From 1a61fb1747e120ae1a6be09b0a64afa3b7850944 Mon Sep 17 00:00:00 2001 From: Bernd Zeimetz Date: Wed, 16 May 2012 21:23:12 +0200 Subject: [PATCH] Merging upstream tag 1_4_3. --- gpsbabel/GPSBabel.pro | 94 + gpsbabel/Makefile.in | 35 +- gpsbabel/alan.c | 588 +- gpsbabel/an1.c | 2070 +-- gpsbabel/an1sym.h | 1118 +- gpsbabel/arcdist.c | 365 +- gpsbabel/avltree.c | 1133 +- gpsbabel/avltree.h | 55 +- gpsbabel/axim_gpb.c | 212 +- gpsbabel/bcr.c | 742 +- gpsbabel/bend.c | 218 + gpsbabel/brauniger_iq.c | 453 +- gpsbabel/bushnell.c | 98 +- gpsbabel/bushnell_trl.c | 47 +- gpsbabel/cet.c | 724 +- gpsbabel/cet.h | 58 +- gpsbabel/cet/ansi_x3_4_1968.h | 4 +- gpsbabel/cet/ibm891.h | 6 +- gpsbabel/cet/ibm903.h | 6 +- gpsbabel/cet/iso_8859_1.h | 4 +- gpsbabel/cet_util.c | 1395 +- gpsbabel/cet_util.h | 50 +- gpsbabel/cetus.c | 1058 +- gpsbabel/coastexp.c | 986 +- gpsbabel/compegps.c | 1023 +- gpsbabel/config.h.in | 5 + gpsbabel/configure | 134 +- gpsbabel/configure.in | 53 +- gpsbabel/copilot.c | 298 +- gpsbabel/coto.c | 606 +- gpsbabel/cst.c | 529 +- gpsbabel/csv_util.c | 3517 +++--- gpsbabel/csv_util.h | 140 +- gpsbabel/defs.h | 1006 +- gpsbabel/delbin.c | 4819 +++---- gpsbabel/delgpl.c | 207 +- gpsbabel/destinator.c | 850 +- gpsbabel/dg-100.c | 1111 +- gpsbabel/discard.c | 257 +- gpsbabel/dmtlog.c | 1135 +- gpsbabel/duplicate.c | 345 +- gpsbabel/easygps.c | 286 +- gpsbabel/enigma.c | 212 +- gpsbabel/exif.c | 2210 ++-- gpsbabel/explorist_ini.c | 74 + gpsbabel/explorist_ini.h | 12 + gpsbabel/fatal.c | 22 +- gpsbabel/filter_skeleton.c | 53 +- gpsbabel/filter_vecs.c | 545 +- gpsbabel/filterdefs.h | 18 +- gpsbabel/format_skeleton.c | 70 +- gpsbabel/formspec.c | 70 +- gpsbabel/g7towin.c | 922 +- gpsbabel/garmin.c | 2053 +-- gpsbabel/garmin_device_xml.c | 98 +- gpsbabel/garmin_device_xml.h | 2955 ++--- gpsbabel/garmin_fit.c | 370 + gpsbabel/garmin_fs.c | 782 +- gpsbabel/garmin_fs.h | 115 +- gpsbabel/garmin_gpi.c | 2437 ++-- gpsbabel/garmin_gpi.h | 206 +- gpsbabel/garmin_tables.c | 1909 +-- gpsbabel/garmin_tables.h | 81 +- gpsbabel/garmin_txt.c | 2088 +-- gpsbabel/garmin_xt.c | 677 +- gpsbabel/gbdatetime.h | 18 + gpsbabel/gbfile.c | 1352 +- gpsbabel/gbfile.h | 162 +- gpsbabel/gbser.c | 234 +- gpsbabel/gbser.h | 50 +- gpsbabel/gbser_posix.c | 612 +- gpsbabel/gbser_private.h | 8 +- gpsbabel/gbser_win.c | 623 +- gpsbabel/gbsleep.c | 12 +- gpsbabel/gbversion.h | 4 +- gpsbabel/gcdb.c | 429 +- gpsbabel/gdb.c | 2823 +++-- gpsbabel/geo.c | 336 +- gpsbabel/geoniche.c | 1336 +- gpsbabel/ggv_log.c | 411 +- gpsbabel/ggv_ovl.c | 599 +- gpsbabel/globals.c | 2 +- gpsbabel/glogbook.c | 140 +- gpsbabel/gnav_trl.c | 136 +- gpsbabel/google.c | 892 +- gpsbabel/gopal.c | 583 +- gpsbabel/gpilots.c | 662 +- gpsbabel/gpspilot.c | 310 +- gpsbabel/gpssim.c | 248 +- gpsbabel/gpsutil.c | 233 +- gpsbabel/gpx.c | 3428 ++--- gpsbabel/grtcirc.c | 352 +- gpsbabel/grtcirc.h | 28 +- gpsbabel/gtm.c | 1188 +- gpsbabel/gtrnctr.c | 713 +- gpsbabel/gui/COPYING.txt | 339 + gpsbabel/gui/aboutdlg.cpp | 2 +- gpsbabel/gui/aboutdlg.h | 2 +- gpsbabel/gui/advdlg.cpp | 2 +- gpsbabel/gui/advdlg.h | 2 +- gpsbabel/gui/app.pro | 12 +- gpsbabel/gui/appname.h | 2 +- gpsbabel/gui/babeldata.h | 2 +- gpsbabel/gui/dpencode.cpp | 2 +- gpsbabel/gui/dpencode.h | 2 +- gpsbabel/gui/filterdata.cpp | 2 +- gpsbabel/gui/filterdata.h | 2 +- gpsbabel/gui/filterdlg.cpp | 2 +- gpsbabel/gui/filterdlg.h | 2 +- gpsbabel/gui/filterwidgets.cpp | 2 +- gpsbabel/gui/filterwidgets.h | 2 +- gpsbabel/gui/format.cpp | 2 +- gpsbabel/gui/format.h | 2 +- gpsbabel/gui/formatload.cpp | 2 +- gpsbabel/gui/formatload.h | 2 +- gpsbabel/gui/gmapdlg.cpp | 2 +- gpsbabel/gui/gmapdlg.h | 2 +- gpsbabel/gui/gpsbabel.desktop | 9 + gpsbabel/gui/gpsbabel.ts | 8 +- gpsbabel/gui/gpsbabelfe | 2 +- gpsbabel/gui/gpsbabelfe.ts | 74 +- gpsbabel/gui/gpsbabelfe_de.qm | Bin 54696 -> 54623 bytes gpsbabel/gui/gpsbabelfe_de.ts | 80 +- gpsbabel/gui/gpsbabelfe_es.qm | Bin 67008 -> 66925 bytes gpsbabel/gui/gpsbabelfe_es.ts | 80 +- gpsbabel/gui/gpsbabelfe_fr.ts | 74 +- gpsbabel/gui/gpsbabelfe_hu.ts | 74 +- gpsbabel/gui/gpsbabelfe_it.qm | Bin 69912 -> 69827 bytes gpsbabel/gui/gpsbabelfe_it.ts | 80 +- gpsbabel/gui/gpsbabelfe_ru.qm | Bin 66237 -> 66164 bytes gpsbabel/gui/gpsbabelfe_ru.ts | 80 +- gpsbabel/gui/gpx.cpp | 2 +- gpsbabel/gui/gpx.h | 2 +- gpsbabel/gui/help.cpp | 2 +- gpsbabel/gui/help.h | 2 +- gpsbabel/gui/latlng.cpp | 2 +- gpsbabel/gui/latlng.h | 2 +- gpsbabel/gui/main.cpp | 35 +- gpsbabel/gui/mainwindow.cpp | 144 +- gpsbabel/gui/mainwindow.h | 18 +- gpsbabel/gui/mainwinui.ui | 2 +- gpsbabel/gui/makesetup.bat | 36 +- gpsbabel/gui/map.cpp | 2 +- gpsbabel/gui/map.h | 2 +- gpsbabel/gui/optionsdlg.cpp | 2 +- gpsbabel/gui/optionsdlg.h | 2 +- gpsbabel/gui/preferences.cpp | 2 +- gpsbabel/gui/processwait.cpp | 2 +- gpsbabel/gui/processwait.h | 2 +- gpsbabel/gui/serial_unix.cpp | 2 +- gpsbabel/gui/serial_win.cpp | 2 +- gpsbabel/gui/setting.h | 2 +- gpsbabel/gui/setup.iss | 40 +- gpsbabel/gui/setup.iss.in | 36 +- gpsbabel/gui/showUrl.sh | 2 +- gpsbabel/gui/upgrade.cpp | 8 +- gpsbabel/height.c | 195 +- gpsbabel/hiketech.c | 252 +- gpsbabel/holux.c | 423 +- gpsbabel/holux.h | 106 +- gpsbabel/hsa_ndv.c | 737 +- gpsbabel/html.c | 470 +- gpsbabel/humminbird.c | 1403 +- gpsbabel/igc.c | 1418 +-- gpsbabel/ignrando.c | 283 +- gpsbabel/igo8.c | 426 +- gpsbabel/ik3d.c | 226 +- gpsbabel/inifile.c | 544 +- gpsbabel/inifile.h | 27 +- gpsbabel/internal_styles.c | 105 +- gpsbabel/interpolate.c | 304 +- gpsbabel/itracku.c | 1008 +- gpsbabel/jeeps/garminusb.h | 58 +- gpsbabel/jeeps/gps.h | 341 +- gpsbabel/jeeps/gpsapp.c | 10530 ++++++++-------- gpsbabel/jeeps/gpsapp.h | 212 +- gpsbabel/jeeps/gpscom.c | 1681 ++- gpsbabel/jeeps/gpscom.h | 56 +- gpsbabel/jeeps/gpsdatum.h | 303 +- gpsbabel/jeeps/gpsdevice.c | 58 +- gpsbabel/jeeps/gpsdevice.h | 58 +- gpsbabel/jeeps/gpsdevice_ser.c | 18 +- gpsbabel/jeeps/gpsdevice_usb.c | 36 +- gpsbabel/jeeps/gpsfmt.c | 2125 ++-- gpsbabel/jeeps/gpsfmt.h | 16 +- gpsbabel/jeeps/gpsinput.c | 3936 +++--- gpsbabel/jeeps/gpsinput.h | 10 +- gpsbabel/jeeps/gpslibusb.c | 610 +- gpsbabel/jeeps/gpsmath.c | 2931 ++--- gpsbabel/jeeps/gpsmath.h | 256 +- gpsbabel/jeeps/gpsmem.c | 351 +- gpsbabel/jeeps/gpsmem.h | 36 +- gpsbabel/jeeps/gpsproj.c | 7077 ++++++----- gpsbabel/jeeps/gpsproj.h | 280 +- gpsbabel/jeeps/gpsprot.c | 599 +- gpsbabel/jeeps/gpsprot.h | 295 +- gpsbabel/jeeps/gpsread.c | 276 +- gpsbabel/jeeps/gpsread.h | 6 +- gpsbabel/jeeps/gpsrqst.c | 182 +- gpsbabel/jeeps/gpsrqst.h | 4 +- gpsbabel/jeeps/gpssend.c | 267 +- gpsbabel/jeeps/gpssend.h | 6 +- gpsbabel/jeeps/gpsserial.c | 627 +- gpsbabel/jeeps/gpsserial.h | 20 +- gpsbabel/jeeps/gpsusbcommon.c | 385 +- gpsbabel/jeeps/gpsusbcommon.h | 18 +- gpsbabel/jeeps/gpsusbint.h | 6 +- gpsbabel/jeeps/gpsusbread.c | 143 +- gpsbabel/jeeps/gpsusbsend.c | 24 +- gpsbabel/jeeps/gpsusbstub.c | 8 +- gpsbabel/jeeps/gpsusbwin.c | 382 +- gpsbabel/jeeps/gpsutil.c | 558 +- gpsbabel/jeeps/gpsutil.h | 62 +- gpsbabel/jeeps/main.c | 40 +- gpsbabel/jogmap.c | 106 +- gpsbabel/jtr.c | 460 +- gpsbabel/kml.c | 2526 ++-- gpsbabel/lmx.c | 467 +- gpsbabel/lowranceusr.c | 1708 +-- gpsbabel/mac/libusb/darwin.c | 6 +- gpsbabel/mag_pdb.c | 329 +- gpsbabel/magellan.h | 36 +- gpsbabel/maggeo.c | 502 +- gpsbabel/magnav.c | 361 +- gpsbabel/magproto.c | 2545 ++-- gpsbabel/main.c | 1271 +- gpsbabel/make-an1sym.pl | 2 +- gpsbabel/mapasia.c | 361 +- gpsbabel/mapopolis.c | 384 +- gpsbabel/mapsend.c | 901 +- gpsbabel/mapsend.h | 26 +- gpsbabel/mapsource.c | 3320 ++--- gpsbabel/mingw/include/ddk/hidsdi.h | 0 gpsbabel/mkicondoc.c | 72 +- gpsbabel/mkshort.c | 1160 +- gpsbabel/mmo.c | 2260 ++-- gpsbabel/msroute.c | 1050 +- gpsbabel/msvc/GPSBabel.vcproj | 16 + gpsbabel/mtk_logger.c | 2652 ++-- gpsbabel/navicache.c | 348 +- gpsbabel/naviguide.c | 529 +- gpsbabel/navilink.c | 1688 +-- gpsbabel/navilink.h | 98 +- gpsbabel/navitel.c | 128 +- gpsbabel/netstumbler.c | 530 +- gpsbabel/nmea.c | 2231 ++-- gpsbabel/nmn4.c | 463 +- gpsbabel/nukedata.c | 56 +- gpsbabel/osm.c | 1110 +- gpsbabel/overlay.c | 596 +- gpsbabel/ozi.c | 1413 ++- gpsbabel/palmdoc.c | 954 +- gpsbabel/parse.c | 472 +- gpsbabel/pathaway.c | 1223 +- gpsbabel/pcx.c | 728 +- gpsbabel/pdbfile.c | 703 +- gpsbabel/pdbfile.h | 70 +- gpsbabel/pocketfms_bc.c | 223 +- gpsbabel/pocketfms_fp.c | 180 +- gpsbabel/pocketfms_wp.c | 255 +- gpsbabel/polygon.c | 520 +- gpsbabel/position.c | 287 +- gpsbabel/psitrex.c | 1135 +- gpsbabel/psp.c | 535 +- gpsbabel/queue.c | 271 +- gpsbabel/queue.h | 10 +- gpsbabel/quovadis.c | 336 +- gpsbabel/quovadis.h | 20 +- gpsbabel/radius.c | 309 +- gpsbabel/random.c | 323 +- gpsbabel/raymarine.c | 705 +- gpsbabel/reference/arc-project.gpx | 311 + gpsbabel/reference/arc-project1.gpx | 270 + gpsbabel/reference/arc-project2.gpx | 282 + gpsbabel/reference/arc-project3.gpx | 299 + gpsbabel/reference/bounds-test.gpx | 499 + gpsbabel/reference/bounds-test.kml | 2463 ++++ gpsbabel/reference/earth-expertgps-track.kml | 372 +- gpsbabel/reference/earth-expertgps.kml | 356 +- gpsbabel/reference/earth-gc.kml | 269 +- gpsbabel/reference/navicache.ref | 4 +- gpsbabel/reference/pocketfms_wp.txt | 0 gpsbabel/reference/psitwpts.txt | 0 gpsbabel/reference/route/bend-expected.gpx | 1770 +++ gpsbabel/reference/route/bend-input.gpx | 942 ++ gpsbabel/reference/route/psitrtes.txt | 0 .../reference/track/bounds-test-track.gpx | 505 + .../reference/track/bounds-test-track.kml | 2600 ++++ gpsbabel/reference/track/course~tcx.gpx | 6 +- gpsbabel/reference/track/fit-sample.fit | Bin 0 -> 16678 bytes gpsbabel/reference/track/fit-sample.gpx | 2679 ++++ .../track/gpx_garmin_extensions-kml_track.kml | 84 +- .../reference/track/gpx_subsecond-sample.gpx | 96 + .../track/gpx_subsecond-sample~subrip.srt | 24 + gpsbabel/reference/track/gtrnctr-readcp.gpx | 220 + gpsbabel/reference/track/gtrnctr-readcp.tcx | 388 + .../reference/track/gtrnctr_power-kml.kml | 62 +- gpsbabel/reference/track/psittrks.txt | 0 .../track/segmented_tracks-track.kml | 259 +- gpsbabel/reference/track/segmented_tracks.kml | 170 +- gpsbabel/reverse_route.c | 48 +- gpsbabel/rgbcolors.c | 394 +- gpsbabel/route.c | 803 +- gpsbabel/saroute.c | 750 +- gpsbabel/sbn.c | 377 +- gpsbabel/sbp.c | 121 +- gpsbabel/session.c | 72 +- gpsbabel/session.h | 24 +- gpsbabel/shape.c | 498 +- gpsbabel/shapelib/dbfopen.c | 10 +- gpsbabel/shapelib/shapefil.h | 7 +- gpsbabel/shapelib/shpopen.c | 9 +- gpsbabel/skyforce.c | 492 +- gpsbabel/skytraq.c | 2058 +-- gpsbabel/smplrout.c | 570 +- gpsbabel/sort.c | 96 +- gpsbabel/stackfilter.c | 384 +- gpsbabel/stmsdf.c | 1136 +- gpsbabel/stmwpp.c | 492 +- gpsbabel/strptime.c | 1434 ++- gpsbabel/strptime.h | 8 +- gpsbabel/style/flysight.style | 28 + gpsbabel/style/iblue757.style | 43 + gpsbabel/style/land_air_sea.style | 24 + gpsbabel/subrip.c | 328 +- gpsbabel/swapdata.c | 34 +- gpsbabel/tef_xml.c | 379 +- gpsbabel/teletype.c | 110 +- gpsbabel/testo.d/arc-project.test | 17 + gpsbabel/testo.d/bend.test | 5 + gpsbabel/testo.d/classic-2.test | 9 - gpsbabel/testo.d/classic-3.test | 8 +- gpsbabel/testo.d/classic-4.test | 37 - gpsbabel/testo.d/delgpl.test | 8 + gpsbabel/testo.d/garmin_fit.test | 6 + gpsbabel/testo.d/garmin_gpi.test | 22 + gpsbabel/testo.d/gtrnctr.test | 23 + gpsbabel/testo.d/kml.test | 30 +- gpsbabel/testo.d/subrip.test | 4 + gpsbabel/text.c | 431 +- gpsbabel/tiger.c | 379 +- gpsbabel/tmpro.c | 367 +- gpsbabel/tomtom.c | 591 +- .../tools/kml22-schema/atom-author-link.xsd | 66 + gpsbabel/tools/kml22-schema/kml22gx.xsd | 321 + gpsbabel/tools/kml22-schema/ogckml22.xsd | 1642 +++ gpsbabel/tools/mac-config | 4 +- gpsbabel/tools/mac-localize | 7 +- gpsbabel/tools/mkchanges | 25 + gpsbabel/tools/mkdmg | 8 +- gpsbabel/tpg.c | 467 +- gpsbabel/tpo.c | 2378 ++-- gpsbabel/trackfilter.c | 2034 +-- gpsbabel/transform.c | 248 +- gpsbabel/unicsv.c | 3424 ++--- gpsbabel/units.c | 164 +- gpsbabel/util.c | 2416 ++-- gpsbabel/util_crc.c | 115 +- gpsbabel/uuid.c | 20 +- gpsbabel/uuid.h | 0 gpsbabel/v900.c | 523 +- gpsbabel/vcf.c | 140 +- gpsbabel/vecs.c | 2639 ++-- gpsbabel/vidaone.c | 135 +- gpsbabel/vitosmt.c | 567 +- gpsbabel/vitovtt.c | 154 +- gpsbabel/vmem.c | 51 +- gpsbabel/vpl.c | 156 +- gpsbabel/waypt.c | 892 +- gpsbabel/wbt-200.c | 1541 +-- gpsbabel/wfff_xml.c | 301 +- gpsbabel/win32/gpsbabel.ico | Bin 766 -> 25214 bytes gpsbabel/win32/gui-2/gnugettext.pas | 2 +- gpsbabel/win32/gui-2/gnugettextD4.pas | 2 +- gpsbabel/wintec_tes.c | 130 +- gpsbabel/xcsv.c | 1014 +- gpsbabel/xhtmlent.c | 1030 +- gpsbabel/xmldoc/chapters/build.xml | 19 +- gpsbabel/xmldoc/chapters/styles.xml | 2 +- gpsbabel/xmldoc/chapters/use.xml | 14 +- gpsbabel/xmldoc/filters/arc-project.xml | 17 + gpsbabel/xmldoc/filters/arc-rte.xml | 5 + gpsbabel/xmldoc/filters/arc-trk.xml | 5 + gpsbabel/xmldoc/filters/arc.xml | 7 +- gpsbabel/xmldoc/filters/bend.xml | 32 + gpsbabel/xmldoc/filters/options/arc-file.xml | 3 - .../xmldoc/filters/options/bend-distance.xml | 7 + .../xmldoc/filters/options/bend-minangle.xml | 7 + gpsbabel/xmldoc/filters/transform.xml | 2 +- gpsbabel/xmldoc/formats/an1.xml | 2 +- gpsbabel/xmldoc/formats/csv.xml | 2 +- gpsbabel/xmldoc/formats/delbin.xml | 7 +- gpsbabel/xmldoc/formats/dg-100.xml | 28 +- gpsbabel/xmldoc/formats/dg-200.xml | 23 + gpsbabel/xmldoc/formats/dna.xml | 13 +- gpsbabel/xmldoc/formats/easygps.xml | 17 +- gpsbabel/xmldoc/formats/enigma.xml | 9 +- gpsbabel/xmldoc/formats/enigma_wp.xml | 8 +- gpsbabel/xmldoc/formats/exif.xml | 2 +- gpsbabel/xmldoc/formats/fit.xml | 5 + gpsbabel/xmldoc/formats/flysight.xml | 6 + gpsbabel/xmldoc/formats/garmin.xml | 24 + gpsbabel/xmldoc/formats/garmin_poi.xml | 21 +- gpsbabel/xmldoc/formats/gcdb.xml | 11 +- gpsbabel/xmldoc/formats/gdb.xml | 15 +- gpsbabel/xmldoc/formats/geo.xml | 2 +- gpsbabel/xmldoc/formats/geonet.xml | 14 +- gpsbabel/xmldoc/formats/glogbook.xml | 16 +- gpsbabel/xmldoc/formats/gnav_trl.xml | 2 +- gpsbabel/xmldoc/formats/gopal.xml | 7 +- gpsbabel/xmldoc/formats/gpl.xml | 13 +- gpsbabel/xmldoc/formats/gpx.xml | 11 +- gpsbabel/xmldoc/formats/gtrnctr.xml | 4 +- gpsbabel/xmldoc/formats/hiketech.xml | 13 +- gpsbabel/xmldoc/formats/html.xml | 29 +- gpsbabel/xmldoc/formats/iblue747.xml | 2 +- gpsbabel/xmldoc/formats/iblue757.xml | 90 + gpsbabel/xmldoc/formats/kml.xml | 4 +- gpsbabel/xmldoc/formats/land_air_sea.xml | 18 + gpsbabel/xmldoc/formats/lowranceusr.xml | 2 +- gpsbabel/xmldoc/formats/m241.xml | 8 + gpsbabel/xmldoc/formats/maggeo.xml | 34 +- gpsbabel/xmldoc/formats/mapsend.xml | 9 +- gpsbabel/xmldoc/formats/mapsource.xml | 33 +- gpsbabel/xmldoc/formats/miniHomer.xml | 62 + gpsbabel/xmldoc/formats/msroute.xml | 41 +- gpsbabel/xmldoc/formats/mtk.xml | 6 +- gpsbabel/xmldoc/formats/navicache.xml | 15 +- gpsbabel/xmldoc/formats/openoffice.xml | 20 +- .../xmldoc/formats/options/dg-200-erase.xml | 1 + .../formats/options/dg-200-erase_only.xml | 6 + .../formats/options/garmin_gpi-bitmap.xml | 6 + gpsbabel/xmldoc/formats/options/kml-units.xml | 2 +- .../xmldoc/formats/options/miniHomer-Bar.xml | 20 + .../xmldoc/formats/options/miniHomer-Boat.xml | 20 + .../xmldoc/formats/options/miniHomer-Car.xml | 20 + .../formats/options/miniHomer-Heart.xml | 20 + .../xmldoc/formats/options/miniHomer-Home.xml | 20 + .../xmldoc/formats/options/miniHomer-baud.xml | 8 + .../formats/options/miniHomer-dump-file.xml | 6 + .../formats/options/miniHomer-erase.xml | 4 + .../options/miniHomer-first-sector.xml | 15 + .../formats/options/miniHomer-initbaud.xml | 13 + .../formats/options/miniHomer-last-sector.xml | 5 + .../formats/options/miniHomer-no-output.xml | 2 + .../options/miniHomer-read-at-once.xml | 7 + gpsbabel/xmldoc/formats/ozi.xml | 10 +- gpsbabel/xmldoc/formats/palmdoc.xml | 17 +- gpsbabel/xmldoc/formats/pathaway.xml | 14 +- gpsbabel/xmldoc/formats/pcx.xml | 3 - gpsbabel/xmldoc/formats/s_and_t.xml | 31 +- gpsbabel/xmldoc/formats/sbn.xml | 2 +- gpsbabel/xmldoc/formats/sbp.xml | 2 +- gpsbabel/xmldoc/formats/shape.xml | 4 +- gpsbabel/xmlgeneric.c | 419 +- gpsbabel/xmlgeneric.h | 60 +- gpsbabel/xmltag.c | 238 +- gpsbabel/xol.c | 424 +- gpsbabel/yahoo.c | 78 +- gpsbabel/zlib/ChangeLog | 2 +- gpsbabel/zlib/adler32.c | 2 +- gpsbabel/zlib/compress.c | 2 +- gpsbabel/zlib/crc32.c | 2 +- gpsbabel/zlib/deflate.c | 2 +- gpsbabel/zlib/deflate.h | 2 +- gpsbabel/zlib/gzio.c | 2 +- gpsbabel/zlib/trees.c | 2 +- gpsbabel/zlib/uncompr.c | 2 +- gpsbabel/zlib/zconf.h | 2 +- gpsbabel/zlib/zconf.in.h | 2 +- gpsbabel/zlib/zutil.c | 2 +- gpsbabel/zlib/zutil.h | 2 +- 472 files changed, 112639 insertions(+), 88676 deletions(-) create mode 100644 gpsbabel/GPSBabel.pro create mode 100644 gpsbabel/bend.c create mode 100644 gpsbabel/explorist_ini.c create mode 100644 gpsbabel/explorist_ini.h create mode 100644 gpsbabel/garmin_fit.c create mode 100644 gpsbabel/gbdatetime.h create mode 100644 gpsbabel/gui/COPYING.txt create mode 100644 gpsbabel/gui/gpsbabel.desktop mode change 100755 => 100644 gpsbabel/mingw/include/ddk/hidsdi.h create mode 100644 gpsbabel/reference/arc-project.gpx create mode 100644 gpsbabel/reference/arc-project1.gpx create mode 100644 gpsbabel/reference/arc-project2.gpx create mode 100644 gpsbabel/reference/arc-project3.gpx create mode 100644 gpsbabel/reference/bounds-test.gpx create mode 100644 gpsbabel/reference/bounds-test.kml mode change 100755 => 100644 gpsbabel/reference/pocketfms_wp.txt mode change 100755 => 100644 gpsbabel/reference/psitwpts.txt create mode 100644 gpsbabel/reference/route/bend-expected.gpx create mode 100644 gpsbabel/reference/route/bend-input.gpx mode change 100755 => 100644 gpsbabel/reference/route/psitrtes.txt create mode 100644 gpsbabel/reference/track/bounds-test-track.gpx create mode 100644 gpsbabel/reference/track/bounds-test-track.kml create mode 100644 gpsbabel/reference/track/fit-sample.fit create mode 100644 gpsbabel/reference/track/fit-sample.gpx create mode 100644 gpsbabel/reference/track/gpx_subsecond-sample.gpx create mode 100644 gpsbabel/reference/track/gpx_subsecond-sample~subrip.srt create mode 100644 gpsbabel/reference/track/gtrnctr-readcp.gpx create mode 100644 gpsbabel/reference/track/gtrnctr-readcp.tcx mode change 100755 => 100644 gpsbabel/reference/track/psittrks.txt create mode 100644 gpsbabel/style/flysight.style create mode 100644 gpsbabel/style/iblue757.style create mode 100644 gpsbabel/style/land_air_sea.style create mode 100644 gpsbabel/testo.d/arc-project.test create mode 100644 gpsbabel/testo.d/bend.test create mode 100644 gpsbabel/testo.d/delgpl.test create mode 100644 gpsbabel/testo.d/garmin_fit.test create mode 100644 gpsbabel/testo.d/garmin_gpi.test create mode 100644 gpsbabel/testo.d/gtrnctr.test create mode 100644 gpsbabel/testo.d/subrip.test create mode 100644 gpsbabel/tools/kml22-schema/atom-author-link.xsd create mode 100644 gpsbabel/tools/kml22-schema/kml22gx.xsd create mode 100644 gpsbabel/tools/kml22-schema/ogckml22.xsd mode change 100755 => 100644 gpsbabel/uuid.h create mode 100644 gpsbabel/xmldoc/filters/arc-project.xml create mode 100644 gpsbabel/xmldoc/filters/arc-rte.xml create mode 100644 gpsbabel/xmldoc/filters/arc-trk.xml create mode 100644 gpsbabel/xmldoc/filters/bend.xml create mode 100644 gpsbabel/xmldoc/filters/options/bend-distance.xml create mode 100644 gpsbabel/xmldoc/filters/options/bend-minangle.xml create mode 100644 gpsbabel/xmldoc/formats/dg-200.xml create mode 100644 gpsbabel/xmldoc/formats/fit.xml create mode 100644 gpsbabel/xmldoc/formats/flysight.xml create mode 100644 gpsbabel/xmldoc/formats/iblue757.xml create mode 100644 gpsbabel/xmldoc/formats/land_air_sea.xml create mode 100644 gpsbabel/xmldoc/formats/miniHomer.xml create mode 100644 gpsbabel/xmldoc/formats/options/dg-200-erase.xml create mode 100644 gpsbabel/xmldoc/formats/options/dg-200-erase_only.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-Bar.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-Boat.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-Car.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-Heart.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-Home.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-baud.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-dump-file.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-erase.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-first-sector.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-initbaud.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-last-sector.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-no-output.xml create mode 100644 gpsbabel/xmldoc/formats/options/miniHomer-read-at-once.xml diff --git a/gpsbabel/GPSBabel.pro b/gpsbabel/GPSBabel.pro new file mode 100644 index 000000000..1f0177096 --- /dev/null +++ b/gpsbabel/GPSBabel.pro @@ -0,0 +1,94 @@ +QT -= gui + +TARGET = GPSBabel +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +MINIMAL_FMTS = magproto.cc explorist_ini.cc gpx.cc geo.cc mapsend.cc mapsource.cc garmin.cc \ + garmin_device_xml.cc garmin_tables.cc internal_styles.cc nmea.cc \ + kml.cc wbt-200.cc + +ALL_FMTS=$$MINIMAL_FMTS gtm.cc gpsutil.cc pcx.cc cetus.cc copilot.cc \ + gpspilot.cc magnav.cc skytraq.cc \ + psp.cc holux.cc tmpro.cc tpg.cc tpo.cc \ + xcsv.cc gcdb.cc tiger.cc easygps.cc quovadis.cc \ + gpilots.cc saroute.cc navicache.cc psitrex.cc geoniche.cc delgpl.cc \ + ozi.cc text.cc html.cc palmdoc.cc netstumbler.cc hsa_ndv.cc \ + igc.cc brauniger_iq.cc shape.cc hiketech.cc glogbook.cc coastexp.cc \ + vcf.cc overlay.cc google.cc xhtmlent.cc lowranceusr.cc an1.cc tomtom.cc \ + tef_xml.cc maggeo.cc pathaway.cc vitosmt.cc gdb.cc bcr.cc coto.cc \ + ignrando.cc stmwpp.cc msroute.cc cst.cc nmn4.cc mag_pdb.cc compegps.cc \ + yahoo.cc unicsv.cc wfff_xml.cc garmin_txt.cc axim_gpb.cc gpssim.cc \ + stmsdf.cc gtrnctr.cc dmtlog.cc raymarine.cc alan.cc vitovtt.cc \ + ggv_log.cc g7towin.cc garmin_gpi.cc lmx.cc random.cc xol.cc dg-100.cc \ + navilink.cc mtk_logger.cc ik3d.cc osm.cc destinator.cc exif.cc vidaone.cc \ + igo8.cc gopal.cc humminbird.cc mapasia.cc gnav_trl.cc navitel.cc ggv_ovl.cc \ + jtr.cc sbp.cc sbn.cc mmo.cc skyforce.cc itracku.cc v900.cc delbin.cc \ + pocketfms_bc.cc pocketfms_fp.cc pocketfms_wp.cc naviguide.cc enigma.cc \ + vpl.cc teletype.cc jogmap.cc bushnell.cc bushnell_trl.cc wintec_tes.cc \ + subrip.cc garmin_xt.cc garmin_fit.cc + +# ALL_FMTS=$$MINIMAL_FMTS +FILTERS=position.cc radius.cc duplicate.cc arcdist.cc polygon.cc smplrout.cc \ + reverse_route.cc sort.cc stackfilter.cc trackfilter.cc discard.cc \ + nukedata.cc interpolate.cc transform.cc height.cc swapdata.cc + +SHAPE=shapelib/shpopen.c shapelib/dbfopen.c pdbfile.cc + +ZLIB=zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/deflate.c zlib/inffast.c \ + zlib/inflate.c zlib/infback.c zlib/inftrees.c zlib/trees.c \ + zlib/uncompr.c zlib/gzio.c zlib/zutil.c + +JEEPS += jeeps/gpsapp.cc jeeps/gpscom.cc \ + jeeps/gpsmath.cc jeeps/gpsmem.cc \ + jeeps/gpsprot.cc jeeps/gpsread.cc \ + jeeps/gpsdevice.cc jeeps/gpsdevice_ser.cc jeeps/gpsdevice_usb.cc \ + jeeps/gpsrqst.cc jeeps/gpssend.cc jeeps/gpsserial.cc jeeps/jgpsutil.cc \ + jeeps/gpsusbread.cc jeeps/gpsusbsend.cc \ + jeeps/gpsusbcommon.cc + + +SUPPORT = queue.cc route.cc waypt.cc filter_vecs.cc util.cc vecs.cc mkshort.cc \ + csv_util.cc strptime.c grtcirc.cc vmem.cc util_crc.cc xmlgeneric.cc \ + uuid.cc formspec.cc xmltag.cc cet.cc cet_util.cc fatal.cc rgbcolors.cc \ + inifile.cc garmin_fs.cc gbsleep.cc units.cc gbser.cc \ + gbfile.cc parse.cc avltree.cc session.cc main.cc globals.cc + +SUBDIRS += jeeps + +macx|linux { + DEFINES += HAVE_NANOSLEEP HAVE_LIBUSB HAVE_LIBEXPAT HAVE_GLOB + DEFINES += HAVE_VA_COPY HAVE_VA_LIST_AS_ARRAY + SOURCES += gbser_posix.cc jeeps/gpslibusb.cc + INCLUDEPATH += jeeps + LIBS += -lexpat +} + +win32 { + SOURCES += gbser_win32.cc jeeps/gpsusbwin.c +} + +linux { + DEFINES += HAVE_LINUX_HID +} + +macx { + LIBS += -framework IOKit -framework CoreFoundation + INCLUDEPATH += mac/libusb + SOURCES += mac/libusb/darwin.c \ + mac/libusb/descriptors.c \ + mac/libusb/error.c \ + mac/libusb/usb.c +} + +SOURCES += $$ALL_FMTS $$FILTERS $$SUPPORT $$SHAPE $$ZLIB $$JEEPS + +# We don't care about stripping things out of the build. Full monty, baby. +DEFINES += MAXIMAL_ENABLED +DEFINES += FILTERS_ENABLED +DEFINES += PDBFMTS_ENABLED +DEFINES += SHAPELIB_ENABLED +DEFINES += CSVFMTS_ENABLED +DEFINES += CET_WANTED diff --git a/gpsbabel/Makefile.in b/gpsbabel/Makefile.in index 8295998ec..02fd854d7 100644 --- a/gpsbabel/Makefile.in +++ b/gpsbabel/Makefile.in @@ -65,11 +65,11 @@ ALL_FMTS=$(MINIMAL_FMTS) gtm.o gpsutil.o pcx.o cetus.o copilot.o \ jtr.o sbp.o sbn.o mmo.o skyforce.o itracku.o v900.o delbin.o \ pocketfms_bc.o pocketfms_fp.o pocketfms_wp.o naviguide.o enigma.o \ vpl.o teletype.o jogmap.o bushnell.o bushnell_trl.o wintec_tes.o \ - subrip.o garmin_xt.o \ + subrip.o garmin_xt.o explorist_ini.o garmin_fit.o \ FMTS=@FMTS@ -FILTERS=position.o radius.o duplicate.o arcdist.o polygon.o smplrout.o \ +FILTERS=bend.o position.o radius.o duplicate.o arcdist.o polygon.o smplrout.o \ reverse_route.o sort.o stackfilter.o trackfilter.o discard.o \ nukedata.o interpolate.o transform.o height.o swapdata.o @@ -141,8 +141,8 @@ configure: configure.in autoconf tag: - cvs commit - cvs tag gpsbabel_@GBMAJOR@_@GBMINOR@_@GBMICRO@@PACKAGE_RELEASE@ + svn commit + svn copy https://gpsbabel.googlecode.com/svn/trunk/ https://gpsbabel.googlecode.com/svn/tags/gpsbabel_@GBMAJOR@_@GBMINOR@_@GBMICRO@@PACKAGE_RELEASE@ more-clean: clean tools/mkmoreclean @@ -259,14 +259,16 @@ WINFILES = gpsbabel.exe mingw/libexpat.dll win32/GPSBabelGUI.exe win32/gui-2/REA # in and tagged. # release-sourcecheck: changes.html - cvs commit - ./chkdoc + svn commit + # ./chkdoc # make clean rm -fr gpsbabel-$(VERSIOND) # make gpsbabel doc gpsbabel.html - @(. tools/functions && ask "Enter 'y' to tag the tree as gpsbabel_$(VERSIONU)." "y") && cvs tag -F gpsbabel_$(VERSIONU) ; exit 0 - cvs export -r gpsbabel_$(VERSIONU) -d gpsbabel-$(VERSIOND) gpsbabel + @(. tools/functions && ask "Enter 'y' to tag the tree as gpsbabel_$(VERSIONU)." "y") && svn copy https://gpsbabel.googlecode.com/svn/trunk/ https://gpsbabel.googlecode.com/svn/tags/gpsbabel_$(VERSIONU) ; exit 0 + svn export https://gpsbabel.googlecode.com/svn/tags/gpsbabel_$(VERSIONU)/gpsbabel gpsbabel-$(VERSIOND) touch gpsbabel-$(VERSIOND)/internal_styles.c + touch gpsbabel-$(VERSIOND)/configure + touch gpsbabel-$(VERSIOND)/xcsv_tokens.gperf # # Build the release tarball from the exported CVS tree, tweaking @@ -276,6 +278,7 @@ release-tarball: release-sourcecheck # rm -fr gpsbabel-$(VERSIOND) cp -ap internal_styles.c gpsbabel-$(VERSIOND)/ tar czf /tmp/gpsbabel-$(VERSIOND).tar.gz gpsbabel-$(VERSIOND) + gb_upload /tmp/gpsbabel-$(VERSIOND).tar.gz # cd /tmp ; tar xzf gpsbabel-$(VERSIOND).tar.gz release-rpm: @@ -347,15 +350,16 @@ mac-release: mac-gui: gpsbabel - file gpsbabel | grep '2 architectures' || exit 1 - file gui/objects/GPSBabelFE.app/Contents/MacOS/GPSBabelFE | grep '2 architectures' || exit 1 - cd gui ; qmake && xcodebuild + # file gpsbabel | grep '2 architectures' || exit 1 + # file gui/objects/GPSBabelFE.app/Contents/MacOS/GPSBabelFE | grep '2 architectures' || exit 1 + cd gui ; qmake && make cd gui ; lupdate app.pro cd gui ; lrelease app.pro - mkdir gui/objects/GPSBabelFE.app/Contents/MacOS/lang - cp gui/*.qm gui/objects/gpsbabelFE.app/Contents/MacOS/lang + @ [ ! -d gui/objects/GPSBabelFE.app/Contents/MacOS/translations ] && \ + mkdir -p gui/objects/GPSBabelFE.app/Contents/MacOS/translations + cp gui/*.qm gui/objects/gpsbabelFE.app/Contents/MacOS/translations cp gpsbabel gui/objects/GPSBabelFE.app/Contents/MacOS - cp -r gui/help gui/objects/GPSBabelFE.app/Contents/MacOS + cp -r gui/help/*.html gui/objects/GPSBabelFE.app/Contents/MacOS cp gui/gmapbase.html gui/objects/GPSBabelFE.app/Contents/MacOS tools/mac-localize @@ -389,6 +393,9 @@ avltree.o: avltree.c avltree.h defs.h config.h queue.h gbtypes.h \ zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h session.h axim_gpb.o: axim_gpb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h session.h +bend.o: bend.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h session.h filterdefs.h \ + grtcirc.h bcr.o: bcr.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ gbfile.h cet.h cet_util.h inifile.h session.h csv_util.h \ garmin_tables.h diff --git a/gpsbabel/alan.c b/gpsbabel/alan.c index 19800f921..0eea38e6d 100644 --- a/gpsbabel/alan.c +++ b/gpsbabel/alan.c @@ -176,7 +176,7 @@ enum { /**************************************************************************/ -static gbfile *fin = NULL, *fout = NULL; +static gbfile* fin = NULL, *fout = NULL; struct wprdata WPR; struct trldata TRL; @@ -196,103 +196,115 @@ static arglist_t trl_args[] = { }; /**************************************************************************/ - -static unsigned int byte_order(void) { +// FIXME: Why is this code doing its own byte order conversion? +static unsigned int byte_order(void) +{ unsigned long test = BYTEORDER_TEST; - unsigned char *ptr; + unsigned char* ptr; unsigned int order; - ptr = (unsigned char *)(&test); + ptr = (unsigned char*)(&test); order = (ptr[0] << 12) | (ptr[1] << 8) | (ptr[2] << 4) | ptr[3]; return order; } -static void sw_bytes(void *word) { - gbuint8 *p = word; - gbuint16 *r = word; +static void sw_bytes(void* word) +{ + gbuint8* p = (gbuint8*) word; + gbuint16* r = (gbuint16*) word; *r = (gbuint16)(p[1] << 8 | p[0]); } -static void sw_words(void *dword) { - gbuint16 *p = dword; - gbuint32 *r = dword; +static void sw_words(void* dword) +{ + gbuint16* p = (gbuint16*) dword; + gbuint32* r = (gbuint32*) dword; *r = (gbuint32)(p[0] << 16 | p[1]); } -static void rev_bytes(void *dword) { - gbuint8 *p = dword; - gbuint32 *r = dword; +static void rev_bytes(void* dword) +{ + gbuint8* p = (gbuint8*) dword; + gbuint32* r = (gbuint32*) dword; *r = (gbuint32)(p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]); } -static void swap_wpthdr(struct wpthdr *wpthdr, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { +static void swap_wpthdr(struct wpthdr* wpthdr, + void (*swap16_func)(void*), void (*swap32_func)(void*)) +{ int i; - if ( swap32_func != NULL ) { - swap32_func( &wpthdr->id ); + if (swap32_func != NULL) { + swap32_func(&wpthdr->id); } - if ( swap16_func != NULL ) { - swap16_func( &wpthdr->num ); - swap16_func( &wpthdr->next ); - for (i=0; iidx[i] ); + if (swap16_func != NULL) { + swap16_func(&wpthdr->num); + swap16_func(&wpthdr->next); + for (i=0; iidx[i]); + } } } -static void swap_wpt(struct wpt *wpt, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { - if ( swap16_func != NULL ) { - swap16_func( &wpt->usecount ); +static void swap_wpt(struct wpt* wpt, + void (*swap16_func)(void*), void (*swap32_func)(void*)) +{ + if (swap16_func != NULL) { + swap16_func(&wpt->usecount); } - if ( swap32_func != NULL ) { - swap32_func( &wpt->pt.x ); - swap32_func( &wpt->pt.y ); - swap32_func( &wpt->date ); - swap32_func( &wpt->time ); + if (swap32_func != NULL) { + swap32_func(&wpt->pt.x); + swap32_func(&wpt->pt.y); + swap32_func(&wpt->date); + swap32_func(&wpt->time); } } -static void swap_rtehdr(struct rtehdr *rtehdr, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { +static void swap_rtehdr(struct rtehdr* rtehdr, + void (*swap16_func)(void*), void (*swap32_func)(void*)) +{ int i; - if ( swap16_func != NULL) { - swap16_func( &rtehdr->num ); - swap16_func( &rtehdr->next ); - for (i=0; iidx[i] ); - swap16_func( &rtehdr->rteno ); + if (swap16_func != NULL) { + swap16_func(&rtehdr->num); + swap16_func(&rtehdr->next); + for (i=0; iidx[i]); + } + swap16_func(&rtehdr->rteno); } - if ( swap32_func != NULL ) { - swap32_func( &rtehdr->id ); + if (swap32_func != NULL) { + swap32_func(&rtehdr->id); } } -static void swap_rte(struct rte *rte, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { +static void swap_rte(struct rte* rte, + void (*swap16_func)(void*), void (*swap32_func)(void*)) +{ int i; if (swap16_func != NULL) { - swap16_func( &rte->wptnum ); - for (i=0; iwptidx[i] ); - swap16_func( &rte->reserved ); + swap16_func(&rte->wptnum); + for (i=0; iwptidx[i]); + } + swap16_func(&rte->reserved); } - if ( swap32_func != NULL ) { - swap32_func( &rte->date ); - swap32_func( &rte->time ); + if (swap32_func != NULL) { + swap32_func(&rte->date); + swap32_func(&rte->time); } } -static void wpr_swap(struct wprdata *wprdata) { - void (*swap16_func)(void *); - void (*swap32_func)(void *); +static void wpr_swap(struct wprdata* wprdata) +{ + void (*swap16_func)(void*); + void (*swap32_func)(void*); int i; - switch( byte_order() ) { + switch (byte_order()) { case SWAP_NONE: /* same byte oder, LITTLE_ENDIAN */ return; break; @@ -311,69 +323,76 @@ static void wpr_swap(struct wprdata *wprdata) { default: return; /* never reached */ } - - swap_wpthdr( &(wprdata->wpthdr), swap16_func, swap32_func ); - for (i=0; i< MAXWPT; i++) - swap_wpt( &(wprdata->wpt[i]), swap16_func, swap32_func ); - swap_rtehdr( &(wprdata->rtehdr), swap16_func, swap32_func ); - for (i=0; irte[i]), swap16_func, swap32_func ); + + swap_wpthdr(&(wprdata->wpthdr), swap16_func, swap32_func); + for (i=0; i< MAXWPT; i++) { + swap_wpt(&(wprdata->wpt[i]), swap16_func, swap32_func); + } + swap_rtehdr(&(wprdata->rtehdr), swap16_func, swap32_func); + for (i=0; irte[i]), swap16_func, swap32_func); + } } -static void swap_trkhdr(struct trkhdr *trkhdr, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { - if ( swap16_func != NULL ) { - swap16_func( &(trkhdr->totalpt) ); - swap16_func( &(trkhdr->next) ); +static void swap_trkhdr(struct trkhdr* trkhdr, + void (*swap16_func)(void*), void (*swap32_func)(void*)) +{ + if (swap16_func != NULL) { + swap16_func(&(trkhdr->totalpt)); + swap16_func(&(trkhdr->next)); } - if ( swap32_func != NULL ) { - swap32_func( &(trkhdr->occupied) ); - swap32_func( &(trkhdr->show) ); - swap32_func( &(trkhdr->fill) ); + if (swap32_func != NULL) { + swap32_func(&(trkhdr->occupied)); + swap32_func(&(trkhdr->show)); + swap32_func(&(trkhdr->fill)); } } -static void swap_loghdr(struct loghdr *loghdr, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { +static void swap_loghdr(struct loghdr* loghdr, + void (*swap16_func)(void*), void (*swap32_func)(void*)) +{ int i; - if ( swap16_func != NULL ) { - swap16_func( &(loghdr->num) ); - swap16_func( &(loghdr->next) ); + if (swap16_func != NULL) { + swap16_func(&(loghdr->num)); + swap16_func(&(loghdr->next)); + } + if (swap32_func != NULL) { + swap32_func(&(loghdr->id)); + swap32_func(&(loghdr->date)); + swap32_func(&(loghdr->time)); } - if ( swap32_func != NULL ) { - swap32_func( &(loghdr->id) ); - swap32_func( &(loghdr->date) ); - swap32_func( &(loghdr->time) ); + for (i=0; itrkhdr[i]), swap16_func, swap32_func); } - for (i=0; itrkhdr[i]), swap16_func, swap32_func ); } -static void swap_trklog(struct trklog *trklog, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { +static void swap_trklog(struct trklog* trklog, + void (*swap16_func)(void*), void (*swap32_func)(void*)) +{ int i; - if ( swap16_func != NULL ) { + if (swap16_func != NULL) { for (i=0; ish[i].speed) ); - swap16_func( &(trklog->sh[i].height) ); + swap16_func(&(trklog->sh[i].speed)); + swap16_func(&(trklog->sh[i].height)); } } - if ( swap32_func != NULL ) { + if (swap32_func != NULL) { for (i=0; ipt[i].x) ); - swap32_func( &(trklog->pt[i].y) ); + swap32_func(&(trklog->pt[i].x)); + swap32_func(&(trklog->pt[i].y)); } } } -static void trl_swap(struct trldata *trldata) { - void (*swap16_func)(void *); - void (*swap32_func)(void *); +static void trl_swap(struct trldata* trldata) +{ + void (*swap16_func)(void*); + void (*swap32_func)(void*); int i; - switch( byte_order() ) { + switch (byte_order()) { case SWAP_NONE: /* same byte oder, LITTLE_ENDIAN */ return; break; @@ -393,45 +412,51 @@ static void trl_swap(struct trldata *trldata) { return; /* never reached */ } - swap_loghdr( &(trldata->loghdr), swap16_func, swap32_func); - for (i=0; itrklog[i]), swap16_func, swap32_func); + swap_loghdr(&(trldata->loghdr), swap16_func, swap32_func); + for (i=0; itrklog[i]), swap16_func, swap32_func); + } } /**************************************************************************/ -static void str2lab(char *dest, char *src, int len, char *fmt, int n) { +static void str2lab(char* dest, char* src, int len, char* fmt, int n) +{ int i,j; j = 0; if (src != NULL) { for (i=0; itm_mday | ((tm->tm_mon+1)<<8) | ((tm->tm_year+1900)<<16); *time = t % 86400; } -static time_t unpack_time(gbint32 date, gbint32 time) { +static time_t unpack_time(gbint32 date, gbint32 time) +{ time_t result; short year, month, day; static int m_to_d[12] = - {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; year = (date >> 16) & 0xffff; month = (date >> 8) & 0xff; /* 1-12 */ @@ -439,14 +464,15 @@ static time_t unpack_time(gbint32 date, gbint32 time) { month -= 1; /* fit struct tm */ year += month / 12; - + if (month < 0) { year -= 1; month += 12; } result = (year - 1970) * 365 + m_to_d[month]; - if (month <= 1) + if (month <= 1) { year -= 1; + } result += (year - 1968) / 4; result -= (year - 1900) / 100; result += (year - 1600) / 400; @@ -454,143 +480,159 @@ static time_t unpack_time(gbint32 date, gbint32 time) { result -= 1; result *= 86400; result += time; /* map500 time is inseconds of the day */ - + return result; } /**************************************************************************/ -static waypoint * get_wpt(struct wprdata *wprdata, unsigned n) { - struct wpthdr *wpthdr; - struct wpt *wpt; +static waypoint* get_wpt(struct wprdata* wprdata, unsigned n) +{ + struct wpthdr* wpthdr; + struct wpt* wpt; int j, idx; - waypoint *WP; + waypoint* WP; wpthdr = &(wprdata->wpthdr); idx = wpthdr->idx[n]; - if (idx == WPT_IDX_NONE || wpthdr->used[idx] == WPT_UNUSED) + if (idx == WPT_IDX_NONE || wpthdr->used[idx] == WPT_UNUSED) { return NULL; + } wpt = &(wprdata->wpt[idx]); - + WP = waypt_new(); WP->latitude = -pt2deg(wpt->pt.y); WP->longitude = pt2deg(wpt->pt.x); WP->creation_time = unpack_time(wpt->date, wpt->time); - for(j=WPT_NAME_LEN-1; j >= 0 && wpt->name[j] == ' '; j--) {}; + for (j=WPT_NAME_LEN-1; j >= 0 && wpt->name[j] == ' '; j--) {}; WP->shortname = xstrndup(wpt->name,j+1); - for(j=WPT_COMMENT_LEN-1; j >= 0 && wpt->comment[j] == ' '; j--) {}; - if (j >= 0) + for (j=WPT_COMMENT_LEN-1; j >= 0 && wpt->comment[j] == ' '; j--) {}; + if (j >= 0) { WP->description = xstrndup(wpt->comment, j+1); - else + } else { WP->description = xstrdup(""); + } WP->notes = xstrdup(""); return WP; } -static void wpr_read(void) { +static void wpr_read(void) +{ struct wprdata wprdata; - struct rtehdr *rtehdr; - struct rte *rte; + struct rtehdr* rtehdr; + struct rte* rte; int i, j, idx; - waypoint *WP; - route_head *RT; + waypoint* WP; + route_head* RT; - if ( gbfread(&wprdata, sizeof(struct wprdata), 1, fin) != 1 ) + if (gbfread(&wprdata, sizeof(struct wprdata), 1, fin) != 1) { fatal(MYNAME ": Read error on %s\n", fin->name); + } wpr_swap(&wprdata); - if ( wprdata.wpthdr.id != WPT_HDR_ID || - wprdata.rtehdr.id != RTE_HDR_ID ) + if (wprdata.wpthdr.id != WPT_HDR_ID || + wprdata.rtehdr.id != RTE_HDR_ID) { fatal(MYNAME ": %s is not in Alan .wpr format.\n", fin->name); + } /* waypoints */ for (i=0; iidx[i]; - if (idx == RTE_IDX_NONE || rtehdr->used[idx] == RTE_UNUSED) + if (idx == RTE_IDX_NONE || rtehdr->used[idx] == RTE_UNUSED) { continue; + } rte = &(wprdata.rte[idx]); - + RT = route_head_alloc(); RT->rte_num = i; - for(j=RTE_NAME_LEN-1; j >= 0 && rte->name[j] == ' '; j--) {}; + for (j=RTE_NAME_LEN-1; j >= 0 && rte->name[j] == ' '; j--) {}; RT->rte_name = xstrndup(rte->name,j+1); - for(j=RTE_COMMENT_LEN-1; j >= 0 && rte->comment[j] == ' '; j--) {}; - if (j >= 0) + for (j=RTE_COMMENT_LEN-1; j >= 0 && rte->comment[j] == ' '; j--) {}; + if (j >= 0) { RT->rte_desc = xstrndup(rte->comment,j+1); - else + } else { RT->rte_desc = xstrdup(""); + } - route_add_head(RT); + route_add_head(RT); /* route points */ - for(j=0; jwptnum; j++) { + for (j=0; jwptnum; j++) { WP = get_wpt(&wprdata, rte->wptidx[j]); - if ( WP != NULL ) - route_add_wpt(RT, WP); + if (WP != NULL) { + route_add_wpt(RT, WP); + } } } } -static void trl_read(void) { +static void trl_read(void) +{ struct trldata trldata; - struct trkhdr *trkhdr; - struct trklog *trklog; - waypoint *WP; - route_head *TL; + struct trkhdr* trkhdr; + struct trklog* trklog; + waypoint* WP; + route_head* TL; int i, j; for (i=0; iname); + } } gbfseek(fin, 0x10000 * MAXTRK/2, SEEK_SET); - if ( gbfread( &(trldata.loghdr), sizeof(struct loghdr), 1, fin) != 1) + if (gbfread(&(trldata.loghdr), sizeof(struct loghdr), 1, fin) != 1) { fatal(MYNAME ": Read error on %s\n", fin->name); + } trl_swap(&trldata); - if ( trldata.loghdr.id != TRL_HDR_ID ) + if (trldata.loghdr.id != TRL_HDR_ID) { fatal(MYNAME ": %s is not in Alan .trl format.\n", fin->name); + } - for(i=0; ioccupied == TRK_UNUSED) + if (trkhdr->occupied == TRK_UNUSED) { continue; + } TL = route_head_alloc(); - for(j=TRK_NAME_LEN-1; - j >= 0 && (trkhdr->name[j] == ' ' || trkhdr->name[j] == '\0'); - j--) {}; + for (j=TRK_NAME_LEN-1; + j >= 0 && (trkhdr->name[j] == ' ' || trkhdr->name[j] == '\0'); + j--) {}; TL->rte_name = xstrndup(trkhdr->name,j+1); -/* TL->rte_name[TRK_NAME_LEN+1] = 0; */ /* MAYBE BAD ADDRESS (Valgrind) */ - for(j=TRK_COMMENT_LEN-1; - j >= 0 && (trkhdr->comment[j] == ' ' || trkhdr->comment[j] == '\0'); - j--) {}; + /* TL->rte_name[TRK_NAME_LEN+1] = 0; */ /* MAYBE BAD ADDRESS (Valgrind) */ + for (j=TRK_COMMENT_LEN-1; + j >= 0 && (trkhdr->comment[j] == ' ' || trkhdr->comment[j] == '\0'); + j--) {}; TL->rte_desc = xstrndup(trkhdr->comment,j+1); -/* TL->rte_desc[TRK_COMMENT_LEN+1] = 0; */ /* MAYBE BAD ADDRESS (Valgrind) */ + /* TL->rte_desc[TRK_COMMENT_LEN+1] = 0; */ /* MAYBE BAD ADDRESS (Valgrind) */ TL->rte_num = i; - track_add_head(TL); + track_add_head(TL); /* track points */ trklog = &(trldata.trklog[i]); - for(j=0; jtotalpt; j++) { + for (j=0; jtotalpt; j++) { WP = waypt_new(); WP->latitude = -pt2deg(trklog->pt[j].y); WP->longitude = pt2deg(trklog->pt[j].x); WP->altitude = hgt2m(trklog->sh[j].height); - if ( trklog->sh[j].speed >= 0 ) - WAYPT_SET(WP, speed, sp2mps(trklog->sh[j].speed)) - else /* bad speed < 0 - set to 0.0 */ - WAYPT_UNSET(WP, speed); + if (trklog->sh[j].speed >= 0) + WAYPT_SET(WP, speed, sp2mps(trklog->sh[j].speed)) + else { /* bad speed < 0 - set to 0.0 */ + WAYPT_UNSET(WP, speed); + } track_add_wpt(TL, WP); } } @@ -598,7 +640,8 @@ static void trl_read(void) { /**************************************************************************/ -static int find_wpt(struct wprdata *wprdata, const waypoint *WP) { +static int find_wpt(struct wprdata* wprdata, const waypoint* WP) +{ struct wpt pattern, *wpt; int i, wpt_idx; @@ -608,29 +651,32 @@ static int find_wpt(struct wprdata *wprdata, const waypoint *WP) { wpt = wprdata->wpt; for (i=0; iwpthdr.idx[i]; - if ( wpt_idx == WPT_IDX_NONE || - wprdata->wpthdr.used[wpt_idx] == WPT_UNUSED ) + wpt_idx = wprdata->wpthdr.idx[i]; + if (wpt_idx == WPT_IDX_NONE || + wprdata->wpthdr.used[wpt_idx] == WPT_UNUSED) { continue; - if ( strncmp( wpt[wpt_idx].name, pattern.name, WPT_NAME_LEN) == 0 && - wpt[wpt_idx].pt.x == pattern.pt.x && - wpt[wpt_idx].pt.y == pattern.pt.y ) + } + if (strncmp(wpt[wpt_idx].name, pattern.name, WPT_NAME_LEN) == 0 && + wpt[wpt_idx].pt.x == pattern.pt.x && + wpt[wpt_idx].pt.y == pattern.pt.y) { return i; + } } return -1; } -static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { - struct wpthdr *wpthdr; +static int add_wpt(struct wprdata* wprdata, const waypoint* WP,int isroute) +{ + struct wpthdr* wpthdr; int hdr_idx, wpt_idx; - struct wpt *wpt; + struct wpt* wpt; int i; wpthdr = &(wprdata->wpthdr); hdr_idx = find_wpt(wprdata, WP); - if ( hdr_idx >= 0 ) { + if (hdr_idx >= 0) { /* duplicate waypoint */ if (isroute) { wpt = &(wprdata->wpt[wpthdr->idx[hdr_idx]]); @@ -638,7 +684,7 @@ static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { } /* warning(MYNAME ": using duplicate waypoint '%s' at (%f°, %f°)\n", - WP->shortname, WP->latitude, WP->longitude); + WP->shortname, WP->latitude, WP->longitude); */ return hdr_idx; } @@ -647,8 +693,9 @@ static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { hdr_idx = i; for (i=0; iused[i] != WPT_UNUSED; i++) { } wpt_idx = i; - if (wpthdr->num >= MAXWPT || hdr_idx >= MAXWPT || wpt_idx >= MAXWPT ) + if (wpthdr->num >= MAXWPT || hdr_idx >= MAXWPT || wpt_idx >= MAXWPT) { fatal(MYNAME ": Can't store more than %u waypoints\n", MAXWPT); + } wpt = &(wprdata->wpt[wpt_idx]); str2lab(wpt->name, WP->shortname, WPT_NAME_LEN, "W%05d", wpt_idx); @@ -664,29 +711,33 @@ static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { wpthdr->used[wpt_idx] = WPT_USED; wpthdr->num++; wpthdr->next++; - if (wpthdr->next >= MAXWPT) /* overrun */ + if (wpthdr->next >= MAXWPT) { /* overrun */ wpthdr->next = 0; + } return hdr_idx; } -static void wpr_waypoint(const waypoint *WP) { +static void wpr_waypoint(const waypoint* WP) +{ add_wpt(&WPR, WP, 0); } -static void wpr_route_hdr(const route_head *RT) { - struct rtehdr *rtehdr; +static void wpr_route_hdr(const route_head* RT) +{ + struct rtehdr* rtehdr; int hdr_idx, rte_idx; - struct rte *rte; + struct rte* rte; int i; - + rtehdr = &(WPR.rtehdr); for (i=0; iidx[i] != RTE_IDX_NONE; i++) { } hdr_idx = i; for (i=0; iused[i] != RTE_UNUSED; i++) { } rte_idx = i; - if (rtehdr->num >= MAXRTE || hdr_idx >= MAXRTE || rte_idx >= MAXRTE ) + if (rtehdr->num >= MAXRTE || hdr_idx >= MAXRTE || rte_idx >= MAXRTE) { fatal(MYNAME ": Can't store more than %u routes", MAXRTE); + } rte = &(WPR.rte[rte_idx]); str2lab(rte->name, RT->rte_name, RTE_NAME_LEN, "R%03d", rte_idx); @@ -697,20 +748,23 @@ static void wpr_route_hdr(const route_head *RT) { rtehdr->used[rte_idx] = RTE_USED; rtehdr->num++; rtehdr->next++; - if (rtehdr->next >= MAXRTE) /* overrun */ + if (rtehdr->next >= MAXRTE) { /* overrun */ rtehdr->next = 0; + } /* if you want the new route to be active, uncomment the next line */ /* rtehdr->rteno = rte_idx; */ } -static void wpr_route_wpt(const waypoint *WP) { - struct rte *rte; +static void wpr_route_wpt(const waypoint* WP) +{ + struct rte* rte; int wpt_idx; rte = &(WPR.rte[WPR.rtehdr.num -1]); - if ( rte->wptnum >= MAXWPTINRTE ) + if (rte->wptnum >= MAXWPTINRTE) { fatal(MYNAME ": Can't store more than %u waypoints per route", MAXWPTINRTE); + } wpt_idx = add_wpt(&WPR, WP, 1); @@ -718,11 +772,13 @@ static void wpr_route_wpt(const waypoint *WP) { rte->wptnum ++; } -static void wpr_route_trl(const route_head *RT) { +static void wpr_route_trl(const route_head* RT) +{ /* should we do some final sanity checks? */ } -static void wpr_write(void) { +static void wpr_write(void) +{ int i; WPR.wpthdr.id = WPT_HDR_ID; @@ -745,33 +801,39 @@ static void wpr_write(void) { route_disp_all(wpr_route_hdr, wpr_route_trl, wpr_route_wpt); wpr_swap(&WPR); - if ( gbfwrite(&WPR, sizeof(struct wprdata), 1, fout) != 1 ) + if (gbfwrite(&WPR, sizeof(struct wprdata), 1, fout) != 1) { fatal(MYNAME ": Write error on %s\n", fout->name); + } } /**************************************************************************/ -static void trl_track_hdr(const route_head *TL) { - struct trkhdr *trkhdr; +static void trl_track_hdr(const route_head* TL) +{ + struct trkhdr* trkhdr; int idx, l; trkhdr = TRL.loghdr.trkhdr; - + for (idx=0; idx< MAXTRK && trkhdr[idx].occupied != TRK_UNUSED; idx++) {}; - if (idx >= MAXTRK) + if (idx >= MAXTRK) { fatal(MYNAME ": Can't store more than %u tracklogs", MAXTRK); + } - if ( TL->rte_name != NULL ) + if (TL->rte_name != NULL) { strncpy(trkhdr[idx].name, TL->rte_name, TRK_NAME_LEN); - if ( *(trkhdr[idx].name) == '\0' ) + } + if (*(trkhdr[idx].name) == '\0') { sprintf(trkhdr[idx].name, "T%03d", idx); + } trkhdr[idx].name[TRK_NAME_LEN-1] = '\0'; - if ( TL->rte_desc != NULL ) { + if (TL->rte_desc != NULL) { strncpy(trkhdr[idx].comment, TL->rte_desc, TRK_COMMENT_LEN); l = strlen(TL->rte_desc); - if ( l < TRK_COMMENT_LEN-1 ) + if (l < TRK_COMMENT_LEN-1) { memset(trkhdr[idx].comment + l, ' ', TRK_COMMENT_LEN - l); + } } trkhdr[idx].comment[TRK_COMMENT_LEN-1] = '\0'; @@ -783,46 +845,53 @@ static void trl_track_hdr(const route_head *TL) { TRL.loghdr.num = idx; } -static void trl_track_wpt(const waypoint *WP) { - struct trklog *trklog; - struct trkhdr *trkhdr; +static void trl_track_wpt(const waypoint* WP) +{ + struct trklog* trklog; + struct trkhdr* trkhdr; int trk_idx, log_idx; - + trk_idx = TRL.loghdr.num; trkhdr = &(TRL.loghdr.trkhdr[trk_idx]); - if ( trkhdr->totalpt >= MAXPTINTRK ) + if (trkhdr->totalpt >= MAXPTINTRK) { fatal(MYNAME ": Can't store more than %u points per track", MAXPTINTRK); + } log_idx = trkhdr->next; trklog = &(TRL.trklog[trk_idx]); - trklog->pt[log_idx].x = deg2pt( WP->longitude); + trklog->pt[log_idx].x = deg2pt(WP->longitude); trklog->pt[log_idx].y = deg2pt(-WP->latitude); - if WAYPT_HAS(WP, speed) + if WAYPT_HAS(WP, speed) { trklog->sh[log_idx].speed = mps2sp(WP->speed); - if ( WP->altitude != unknown_alt ) + } + if (WP->altitude != unknown_alt) { trklog->sh[log_idx].height = m2hgt(WP->altitude); + } trkhdr->totalpt ++; trkhdr->next = trkhdr->totalpt; } -static void trl_track_tlr(const route_head *TL) { - struct trkhdr *trkhdr; +static void trl_track_tlr(const route_head* TL) +{ + struct trkhdr* trkhdr; int trk_idx; trk_idx = TRL.loghdr.num; trkhdr = &(TRL.loghdr.trkhdr[trk_idx]); - if ( trkhdr->totalpt == 0 ) + if (trkhdr->totalpt == 0) { trkhdr->occupied = TRK_UNUSED; + } TRL.loghdr.num = -1; } -static void trl_write(void) { - struct trkhdr *trkhdr; - void *buf; +static void trl_write(void) +{ + struct trkhdr* trkhdr; + void* buf; int i; size_t fill; @@ -845,96 +914,105 @@ static void trl_write(void) { track_disp_all(trl_track_hdr, trl_track_tlr, trl_track_wpt); trl_swap(&TRL); - + fill = 0x10000 - 2 * sizeof(struct trklog); buf = xmalloc(fill); - if (buf == NULL) + if (buf == NULL) { fatal(MYNAME ": Not enough memory\n"); + } memset(buf, 0xff, fill); for (i=0; iname); + } } xfree(buf); fill = 0x1000 - sizeof(struct loghdr); buf = xmalloc(fill); - if (buf == NULL) + if (buf == NULL) { fatal(MYNAME ": Not enough memory\n"); + } memset(buf, 0xff, fill); - if ( gbfwrite(&(TRL.loghdr), sizeof(struct loghdr), 1, fout) != 1 || - gbfwrite(buf, fill, 1, fout) != 1 ) + if (gbfwrite(&(TRL.loghdr), sizeof(struct loghdr), 1, fout) != 1 || + gbfwrite(buf, fill, 1, fout) != 1) { fatal(MYNAME ": Write error on %s\n", fout->name); + } xfree(buf); } /**************************************************************************/ -static void alan_rd_init(const char *fname) { +static void alan_rd_init(const char* fname) +{ fin = gbfopen(fname, "rb", MYNAME); } -static void alan_rd_deinit(void) { +static void alan_rd_deinit(void) +{ gbfclose(fin); fin = NULL; } -static void alan_wr_init(const char *fname) { +static void alan_wr_init(const char* fname) +{ fout = gbfopen(fname, "wb", MYNAME); } -static void alan_wr_deinit(void) { +static void alan_wr_deinit(void) +{ gbfclose(fout); fout = NULL; } -static void alan_exit(void) { +static void alan_exit(void) +{ return; } /**************************************************************************/ ff_vecs_t alanwpr_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_read | ff_cap_write /* routes */ - }, - alan_rd_init, - alan_wr_init, - alan_rd_deinit, - alan_wr_deinit, - wpr_read, - wpr_write, - alan_exit, - wpr_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command - line parameter */ + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + ff_cap_none /* tracks */, + (ff_cap)(ff_cap_read | ff_cap_write) /* routes */ + }, + alan_rd_init, + alan_wr_init, + alan_rd_deinit, + alan_wr_deinit, + wpr_read, + wpr_write, + alan_exit, + wpr_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command + line parameter */ }; ff_vecs_t alantrl_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - alan_rd_init, - alan_wr_init, - alan_rd_deinit, - alan_wr_deinit, - trl_read, - trl_write, - alan_exit, - trl_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command - line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + alan_rd_init, + alan_wr_init, + alan_rd_deinit, + alan_wr_deinit, + trl_read, + trl_write, + alan_exit, + trl_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command + line parameter */ }; diff --git a/gpsbabel/an1.c b/gpsbabel/an1.c index a0460fd72..b80f66a53 100644 --- a/gpsbabel/an1.c +++ b/gpsbabel/an1.c @@ -27,18 +27,18 @@ #define MYNAME "an1" #include "defs.h" -static gbfile *infile; -static gbfile *outfile; - -static char *output_type = NULL; -static char *road_changes = NULL; -static char *nogc = NULL; -static char *nourl = NULL; -static char *opt_symbol = NULL; -static char *opt_color = NULL; -static char *opt_zoom = NULL; -static char *opt_wpt_type = NULL; -static char *opt_radius = NULL; +static gbfile* infile; +static gbfile* outfile; + +static char* output_type = NULL; +static char* road_changes = NULL; +static char* nogc = NULL; +static char* nourl = NULL; +static char* opt_symbol = NULL; +static char* opt_color = NULL; +static char* opt_zoom = NULL; +static char* opt_wpt_type = NULL; +static char* opt_radius = NULL; static short output_type_num = 0; static short opt_zoom_num = 0; @@ -51,40 +51,58 @@ static long serial=10000; static long rtserial=1; typedef struct roadchange { - long type; - char *name; + long type; + char* name; } roadchange; -roadchange *roadchanges = NULL; +roadchange* roadchanges = NULL; static arglist_t an1_args[] = { - {"type", &output_type, "Type of .an1 file", - "", ARGTYPE_STRING, ARG_NOMINMAX }, - {"road", &road_changes, "Road type changes", - "", ARGTYPE_STRING, ARG_NOMINMAX }, - {"nogc", &nogc, "Do not add geocache data to description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"nourl", &nourl, "Do not add URLs to description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"deficon", &opt_symbol, "Symbol to use for point data", - "Red Flag", ARGTYPE_STRING, ARG_NOMINMAX }, - {"color", &opt_color, "Color for lines or mapnotes", - "red", ARGTYPE_STRING, ARG_NOMINMAX }, - {"zoom", &opt_zoom, "Zoom level to reduce points", - NULL, ARGTYPE_INT, ARG_NOMINMAX }, - {"wpt_type", &opt_wpt_type, - "Waypoint type", - "", ARGTYPE_STRING, ARG_NOMINMAX }, - {"radius", &opt_radius, "Radius for circles", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "type", &output_type, "Type of .an1 file", + "", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "road", &road_changes, "Road type changes", + "", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "nogc", &nogc, "Do not add geocache data to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "nourl", &nourl, "Do not add URLs to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "deficon", &opt_symbol, "Symbol to use for point data", + "Red Flag", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "color", &opt_color, "Color for lines or mapnotes", + "red", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "zoom", &opt_zoom, "Zoom level to reduce points", + NULL, ARGTYPE_INT, ARG_NOMINMAX + }, + { + "wpt_type", &opt_wpt_type, + "Waypoint type", + "", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "radius", &opt_radius, "Radius for circles", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; typedef struct guid { - unsigned long l; - unsigned short s[3]; - unsigned char c[6]; + unsigned long l; + unsigned short s[3]; + unsigned char c[6]; } GUID; #include "an1sym.h" @@ -96,1136 +114,1142 @@ typedef struct guid { #define ReadDouble(f) gbfgetdbl(f) #define WriteDouble(f,d) gbfputdbl((d),f) -static char * -ReadString( gbfile * f, short len ) +static char* +ReadString(gbfile* f, short len) { - char *result = NULL; - result = (char *)xcalloc( 1, len + 1 ); - if ( len ) { - gbfread( result, 1, len, f ); - } - return result; + char* result = NULL; + result = (char*)xcalloc(1, len + 1); + if (len) { + gbfread(result, 1, len, f); + } + return result; } #define ReadChar(f) (unsigned char) gbfgetc(f) #define WriteChar(f,c) gbfputc((unsigned char)(c),f) #define WriteString(f,s) gbfputs((s),f) -static void -ReadGuid( gbfile *f, GUID *guid ) +static void +ReadGuid(gbfile* f, GUID* guid) { - int i = 0; - guid->l = ReadLong( f ); - for ( i = 0; i < 3; i++ ) { - guid->s[i] = ReadShort( f ); - } - for ( i = 0; i < 6; i++ ) { - guid->c[i] = ReadChar( f ); - } + int i = 0; + guid->l = ReadLong(f); + for (i = 0; i < 3; i++) { + guid->s[i] = ReadShort(f); + } + for (i = 0; i < 6; i++) { + guid->c[i] = ReadChar(f); + } } -static void -WriteGuid( gbfile *f, GUID *guid ) +static void +WriteGuid(gbfile* f, GUID* guid) { - int i = 0; - WriteLong( f, guid->l ); - for ( i = 0; i < 3; i++ ) { - WriteShort( f, guid->s[i] ); - } - for ( i = 0; i < 6; i++ ) { - WriteChar( f, guid->c[i] ); - } -} + int i = 0; + WriteLong(f, guid->l); + for (i = 0; i < 3; i++) { + WriteShort(f, guid->s[i]); + } + for (i = 0; i < 6; i++) { + WriteChar(f, guid->c[i]); + } +} static void -Skip(gbfile * f, +Skip(gbfile* f, unsigned long distance) { - gbfseek(f, distance, SEEK_CUR); + gbfseek(f, distance, SEEK_CUR); } static double -DecodeOrd( long ord ) +DecodeOrd(long ord) { - return (double)((gbint32)(0x80000000 - ord)) / 0x800000; + return (double)((gbint32)(0x80000000 - ord)) / 0x800000; } static long -EncodeOrd( double ord ) +EncodeOrd(double ord) { - return (gbint32)(0x80000000 - (gbint32)(ord * 0x800000)); + return (gbint32)(0x80000000 - (gbint32)(ord * 0x800000)); } typedef struct { - short hotspotxhi; - long hotspoty; - long unk1; - GUID guid; - char *name; + short hotspotxhi; + long hotspoty; + long unk1; + GUID guid; + char* name; } an1_symbol_record; typedef struct { - format_specific_data fs; - short magic; - long unk1; - long lon; - long lat; - short type; - long height; - long width; - short unk2; - short unk3; - short serial; - short unk4; - unsigned char create_zoom; - unsigned char visible_zoom; - short unk5; - double radius; /* in km */ - char *name; - char *fontname; - GUID guid; - long fontcolor; - long fontstyle; - long fontsize; - long outlineweight; - long outlinecolor; - long outlineflags; - long fillcolor; - long unk6; - long fillflags; - - /* Added in SA2006/Topo 6.0 */ - short unk6_1; - char *url; - char *comment; - long creation_time; - long modification_time; - char *image_name; + format_specific_data fs; + short magic; + long unk1; + long lon; + long lat; + short type; + long height; + long width; + short unk2; + short unk3; + short serial; + short unk4; + unsigned char create_zoom; + unsigned char visible_zoom; + short unk5; + double radius; /* in km */ + char* name; + char* fontname; + GUID guid; + long fontcolor; + long fontstyle; + long fontsize; + long outlineweight; + long outlinecolor; + long outlineflags; + long fillcolor; + long unk6; + long fillflags; + + /* Added in SA2006/Topo 6.0 */ + short unk6_1; + char* url; + char* comment; + long creation_time; + long modification_time; + char* image_name; } an1_waypoint_record; typedef struct { - format_specific_data fs; - short magic; - long unk0; - long lon; - long lat; - short unk1; + format_specific_data fs; + short magic; + long unk0; + long lon; + long lat; + short unk1; } an1_vertex_record; typedef struct { - format_specific_data fs; - long roadtype; - short serial; - long unk2; - short unk3; - short type; - long unk4; - char *name; - long lineweight; - long linestyle; - long linecolor; - long opacity; - long polyfillcolor; - long unk6; - long unk7; - short unk8; - long pointcount; + format_specific_data fs; + long roadtype; + short serial; + long unk2; + short unk3; + short type; + long unk4; + char* name; + long lineweight; + long linestyle; + long linecolor; + long opacity; + long polyfillcolor; + long unk6; + long unk7; + short unk8; + long pointcount; } an1_line_record; -static an1_waypoint_record *Alloc_AN1_Waypoint( ); - -void Destroy_AN1_Waypoint( void *vwpt ) { - - an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; - xfree( wpt->name ); - xfree( wpt->fontname ); - if ( wpt->url ) xfree( wpt->url ); - if ( wpt->comment ) xfree( wpt->comment ); - if ( wpt->image_name ) xfree( wpt->image_name ); - xfree( vwpt ); +static an1_waypoint_record* Alloc_AN1_Waypoint(); + +void Destroy_AN1_Waypoint(void* vwpt) +{ + + an1_waypoint_record* wpt = (an1_waypoint_record*)vwpt; + xfree(wpt->name); + xfree(wpt->fontname); + if (wpt->url) { + xfree(wpt->url); + } + if (wpt->comment) { + xfree(wpt->comment); + } + if (wpt->image_name) { + xfree(wpt->image_name); + } + xfree(vwpt); } -void Copy_AN1_Waypoint( void **vdwpt, void *vwpt ) { - an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; - an1_waypoint_record *dwpt = Alloc_AN1_Waypoint(); - memcpy( dwpt, wpt, sizeof( an1_waypoint_record )); - dwpt->name = xstrdup( wpt->name ); - dwpt->fontname = xstrdup( wpt->fontname ); - dwpt->url = xstrdup( wpt->url ); - dwpt->comment = xstrdup( wpt->comment ); - dwpt->image_name = xstrdup( wpt->image_name ); - *vdwpt = (void *)dwpt; +void Copy_AN1_Waypoint(void** vdwpt, void* vwpt) +{ + an1_waypoint_record* wpt = (an1_waypoint_record*)vwpt; + an1_waypoint_record* dwpt = Alloc_AN1_Waypoint(); + memcpy(dwpt, wpt, sizeof(an1_waypoint_record)); + dwpt->name = xstrdup(wpt->name); + dwpt->fontname = xstrdup(wpt->fontname); + dwpt->url = xstrdup(wpt->url); + dwpt->comment = xstrdup(wpt->comment); + dwpt->image_name = xstrdup(wpt->image_name); + *vdwpt = (void*)dwpt; } -static an1_waypoint_record *Alloc_AN1_Waypoint( ) { - an1_waypoint_record *result = NULL; - result = (an1_waypoint_record *)xcalloc( sizeof(*result), 1 ); - result->fs.type = FS_AN1W; - result->fs.copy = Copy_AN1_Waypoint; - result->fs.destroy = Destroy_AN1_Waypoint; - result->fs.convert = NULL; - return result; +static an1_waypoint_record* Alloc_AN1_Waypoint() +{ + an1_waypoint_record* result = NULL; + result = (an1_waypoint_record*)xcalloc(sizeof(*result), 1); + result->fs.type = FS_AN1W; + result->fs.copy = Copy_AN1_Waypoint; + result->fs.destroy = Destroy_AN1_Waypoint; + result->fs.convert = NULL; + return result; } - -static an1_vertex_record *Alloc_AN1_Vertex(); -void Destroy_AN1_Vertex( void *vvertex ) { - xfree( vvertex ); +static an1_vertex_record* Alloc_AN1_Vertex(); + +void Destroy_AN1_Vertex(void* vvertex) +{ + xfree(vvertex); } -void Copy_AN1_Vertex( void **vdvert, void *vvert ) { - an1_vertex_record *vert = (an1_vertex_record *)vvert; - an1_vertex_record *dvert = Alloc_AN1_Vertex(); - memcpy( dvert, vert, sizeof( an1_vertex_record )); - *vdvert = (void *)dvert; +void Copy_AN1_Vertex(void** vdvert, void* vvert) +{ + an1_vertex_record* vert = (an1_vertex_record*)vvert; + an1_vertex_record* dvert = Alloc_AN1_Vertex(); + memcpy(dvert, vert, sizeof(an1_vertex_record)); + *vdvert = (void*)dvert; } -static an1_vertex_record *Alloc_AN1_Vertex() { - an1_vertex_record *result = NULL; - result = (an1_vertex_record *)xcalloc( sizeof( *result), 1 ); - result->fs.type = FS_AN1V; - result->fs.copy = Copy_AN1_Vertex; - result->fs.destroy = Destroy_AN1_Vertex; - result->fs.convert = NULL; - return result; +static an1_vertex_record* Alloc_AN1_Vertex() +{ + an1_vertex_record* result = NULL; + result = (an1_vertex_record*)xcalloc(sizeof(*result), 1); + result->fs.type = FS_AN1V; + result->fs.copy = Copy_AN1_Vertex; + result->fs.destroy = Destroy_AN1_Vertex; + result->fs.convert = NULL; + return result; } - -static an1_line_record *Alloc_AN1_Line(); -void Destroy_AN1_Line( void *vline ) { - an1_line_record *line = (an1_line_record *)vline; - xfree( line->name ); - xfree( vline ); +static an1_line_record* Alloc_AN1_Line(); + +void Destroy_AN1_Line(void* vline) +{ + an1_line_record* line = (an1_line_record*)vline; + xfree(line->name); + xfree(vline); } -void Copy_AN1_Line( void **vdline, void *vline ) { - an1_line_record *line = (an1_line_record *)vline; - an1_line_record *dline = Alloc_AN1_Line(); - memcpy( dline, line, sizeof( an1_line_record )); - dline->name = xstrdup( line->name ); - *vdline = (void *)dline; +void Copy_AN1_Line(void** vdline, void* vline) +{ + an1_line_record* line = (an1_line_record*)vline; + an1_line_record* dline = Alloc_AN1_Line(); + memcpy(dline, line, sizeof(an1_line_record)); + dline->name = xstrdup(line->name); + *vdline = (void*)dline; } -static an1_line_record *Alloc_AN1_Line( ) { - an1_line_record *result = NULL; - result = (an1_line_record *)xcalloc( sizeof(*result), 1 ); - result->fs.type = FS_AN1L; - result->fs.copy = Copy_AN1_Line; - result->fs.destroy = Destroy_AN1_Line; - result->fs.convert = NULL; - return result; +static an1_line_record* Alloc_AN1_Line() +{ + an1_line_record* result = NULL; + result = (an1_line_record*)xcalloc(sizeof(*result), 1); + result->fs.type = FS_AN1L; + result->fs.copy = Copy_AN1_Line; + result->fs.destroy = Destroy_AN1_Line; + result->fs.convert = NULL; + return result; } -static void Destroy_AN1_Symbol( an1_symbol_record *symbol ) { - xfree( symbol->name ); +static void Destroy_AN1_Symbol(an1_symbol_record* symbol) +{ + xfree(symbol->name); } -static void Read_AN1_Waypoint( gbfile *f, an1_waypoint_record *wpt ) { - short len; - - wpt->magic = ReadShort( f ); - wpt->unk1 = ReadLong( f ); - wpt->lon = ReadLong( f ); - wpt->lat = ReadLong( f ); - wpt->type = ReadShort( f ); - wpt->height = ReadLong( f ); - wpt->width = ReadLong( f ); - wpt->unk2 = ReadShort( f ); - wpt->unk3 = ReadShort( f ); - wpt->serial = ReadShort( f ); - wpt->unk4 = ReadShort( f ); - wpt->create_zoom = ReadChar( f ); - wpt->visible_zoom = ReadChar( f ); - wpt->unk5 = ReadShort( f ); - wpt->radius = ReadDouble( f ); - len = ReadShort( f ); - wpt->name = ReadString( f, len ); - - if ( len != strlen(wpt->name)) { - /* This happens in 06/6.0 files that put extra data in the - * name record for backward compatibility's sake */ - char *ofs = wpt->name + strlen( wpt->name ) + 1; - wpt->unk6_1 = le_read16( ofs ); - ofs += 2; - - len = le_read16( ofs ); - ofs += 2; - - if ( len ) { - char *oldurlstr; - /* - * Trust URL encoded in new format over one in - * old format if both are present. Whack the - * name starting at '{URL='. - */ - oldurlstr = strstr(wpt->name, "{URL="); - if (oldurlstr) { - *oldurlstr = 0; - } - - wpt->url = xcalloc( len+1, 1 ); - memcpy( wpt->url, ofs, len ); - ofs += len; - } - - len = le_read16( ofs ); - ofs += 2; - - if ( len ) { - wpt->comment = xcalloc( len+1, 1 ); - memcpy( wpt->comment, ofs, len ); - ofs += len; - } - - /* these are quadwords, presumably for year-2038 compat. */ - wpt->creation_time = le_read32( ofs ); - ofs += 8; - - wpt->modification_time = le_read32( ofs ); - ofs += 8; - } - - if ( wpt->type == 0x12 ) { - /* 'image' type */ - ReadShort( f ); /* length of font + filename */ - len = ReadShort( f ); - wpt->fontname = ReadString( f, len ); - len = ReadShort( f ); - wpt->image_name = ReadString( f, len ); - } - else { - len = ReadShort( f ); - wpt->fontname = ReadString( f, len ); - wpt->image_name = NULL; - } - ReadGuid( f, &wpt->guid ); - wpt->fontcolor = ReadLong( f ); - wpt->fontstyle = ReadLong( f ); - wpt->fontsize = ReadLong( f ); - wpt->outlineweight = ReadLong( f ); - wpt->outlinecolor = ReadLong( f ); - wpt->outlineflags = ReadLong( f ); - wpt->fillcolor = ReadLong( f ); - wpt->unk6 = ReadLong( f ); - wpt->fillflags = ReadLong( f ); +static void Read_AN1_Waypoint(gbfile* f, an1_waypoint_record* wpt) +{ + short len; + + wpt->magic = ReadShort(f); + wpt->unk1 = ReadLong(f); + wpt->lon = ReadLong(f); + wpt->lat = ReadLong(f); + wpt->type = ReadShort(f); + wpt->height = ReadLong(f); + wpt->width = ReadLong(f); + wpt->unk2 = ReadShort(f); + wpt->unk3 = ReadShort(f); + wpt->serial = ReadShort(f); + wpt->unk4 = ReadShort(f); + wpt->create_zoom = ReadChar(f); + wpt->visible_zoom = ReadChar(f); + wpt->unk5 = ReadShort(f); + wpt->radius = ReadDouble(f); + len = ReadShort(f); + wpt->name = ReadString(f, len); + + if (len != strlen(wpt->name)) { + /* This happens in 06/6.0 files that put extra data in the + * name record for backward compatibility's sake */ + char* ofs = wpt->name + strlen(wpt->name) + 1; + wpt->unk6_1 = le_read16(ofs); + ofs += 2; + + len = le_read16(ofs); + ofs += 2; + + if (len) { + char* oldurlstr; + /* + * Trust URL encoded in new format over one in + * old format if both are present. Whack the + * name starting at '{URL='. + */ + oldurlstr = strstr(wpt->name, "{URL="); + if (oldurlstr) { + *oldurlstr = 0; + } + + wpt->url = (char*) xcalloc(len+1, 1); + memcpy(wpt->url, ofs, len); + ofs += len; + } + + len = le_read16(ofs); + ofs += 2; + + if (len) { + wpt->comment = (char*) xcalloc(len+1, 1); + memcpy(wpt->comment, ofs, len); + ofs += len; + } + + /* these are quadwords, presumably for year-2038 compat. */ + wpt->creation_time = le_read32(ofs); + ofs += 8; + + wpt->modification_time = le_read32(ofs); + ofs += 8; + } + + if (wpt->type == 0x12) { + /* 'image' type */ + ReadShort(f); /* length of font + filename */ + len = ReadShort(f); + wpt->fontname = ReadString(f, len); + len = ReadShort(f); + wpt->image_name = ReadString(f, len); + } else { + len = ReadShort(f); + wpt->fontname = ReadString(f, len); + wpt->image_name = NULL; + } + ReadGuid(f, &wpt->guid); + wpt->fontcolor = ReadLong(f); + wpt->fontstyle = ReadLong(f); + wpt->fontsize = ReadLong(f); + wpt->outlineweight = ReadLong(f); + wpt->outlinecolor = ReadLong(f); + wpt->outlineflags = ReadLong(f); + wpt->fillcolor = ReadLong(f); + wpt->unk6 = ReadLong(f); + wpt->fillflags = ReadLong(f); } -static void Write_AN1_Waypoint( gbfile *f, an1_waypoint_record *wpt ) { - short len; - - WriteShort( f, wpt->magic ); - WriteLong( f, wpt->unk1 ); - WriteLong( f, wpt->lon ); - WriteLong( f, wpt->lat ); - WriteShort( f, wpt->type ); - WriteLong( f, wpt->height ); - WriteLong( f, wpt->width ); - WriteShort( f, wpt->unk2 ); - WriteShort( f, wpt->unk3 ); - WriteShort( f, wpt->serial ); - WriteShort( f, wpt->unk4 ); - WriteChar( f, wpt->create_zoom ); - WriteChar( f, wpt->visible_zoom ); - WriteShort( f, wpt->unk5 ); - WriteDouble( f, wpt->radius ); - - len = strlen( wpt->name ) + 1 + 2 + 2 + - (wpt->url ? strlen( wpt->url ) : 0) + 2 + - (wpt->comment ? strlen( wpt->comment ) : 0) + 8 + 8; - WriteShort( f, len ); - WriteString( f, wpt->name ); - WriteChar( f, 0 ); /* name string terminator */ - - WriteShort( f, wpt->unk6_1 ); - - if ( wpt->url ) { - WriteShort( f, strlen(wpt->url)); - WriteString( f, wpt->url ); - } - else { - WriteShort( f, 0 ); - } - - if ( wpt->comment ) { - WriteShort( f, strlen(wpt->comment)); - WriteString( f, wpt->comment ); - } - else { - WriteShort( f, 0 ); - } - - WriteLong( f, wpt->creation_time ); - WriteLong( f, 0 ); - - WriteLong( f, wpt->modification_time ); - WriteLong( f, 0 ); - - if ( wpt->type == 0x12 ) { /* image */ - len = 2 + (wpt->fontname ? strlen( wpt->fontname ) : 0 ) + - 2 + (wpt->image_name ? strlen( wpt->image_name ) : 0 ); - WriteShort( f, len ); - if ( wpt->fontname ) { - len = strlen( wpt->fontname ); - WriteShort( f, len ); - WriteString( f, wpt->fontname ); - } - else { - WriteShort( f, 0 ); - } - if ( wpt->image_name ) { - len = strlen( wpt->image_name ); - WriteShort( f, len ); - WriteString( f, wpt->image_name ); - } - else { - WriteShort( f, 0 ); - } - } - else { - len = strlen( wpt->fontname ); - WriteShort( f, len ); - WriteString( f, wpt->fontname ); - } - WriteGuid( f, &wpt->guid ); - WriteLong( f, wpt->fontcolor ); - WriteLong( f, wpt->fontstyle ); - WriteLong( f, wpt->fontsize ); - WriteLong( f, wpt->outlineweight ); - WriteLong( f, wpt->outlinecolor ); - WriteLong( f, wpt->outlineflags ); - WriteLong( f, wpt->fillcolor ); - WriteLong( f, wpt->unk6 ); - WriteLong( f, wpt->fillflags ); +static void Write_AN1_Waypoint(gbfile* f, an1_waypoint_record* wpt) +{ + short len; + + WriteShort(f, wpt->magic); + WriteLong(f, wpt->unk1); + WriteLong(f, wpt->lon); + WriteLong(f, wpt->lat); + WriteShort(f, wpt->type); + WriteLong(f, wpt->height); + WriteLong(f, wpt->width); + WriteShort(f, wpt->unk2); + WriteShort(f, wpt->unk3); + WriteShort(f, wpt->serial); + WriteShort(f, wpt->unk4); + WriteChar(f, wpt->create_zoom); + WriteChar(f, wpt->visible_zoom); + WriteShort(f, wpt->unk5); + WriteDouble(f, wpt->radius); + + len = strlen(wpt->name) + 1 + 2 + 2 + + (wpt->url ? strlen(wpt->url) : 0) + 2 + + (wpt->comment ? strlen(wpt->comment) : 0) + 8 + 8; + WriteShort(f, len); + WriteString(f, wpt->name); + WriteChar(f, 0); /* name string terminator */ + + WriteShort(f, wpt->unk6_1); + + if (wpt->url) { + WriteShort(f, strlen(wpt->url)); + WriteString(f, wpt->url); + } else { + WriteShort(f, 0); + } + + if (wpt->comment) { + WriteShort(f, strlen(wpt->comment)); + WriteString(f, wpt->comment); + } else { + WriteShort(f, 0); + } + + WriteLong(f, wpt->creation_time); + WriteLong(f, 0); + + WriteLong(f, wpt->modification_time); + WriteLong(f, 0); + + if (wpt->type == 0x12) { /* image */ + len = 2 + (wpt->fontname ? strlen(wpt->fontname) : 0) + + 2 + (wpt->image_name ? strlen(wpt->image_name) : 0); + WriteShort(f, len); + if (wpt->fontname) { + len = strlen(wpt->fontname); + WriteShort(f, len); + WriteString(f, wpt->fontname); + } else { + WriteShort(f, 0); + } + if (wpt->image_name) { + len = strlen(wpt->image_name); + WriteShort(f, len); + WriteString(f, wpt->image_name); + } else { + WriteShort(f, 0); + } + } else { + len = strlen(wpt->fontname); + WriteShort(f, len); + WriteString(f, wpt->fontname); + } + WriteGuid(f, &wpt->guid); + WriteLong(f, wpt->fontcolor); + WriteLong(f, wpt->fontstyle); + WriteLong(f, wpt->fontsize); + WriteLong(f, wpt->outlineweight); + WriteLong(f, wpt->outlinecolor); + WriteLong(f, wpt->outlineflags); + WriteLong(f, wpt->fillcolor); + WriteLong(f, wpt->unk6); + WriteLong(f, wpt->fillflags); } -static void Read_AN1_Vertex( gbfile *f, an1_vertex_record *vertex ) { - - vertex->magic = ReadShort( f ); - vertex->unk0 = ReadLong( f ); - vertex->lon = ReadLong( f ); - vertex->lat = ReadLong( f ); - vertex->unk1 = ReadShort( f ); +static void Read_AN1_Vertex(gbfile* f, an1_vertex_record* vertex) +{ + + vertex->magic = ReadShort(f); + vertex->unk0 = ReadLong(f); + vertex->lon = ReadLong(f); + vertex->lat = ReadLong(f); + vertex->unk1 = ReadShort(f); } -static void Write_AN1_Vertex( gbfile *f, an1_vertex_record *vertex ) { - WriteShort( f, vertex->magic ); - WriteLong( f, vertex->unk0 ); - WriteLong( f, vertex->lon ); - WriteLong( f, vertex->lat ); - WriteShort( f, vertex->unk1 ); +static void Write_AN1_Vertex(gbfile* f, an1_vertex_record* vertex) +{ + WriteShort(f, vertex->magic); + WriteLong(f, vertex->unk0); + WriteLong(f, vertex->lon); + WriteLong(f, vertex->lat); + WriteShort(f, vertex->unk1); } -static void Read_AN1_Line( gbfile *f, an1_line_record *line ) { - - short len; - - line->roadtype = ReadLong( f ); - line->serial = ReadShort( f ); - line->unk2 = ReadLong( f ); - line->unk3 = ReadShort( f ); - line->type = ReadShort( f ); - line->unk4 = ReadLong( f ); - len = ReadShort( f ); - line->name = ReadString( f, len ); - line->lineweight = ReadShort( f ); - line->linestyle = ReadLong( f ); - line->linecolor = ReadLong( f ); - line->opacity = ReadLong( f ); - line->polyfillcolor = ReadLong( f ); - line->unk6 = ReadLong( f ); - line->unk7 = ReadLong( f ); - line->unk8 = ReadShort( f ); - line->pointcount = ReadLong( f ); +static void Read_AN1_Line(gbfile* f, an1_line_record* line) +{ + + short len; + + line->roadtype = ReadLong(f); + line->serial = ReadShort(f); + line->unk2 = ReadLong(f); + line->unk3 = ReadShort(f); + line->type = ReadShort(f); + line->unk4 = ReadLong(f); + len = ReadShort(f); + line->name = ReadString(f, len); + line->lineweight = ReadShort(f); + line->linestyle = ReadLong(f); + line->linecolor = ReadLong(f); + line->opacity = ReadLong(f); + line->polyfillcolor = ReadLong(f); + line->unk6 = ReadLong(f); + line->unk7 = ReadLong(f); + line->unk8 = ReadShort(f); + line->pointcount = ReadLong(f); } -static void Write_AN1_Line( gbfile *f, an1_line_record *line ) { - short len; - - WriteLong( f, line->roadtype ); - WriteShort( f, line->serial ); - WriteLong( f, line->unk2 ); - WriteShort( f, line->unk3 ); - WriteShort( f, line->type ); - WriteLong( f, line->unk4 ); - len = strlen( line->name ); - WriteShort( f, len ); - WriteString( f, line->name ); - WriteShort( f, (short) line->lineweight ); - WriteLong( f, line->linestyle ); - WriteLong( f, line->linecolor ); - WriteLong( f, line->opacity ); - WriteLong( f, line->polyfillcolor ); - WriteLong( f, line->unk6 ); - WriteLong( f, line->unk7 ); - WriteShort( f, line->unk8 ); - WriteLong( f, line->pointcount ); -} - -static void Skip_AN1_IL( gbfile *f ) { - Skip( f, 26 ); +static void Write_AN1_Line(gbfile* f, an1_line_record* line) +{ + short len; + + WriteLong(f, line->roadtype); + WriteShort(f, line->serial); + WriteLong(f, line->unk2); + WriteShort(f, line->unk3); + WriteShort(f, line->type); + WriteLong(f, line->unk4); + len = strlen(line->name); + WriteShort(f, len); + WriteString(f, line->name); + WriteShort(f, (short) line->lineweight); + WriteLong(f, line->linestyle); + WriteLong(f, line->linecolor); + WriteLong(f, line->opacity); + WriteLong(f, line->polyfillcolor); + WriteLong(f, line->unk6); + WriteLong(f, line->unk7); + WriteShort(f, line->unk8); + WriteLong(f, line->pointcount); } -static void Skip_AN1_BM( gbfile *f ) { - unsigned long bmsize; - unsigned long palettesize; - unsigned long bmisize; - unsigned long bitoffset; - - Skip( f, 8 ); /* BITMAPFILEHEADER fields 1-3 */ - bitoffset = ReadLong( f ); - - bmisize = ReadLong( f ); - Skip( f, 16 ); /* BITMAPINFOHEADER fields 2-6 */ - bmsize = ReadLong( f ); - Skip( f, 16 ); /* BITMAPINFOHEADER fields 8-11 */ - - palettesize = bitoffset - bmisize - 14; - Skip( f, bmsize + palettesize ); +static void Skip_AN1_IL(gbfile* f) +{ + Skip(f, 26); } -static void Read_AN1_Symbol( gbfile *f, an1_symbol_record *symbol ) { - short len; - - /* This is just the high word of a long; we ate the low - * word in the caller. Fortunately, we don't care. */ - symbol->hotspotxhi = ReadShort( f ); - symbol->hotspoty = ReadLong( f ); - symbol->unk1 = ReadLong( f ); - ReadGuid( f, &symbol->guid ); - len = ReadChar( f ); - symbol->name = ReadString( f, len ); +static void Skip_AN1_BM(gbfile* f) +{ + unsigned long bmsize; + unsigned long palettesize; + unsigned long bmisize; + unsigned long bitoffset; + + Skip(f, 8); /* BITMAPFILEHEADER fields 1-3 */ + bitoffset = ReadLong(f); + + bmisize = ReadLong(f); + Skip(f, 16); /* BITMAPINFOHEADER fields 2-6 */ + bmsize = ReadLong(f); + Skip(f, 16); /* BITMAPINFOHEADER fields 8-11 */ + + palettesize = bitoffset - bmisize - 14; + Skip(f, bmsize + palettesize); } -static void Read_AN1_Header( gbfile *f ) { - unsigned short magic; - unsigned short type; - - magic = ReadShort( f ); - type = ReadShort( f ); - - last_read_type = type; +static void Read_AN1_Symbol(gbfile* f, an1_symbol_record* symbol) +{ + short len; + + /* This is just the high word of a long; we ate the low + * word in the caller. Fortunately, we don't care. */ + symbol->hotspotxhi = ReadShort(f); + symbol->hotspoty = ReadLong(f); + symbol->unk1 = ReadLong(f); + ReadGuid(f, &symbol->guid); + len = ReadChar(f); + symbol->name = ReadString(f, len); } -static void Write_AN1_Header( gbfile *f ) { - WriteShort( f, 11557 ); - WriteShort( f, output_type_num ); +static void Read_AN1_Header(gbfile* f) +{ + unsigned short magic; + unsigned short type; + + magic = ReadShort(f); + type = ReadShort(f); + + last_read_type = type; } -static void Read_AN1_Bitmaps( gbfile *f ) { - long count; - unsigned short magic; - an1_symbol_record symbol; - - count = ReadLong( f ); - - while ( count ) { - magic = ReadShort( f ); - switch (magic) { - case 0x4d42: - Skip_AN1_BM( f ); - break; - case 0x4c49: - Skip_AN1_IL( f ); - break; - default: - Read_AN1_Symbol( f, &symbol ); - Destroy_AN1_Symbol( &symbol ); - count--; - break; - } - } - - /* Read the symbol table */ +static void Write_AN1_Header(gbfile* f) +{ + WriteShort(f, 11557); + WriteShort(f, output_type_num); } -static void Write_AN1_Bitmaps( gbfile *f ) { - /* On write, we don't output any bitmaps, so writing them - * is just a matter of writing a count of zero */ - WriteLong( f, 0 ); +static void Read_AN1_Bitmaps(gbfile* f) +{ + long count; + unsigned short magic; + an1_symbol_record symbol; + + count = ReadLong(f); + + while (count) { + magic = ReadShort(f); + switch (magic) { + case 0x4d42: + Skip_AN1_BM(f); + break; + case 0x4c49: + Skip_AN1_IL(f); + break; + default: + Read_AN1_Symbol(f, &symbol); + Destroy_AN1_Symbol(&symbol); + count--; + break; + } + } + + /* Read the symbol table */ } -static void Read_AN1_Waypoints( gbfile *f ) { - unsigned long count = 0; - unsigned long i = 0; - an1_waypoint_record *rec = NULL; - waypoint *wpt_tmp; - char *icon = NULL; - char *url = NULL; - ReadShort( f ); - count = ReadLong( f ); - for (i = 0; i < count; i++ ) { - rec = Alloc_AN1_Waypoint(); - Read_AN1_Waypoint( f, rec ); - wpt_tmp = waypt_new(); - - if ( rec->creation_time ) { - wpt_tmp->creation_time = rec->creation_time; - } - wpt_tmp->longitude = -DecodeOrd( rec->lon ); - wpt_tmp->latitude = DecodeOrd( rec->lat ); - wpt_tmp->notes = xstrdup( rec->comment ); - wpt_tmp->description = xstrdup( rec->name ); - if ( rec->url ) { - wpt_tmp->url = xstrdup( rec->url ); - } - else if ( NULL != (url=strstr(wpt_tmp->description, "{URL="))) { - *url = '\0'; - url += 5; - url[strlen(url)-1] = '\0'; - wpt_tmp->url = xstrdup( url ); - } - - if ( rec->image_name ) { - wpt_tmp->icon_descr = xstrdup( rec->image_name ); - } - else if (FindIconByGuid(&rec->guid, &icon)) { - wpt_tmp->icon_descr = icon; - } - - fs_chain_add( &(wpt_tmp->fs), (format_specific_data *)rec); - rec = NULL; - waypt_add( wpt_tmp ); - } +static void Write_AN1_Bitmaps(gbfile* f) +{ + /* On write, we don't output any bitmaps, so writing them + * is just a matter of writing a count of zero */ + WriteLong(f, 0); +} + +static void Read_AN1_Waypoints(gbfile* f) +{ + unsigned long count = 0; + unsigned long i = 0; + an1_waypoint_record* rec = NULL; + waypoint* wpt_tmp; + char* icon = NULL; + char* url = NULL; + ReadShort(f); + count = ReadLong(f); + for (i = 0; i < count; i++) { + rec = Alloc_AN1_Waypoint(); + Read_AN1_Waypoint(f, rec); + wpt_tmp = waypt_new(); + + if (rec->creation_time) { + wpt_tmp->creation_time = rec->creation_time; + } + wpt_tmp->longitude = -DecodeOrd(rec->lon); + wpt_tmp->latitude = DecodeOrd(rec->lat); + wpt_tmp->notes = xstrdup(rec->comment); + wpt_tmp->description = xstrdup(rec->name); + if (rec->url) { + wpt_tmp->url = xstrdup(rec->url); + } else if (NULL != (url=strstr(wpt_tmp->description, "{URL="))) { + *url = '\0'; + url += 5; + url[strlen(url)-1] = '\0'; + wpt_tmp->url = xstrdup(url); + } + + if (rec->image_name) { + wpt_tmp->icon_descr = xstrdup(rec->image_name); + } else if (FindIconByGuid(&rec->guid, &icon)) { + wpt_tmp->icon_descr = icon; + } + + fs_chain_add(&(wpt_tmp->fs), (format_specific_data*)rec); + rec = NULL; + waypt_add(wpt_tmp); + } } static void -Write_One_AN1_Waypoint( const waypoint *wpt ) +Write_One_AN1_Waypoint(const waypoint* wpt) { - an1_waypoint_record *rec; - int local; - format_specific_data *fs = NULL; - - fs = fs_chain_find( wpt->fs, FS_AN1W ); - if ( fs ) { - rec = (an1_waypoint_record *)fs; - xfree( rec->name ); - local = 0; - if ( opt_zoom ) - rec->visible_zoom = opt_zoom_num; - } - else { - rec = Alloc_AN1_Waypoint(); - local = 1; - rec->magic = 1; - rec->type = wpt_type_num; - rec->unk2 = 3; - rec->unk3 = 18561; - rec->radius = radius; - rec->fillcolor = opt_color_num; - rec->fillflags = 3; - if ( wpt_type_num == 5 ) rec->fillflags = 0x8200; - rec->height = -50; - rec->width = 20; - rec->fontname = xstrdup( "Arial" ); - FindIconByName( opt_symbol, &rec->guid ); - rec->fontsize = 10; - rec->visible_zoom = opt_zoom?opt_zoom_num:10; - rec->unk6_1 = 1; - } - rec->name = xstrdup( wpt->description ); - - if ( !nogc && wpt->gc_data->id ) { - char *extra = xmalloc( 25 + strlen(wpt->gc_data->placer) + strlen( wpt->shortname )); - sprintf( extra, "\r\nBy %s\r\n%s (%1.1f/%1.1f)", - wpt->gc_data->placer, - wpt->shortname, wpt->gc_data->diff/10.0, - wpt->gc_data->terr/10.0); - rec->name = xstrappend( rec->name, extra ); - xfree( extra ); - } - - if ( !nourl && wpt->url ) { - int len = 7+strlen(wpt->url); - char *extra = (char *)xmalloc( len ); - sprintf( extra, "{URL=%s}", wpt->url ); - rec->name = xstrappend( rec->name, extra ); - xfree( extra ); - rec->url = xstrdup( wpt->url ); - } - - if ( wpt->notes ) { - if ( rec->comment ) { - xfree( rec->comment ); - } - rec->comment = xstrdup( wpt->notes ); - } - - - rec->creation_time = rec->modification_time = wpt->creation_time; - rec->lat = EncodeOrd( wpt->latitude ); - rec->lon = EncodeOrd( -wpt->longitude ); - rec->serial = serial++; - - if ( rec->type == 0x12 ) { /* image */ - if ( strstr( wpt->icon_descr, ":\\" )) { - rec->image_name = xstrdup( wpt->icon_descr ); - rec->height = -244; - rec->width = -1; - } - } - if ( !rec->image_name && wpt->icon_descr ) { - FindIconByName( (char *)(void *)wpt->icon_descr, &rec->guid ); - } - - Write_AN1_Waypoint( outfile, rec ); - if ( local ) { - Destroy_AN1_Waypoint( rec ); - } + an1_waypoint_record* rec; + int local; + format_specific_data* fs = NULL; + + fs = fs_chain_find(wpt->fs, FS_AN1W); + if (fs) { + rec = (an1_waypoint_record*)fs; + xfree(rec->name); + local = 0; + if (opt_zoom) { + rec->visible_zoom = opt_zoom_num; + } + } else { + rec = Alloc_AN1_Waypoint(); + local = 1; + rec->magic = 1; + rec->type = wpt_type_num; + rec->unk2 = 3; + rec->unk3 = 18561; + rec->radius = radius; + rec->fillcolor = opt_color_num; + rec->fillflags = 3; + if (wpt_type_num == 5) { + rec->fillflags = 0x8200; + } + rec->height = -50; + rec->width = 20; + rec->fontname = xstrdup("Arial"); + FindIconByName(opt_symbol, &rec->guid); + rec->fontsize = 10; + rec->visible_zoom = opt_zoom?opt_zoom_num:10; + rec->unk6_1 = 1; + } + rec->name = xstrdup(wpt->description); + + if (!nogc && wpt->gc_data->id) { + char* extra = (char*) xmalloc(25 + strlen(wpt->gc_data->placer) + strlen(wpt->shortname)); + sprintf(extra, "\r\nBy %s\r\n%s (%1.1f/%1.1f)", + wpt->gc_data->placer, + wpt->shortname, wpt->gc_data->diff/10.0, + wpt->gc_data->terr/10.0); + rec->name = xstrappend(rec->name, extra); + xfree(extra); + } + + if (!nourl && wpt->url) { + int len = 7+strlen(wpt->url); + char* extra = (char*)xmalloc(len); + sprintf(extra, "{URL=%s}", wpt->url); + rec->name = xstrappend(rec->name, extra); + xfree(extra); + rec->url = xstrdup(wpt->url); + } + + if (wpt->notes) { + if (rec->comment) { + xfree(rec->comment); + } + rec->comment = xstrdup(wpt->notes); + } + + + rec->creation_time = rec->modification_time = wpt->creation_time; + rec->lat = EncodeOrd(wpt->latitude); + rec->lon = EncodeOrd(-wpt->longitude); + rec->serial = serial++; + + if (rec->type == 0x12) { /* image */ + if (strstr(wpt->icon_descr, ":\\")) { + rec->image_name = xstrdup(wpt->icon_descr); + rec->height = -244; + rec->width = -1; + } + } + if (!rec->image_name && wpt->icon_descr) { + FindIconByName((char*)(void*)wpt->icon_descr, &rec->guid); + } + + Write_AN1_Waypoint(outfile, rec); + if (local) { + Destroy_AN1_Waypoint(rec); + } } -static void Write_AN1_Waypoints( gbfile *f ) { - WriteShort( f, 2 ); - WriteLong( f, waypt_count() ); - waypt_disp_all( Write_One_AN1_Waypoint ); +static void Write_AN1_Waypoints(gbfile* f) +{ + WriteShort(f, 2); + WriteLong(f, waypt_count()); + waypt_disp_all(Write_One_AN1_Waypoint); } -static void Read_AN1_Lines( gbfile *f ) { - unsigned long count = 0; - unsigned long i = 0; - unsigned long j = 0; - an1_line_record *rec = NULL; - an1_vertex_record *vert = NULL; - route_head *rte_head; - waypoint *wpt_tmp; - - ReadShort( f ); - count = ReadLong( f ); - for (i = 0; i < count; i++ ) { - rec = Alloc_AN1_Line(); - Read_AN1_Line( f, rec ); - /* create route rec */ - rte_head = route_head_alloc(); - rte_head->line_color.bbggrr = rec->linecolor; - if (rec->opacity == 0x8200) - rte_head->line_color.opacity = 128; - // lineweight isn't set for dashed/dotted lines - // Since we don't have a way to represent this internally yet, - // use leave line_width at the default. - if(rec->lineweight) - rte_head->line_width = rec->lineweight; - rte_head->rte_name = xstrdup(rec->name); - fs_chain_add( &rte_head->fs, (format_specific_data *)rec ); - route_add_head(rte_head); - for (j = 0; j < (unsigned) rec->pointcount; j++ ) { - vert = Alloc_AN1_Vertex(); - Read_AN1_Vertex( f, vert ); - - /* create route point */ - wpt_tmp = waypt_new(); - wpt_tmp->latitude = DecodeOrd( vert->lat ); - wpt_tmp->longitude = -DecodeOrd( vert->lon ); - wpt_tmp->shortname = (char *) xmalloc(7); - sprintf( wpt_tmp->shortname, "\\%5.5lx", rtserial++ ); - fs_chain_add( &wpt_tmp->fs, - (format_specific_data *)vert ); - route_add_wpt(rte_head, wpt_tmp); - } - } +static void Read_AN1_Lines(gbfile* f) +{ + unsigned long count = 0; + unsigned long i = 0; + unsigned long j = 0; + an1_line_record* rec = NULL; + an1_vertex_record* vert = NULL; + route_head* rte_head; + waypoint* wpt_tmp; + + ReadShort(f); + count = ReadLong(f); + for (i = 0; i < count; i++) { + rec = Alloc_AN1_Line(); + Read_AN1_Line(f, rec); + /* create route rec */ + rte_head = route_head_alloc(); + rte_head->line_color.bbggrr = rec->linecolor; + if (rec->opacity == 0x8200) { + rte_head->line_color.opacity = 128; + } + // lineweight isn't set for dashed/dotted lines + // Since we don't have a way to represent this internally yet, + // use leave line_width at the default. + if (rec->lineweight) { + rte_head->line_width = rec->lineweight; + } + rte_head->rte_name = xstrdup(rec->name); + fs_chain_add(&rte_head->fs, (format_specific_data*)rec); + route_add_head(rte_head); + for (j = 0; j < (unsigned) rec->pointcount; j++) { + vert = Alloc_AN1_Vertex(); + Read_AN1_Vertex(f, vert); + + /* create route point */ + wpt_tmp = waypt_new(); + wpt_tmp->latitude = DecodeOrd(vert->lat); + wpt_tmp->longitude = -DecodeOrd(vert->lon); + wpt_tmp->shortname = (char*) xmalloc(7); + sprintf(wpt_tmp->shortname, "\\%5.5lx", rtserial++); + fs_chain_add(&wpt_tmp->fs, + (format_specific_data*)vert); + route_add_wpt(rte_head, wpt_tmp); + } + } } static void -Make_Road_Changes( an1_line_record *rec ) { - int i = 0; - - if ( !rec ) { - return; - } - - if ( !roadchanges ) { - return; - } - - while ( roadchanges[i].name ) { - if ( !case_ignore_strcmp(roadchanges[i].name, rec->name )) { - rec->roadtype = roadchanges[i].type; - break; - } - i++; - } +Make_Road_Changes(an1_line_record* rec) +{ + int i = 0; + + if (!rec) { + return; + } + + if (!roadchanges) { + return; + } + + while (roadchanges[i].name) { + if (!case_ignore_strcmp(roadchanges[i].name, rec->name)) { + rec->roadtype = roadchanges[i].type; + break; + } + i++; + } } - + static void -Write_One_AN1_Line( const route_head *rte ) +Write_One_AN1_Line(const route_head* rte) { - an1_line_record *rec; - int local; - format_specific_data *fs = NULL; - - fs = fs_chain_find( rte->fs, FS_AN1L ); - - if ( fs ) { - rec = (an1_line_record *)(void *)fs; - local = 0; - switch (output_type_num) { - case 1: - if ( rec->type != 14 ) { - rec = Alloc_AN1_Line(); - memcpy( rec, fs, sizeof(an1_line_record)); - local = 1; - rec->roadtype = 0x11100541; - rec->unk2 = 655360; - rec->type = 14; - rec->unk8 = 2; - } // end if - Make_Road_Changes( rec ); - break; - case 2: - if ( rec->type != 15 ) { - rec = Alloc_AN1_Line(); - memcpy( rec, fs, sizeof(an1_line_record)); - local = 1; - rec->type = 15; - } // end if - break; - case 4: - if ( rec->type != 16 ) { - rec = Alloc_AN1_Line(); - memcpy( rec, fs, sizeof(an1_line_record)); - local = 1; - rec->type = 16; - } // end if - break; - } - } - else { - rec = Alloc_AN1_Line(); - local = 1; - rec->name = NULL; - switch (output_type_num) { - /* drawing road trail waypoint track */ - case 1: /* road */ - rec->roadtype = 0x11100541; - rec->unk2 = 655360; - rec->type = 14; - rec->unk8 = 2; - rec->name = xstrdup( rte->rte_name ); - break; - - case 2: /* trail */ - rec->roadtype = 0x11071c50; - rec->unk2 = 917504; - rec->type = 15; - rec->unk8 = 2; - break; - - case 4: /* track */ - rec->roadtype = 0x48800015; - rec->unk2 = 917504; - rec->type = 16; - rec->unk4 = 2; - rec->unk8 = 2; - break; - - case 0: /* drawing */ - case 3: /* waypoint - shouldn't have lines */ - default: - rec->roadtype = 0x48800015; - rec->unk2 = 1048576; - rec->type = 2; - rec->unk4 = 2; - rec->lineweight = 6; - rec->linecolor = opt_color_num; /* red */ - rec->opacity = 3; - rec->unk8 = 2; - break; - } - if ( !rec->name ) { - rec->name = xstrdup( "" ); - } - - } - rec->serial = serial++; - rec->pointcount = rte->rte_waypt_ct; - Write_AN1_Line( outfile, rec ); - if ( local ) { - Destroy_AN1_Line( rec ); - } + an1_line_record* rec; + int local; + format_specific_data* fs = NULL; + + fs = fs_chain_find(rte->fs, FS_AN1L); + + if (fs) { + rec = (an1_line_record*)(void*)fs; + local = 0; + switch (output_type_num) { + case 1: + if (rec->type != 14) { + rec = Alloc_AN1_Line(); + memcpy(rec, fs, sizeof(an1_line_record)); + local = 1; + rec->roadtype = 0x11100541; + rec->unk2 = 655360; + rec->type = 14; + rec->unk8 = 2; + } // end if + Make_Road_Changes(rec); + break; + case 2: + if (rec->type != 15) { + rec = Alloc_AN1_Line(); + memcpy(rec, fs, sizeof(an1_line_record)); + local = 1; + rec->type = 15; + } // end if + break; + case 4: + if (rec->type != 16) { + rec = Alloc_AN1_Line(); + memcpy(rec, fs, sizeof(an1_line_record)); + local = 1; + rec->type = 16; + } // end if + break; + } + } else { + rec = Alloc_AN1_Line(); + local = 1; + rec->name = NULL; + switch (output_type_num) { + /* drawing road trail waypoint track */ + case 1: /* road */ + rec->roadtype = 0x11100541; + rec->unk2 = 655360; + rec->type = 14; + rec->unk8 = 2; + rec->name = xstrdup(rte->rte_name); + break; + + case 2: /* trail */ + rec->roadtype = 0x11071c50; + rec->unk2 = 917504; + rec->type = 15; + rec->unk8 = 2; + break; + + case 4: /* track */ + rec->roadtype = 0x48800015; + rec->unk2 = 917504; + rec->type = 16; + rec->unk4 = 2; + rec->unk8 = 2; + break; + + case 0: /* drawing */ + case 3: /* waypoint - shouldn't have lines */ + default: + rec->roadtype = 0x48800015; + rec->unk2 = 1048576; + rec->type = 2; + rec->unk4 = 2; + rec->lineweight = 6; + rec->linecolor = opt_color_num; /* red */ + rec->opacity = 3; + rec->unk8 = 2; + break; + } + if (!rec->name) { + rec->name = xstrdup(""); + } + + } + rec->serial = serial++; + rec->pointcount = rte->rte_waypt_ct; + Write_AN1_Line(outfile, rec); + if (local) { + Destroy_AN1_Line(rec); + } } static void -Write_One_AN1_Vertex( const waypoint *wpt ) +Write_One_AN1_Vertex(const waypoint* wpt) { - an1_vertex_record *rec; - int local; - format_specific_data *fs = NULL; - - fs = fs_chain_find( wpt->fs, FS_AN1V ); - - if ( fs ) { - rec = (an1_vertex_record *)(void *)fs; - local = 0; - } - else { - rec = Alloc_AN1_Vertex(); - local = 1; - rec->magic = 1; - } - rec->lat = EncodeOrd( wpt->latitude ); - rec->lon = EncodeOrd( -wpt->longitude ); - - Write_AN1_Vertex( outfile, rec ); - if ( local ) { - Destroy_AN1_Vertex( rec ); - } + an1_vertex_record* rec; + int local; + format_specific_data* fs = NULL; + + fs = fs_chain_find(wpt->fs, FS_AN1V); + + if (fs) { + rec = (an1_vertex_record*)(void*)fs; + local = 0; + } else { + rec = Alloc_AN1_Vertex(); + local = 1; + rec->magic = 1; + } + rec->lat = EncodeOrd(wpt->latitude); + rec->lon = EncodeOrd(-wpt->longitude); + + Write_AN1_Vertex(outfile, rec); + if (local) { + Destroy_AN1_Vertex(rec); + } } -static void Write_AN1_Lines( gbfile *f ) { - WriteShort( f, 2 ); - WriteLong( f, route_count()+track_count() ); - - route_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex ); - track_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex ); +static void Write_AN1_Lines(gbfile* f) +{ + WriteShort(f, 2); + WriteLong(f, route_count()+track_count()); + + route_disp_all(Write_One_AN1_Line, NULL, Write_One_AN1_Vertex); + track_disp_all(Write_One_AN1_Line, NULL, Write_One_AN1_Vertex); } -static void -Init_Wpt_Type( void ) +static void +Init_Wpt_Type(void) { - if ( !opt_wpt_type || !opt_wpt_type[0] ) { - wpt_type_num = 1; /* marker */ - return; - } - if ((opt_wpt_type[0] & 0xf0) == 0x30) { - wpt_type_num = atoi( opt_wpt_type ); - } - else { - wpt_type_num = 1; /* marker */ - if ( !case_ignore_strcmp( opt_wpt_type, "marker" )) { - wpt_type_num = 1; - } - else if ( !case_ignore_strcmp( opt_wpt_type, "symbol" )) { - wpt_type_num = 1; /* symbol and marker are synonyms */ - } - else if ( !case_ignore_strcmp( opt_wpt_type, "text" )) { - wpt_type_num = 4; - } - else if ( !case_ignore_strcmp( opt_wpt_type, "mapnote" )) { - wpt_type_num = 6; - } - else if ( !case_ignore_strcmp( opt_wpt_type, "circle" )) { - wpt_type_num = 5; - } - else if ( !case_ignore_strcmp( opt_wpt_type, "image" )) { - wpt_type_num = 18; - } - else { - fatal( MYNAME ": wpt_type must be " - "symbol, text, mapnote, circle, or image\n" ); - } - } + if (!opt_wpt_type || !opt_wpt_type[0]) { + wpt_type_num = 1; /* marker */ + return; + } + if ((opt_wpt_type[0] & 0xf0) == 0x30) { + wpt_type_num = atoi(opt_wpt_type); + } else { + wpt_type_num = 1; /* marker */ + if (!case_ignore_strcmp(opt_wpt_type, "marker")) { + wpt_type_num = 1; + } else if (!case_ignore_strcmp(opt_wpt_type, "symbol")) { + wpt_type_num = 1; /* symbol and marker are synonyms */ + } else if (!case_ignore_strcmp(opt_wpt_type, "text")) { + wpt_type_num = 4; + } else if (!case_ignore_strcmp(opt_wpt_type, "mapnote")) { + wpt_type_num = 6; + } else if (!case_ignore_strcmp(opt_wpt_type, "circle")) { + wpt_type_num = 5; + } else if (!case_ignore_strcmp(opt_wpt_type, "image")) { + wpt_type_num = 18; + } else { + fatal(MYNAME ": wpt_type must be " + "symbol, text, mapnote, circle, or image\n"); + } + } } static void -Init_Output_Type( void ) +Init_Output_Type(void) { - if ( !output_type || !output_type[0]) { - output_type_num = last_read_type; - return; - } - if ( (output_type[0] & 0xf0 ) == 0x30) { - output_type_num = atoi( output_type ); - } - else { - output_type_num = 0; - if ( !case_ignore_strcmp(output_type, "drawing")) { - output_type_num = 0; - } - else if ( !case_ignore_strcmp(output_type, "road")) { - output_type_num = 1; - } - else if ( !case_ignore_strcmp(output_type, "trail")) { - output_type_num = 2; - } - else if ( !case_ignore_strcmp(output_type, "waypoint")) { - output_type_num = 3; - } - else if ( !case_ignore_strcmp(output_type, "track")) { - output_type_num = 4; - } - else { - fatal(MYNAME ": type must be " - "drawing, road, trail, waypoint, or track\n"); - } - } - last_read_type = output_type_num; + if (!output_type || !output_type[0]) { + output_type_num = last_read_type; + return; + } + if ((output_type[0] & 0xf0) == 0x30) { + output_type_num = atoi(output_type); + } else { + output_type_num = 0; + if (!case_ignore_strcmp(output_type, "drawing")) { + output_type_num = 0; + } else if (!case_ignore_strcmp(output_type, "road")) { + output_type_num = 1; + } else if (!case_ignore_strcmp(output_type, "trail")) { + output_type_num = 2; + } else if (!case_ignore_strcmp(output_type, "waypoint")) { + output_type_num = 3; + } else if (!case_ignore_strcmp(output_type, "track")) { + output_type_num = 4; + } else { + fatal(MYNAME ": type must be " + "drawing, road, trail, waypoint, or track\n"); + } + } + last_read_type = output_type_num; } -static long -Parse_Change_Type( char *type ) { - long retval = 0x11100541; - - if ( !case_ignore_strcmp( type, "limited" )) { - retval = 0x11070430; - } - else if ( !case_ignore_strcmp( type, "toll" )) { - retval = 0x11070470; - } - else if ( !case_ignore_strcmp( type, "us" )) { - retval = 0x11070870; - } - else if ( !case_ignore_strcmp( type, "state" )) { - retval = 0x11070c10; - } - else if ( !case_ignore_strcmp( type, "primary" )) { - /* primary state/provincial routes */ - retval = 0x11070840; - } - else if ( !case_ignore_strcmp( type, "major" )) { - retval = 0x11070c30; - } - else if ( !case_ignore_strcmp( type, "local" )) { - retval = 0x11071010; - } - else if ( !case_ignore_strcmp( type, "ramp" )) { - retval = 0x11070cb0; - } - else if ( !case_ignore_strcmp( type, "ferry" )) { - retval = 0x11070ca0; - } - else if ( !case_ignore_strcmp( type, "editable" )) { - retval = 0x11100541; - } - else { - fatal( MYNAME ": unknown road type for road changes\n" ); - } - return retval; +static long +Parse_Change_Type(char* type) +{ + long retval = 0x11100541; + + if (!case_ignore_strcmp(type, "limited")) { + retval = 0x11070430; + } else if (!case_ignore_strcmp(type, "toll")) { + retval = 0x11070470; + } else if (!case_ignore_strcmp(type, "us")) { + retval = 0x11070870; + } else if (!case_ignore_strcmp(type, "state")) { + retval = 0x11070c10; + } else if (!case_ignore_strcmp(type, "primary")) { + /* primary state/provincial routes */ + retval = 0x11070840; + } else if (!case_ignore_strcmp(type, "major")) { + retval = 0x11070c30; + } else if (!case_ignore_strcmp(type, "local")) { + retval = 0x11071010; + } else if (!case_ignore_strcmp(type, "ramp")) { + retval = 0x11070cb0; + } else if (!case_ignore_strcmp(type, "ferry")) { + retval = 0x11070ca0; + } else if (!case_ignore_strcmp(type, "editable")) { + retval = 0x11100541; + } else { + fatal(MYNAME ": unknown road type for road changes\n"); + } + return retval; } -static void -Free_Road_Changes( void ) +static void +Free_Road_Changes(void) { - int i = 0; - if ( roadchanges ) { - while ( roadchanges[i].name ) { - xfree(roadchanges[i].name ); - i++; - } - xfree( roadchanges ); - } - roadchanges = NULL; -} + int i = 0; + if (roadchanges) { + while (roadchanges[i].name) { + xfree(roadchanges[i].name); + i++; + } + xfree(roadchanges); + } + roadchanges = NULL; +} static void -Init_Road_Changes( void ) +Init_Road_Changes(void) { - int count = 0; - char *strType = NULL; - char *name = NULL; - char *bar = NULL; - char *copy = NULL; - Free_Road_Changes(); - - if ( !road_changes || !road_changes[0] ) { - return; - } - bar = strchr( road_changes, '!' ); - while ( bar ) { - count++; - bar = strchr( bar+1, '!' ); - } - if ( !(count&1)) { - fatal( MYNAME ": invalid format for road changes\n" ); - } - count = 1 + count / 2; - roadchanges = (roadchange *)xmalloc( (count+1) * sizeof(roadchange)); - - roadchanges[count].type = 0; - roadchanges[count].name = NULL; - - copy = xstrdup( road_changes ); - bar = copy; - - while ( count ) { - count--; - name = bar; - bar = strchr( name, '!' ); - *bar = '\0'; - bar++; - strType = bar; - bar = strchr( strType, '!' ); - if ( bar ) { - *bar = '\0'; - bar++; - } - roadchanges[count].name = xstrdup( name ); - roadchanges[count].type = Parse_Change_Type( strType ); - } - - xfree( copy ); + int count = 0; + char* strType = NULL; + char* name = NULL; + char* bar = NULL; + char* copy = NULL; + Free_Road_Changes(); + + if (!road_changes || !road_changes[0]) { + return; + } + bar = strchr(road_changes, '!'); + while (bar) { + count++; + bar = strchr(bar+1, '!'); + } + if (!(count&1)) { + fatal(MYNAME ": invalid format for road changes\n"); + } + count = 1 + count / 2; + roadchanges = (roadchange*)xmalloc((count+1) * sizeof(roadchange)); + + roadchanges[count].type = 0; + roadchanges[count].name = NULL; + + copy = xstrdup(road_changes); + bar = copy; + + while (count) { + count--; + name = bar; + bar = strchr(name, '!'); + *bar = '\0'; + bar++; + strType = bar; + bar = strchr(strType, '!'); + if (bar) { + *bar = '\0'; + bar++; + } + roadchanges[count].name = xstrdup(name); + roadchanges[count].type = Parse_Change_Type(strType); + } + + xfree(copy); } static void -rd_init(const char *fname) +rd_init(const char* fname) { - infile = gbfopen_le(fname, "rb", MYNAME); + infile = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(infile); + gbfclose(infile); } static void my_read(void) { - Read_AN1_Header( infile ); - Read_AN1_Bitmaps( infile ); - Read_AN1_Waypoints( infile ); - Read_AN1_Lines( infile ); + Read_AN1_Header(infile); + Read_AN1_Bitmaps(infile); + Read_AN1_Waypoints(infile); + Read_AN1_Lines(infile); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - outfile = gbfopen_le( fname, "wb", MYNAME ); - Init_Output_Type(); - Init_Road_Changes(); - opt_color_num = color_to_bbggrr(opt_color); - Init_Wpt_Type(); - if ( opt_zoom ) { - opt_zoom_num = atoi(opt_zoom); - } - radius = .1609344; /* 1/10 mi */ - if ( opt_radius ) { - radius = atof(opt_radius); - if ( !strchr(opt_radius,'k') && !strchr(opt_radius,'K')) { - radius *= 5280*12*2.54/100000; - } - } + outfile = gbfopen_le(fname, "wb", MYNAME); + Init_Output_Type(); + Init_Road_Changes(); + opt_color_num = color_to_bbggrr(opt_color); + Init_Wpt_Type(); + if (opt_zoom) { + opt_zoom_num = atoi(opt_zoom); + } + radius = .1609344; /* 1/10 mi */ + if (opt_radius) { + radius = atof(opt_radius); + if (!strchr(opt_radius,'k') && !strchr(opt_radius,'K')) { + radius *= 5280*12*2.54/100000; + } + } } static void -wr_deinit( void ) +wr_deinit(void) { - Free_Road_Changes(); - gbfclose(outfile); + Free_Road_Changes(); + gbfclose(outfile); } static void -my_write( void ) +my_write(void) { - Write_AN1_Header( outfile ); - Write_AN1_Bitmaps( outfile ); - Write_AN1_Waypoints( outfile ); - Write_AN1_Lines( outfile ); + Write_AN1_Header(outfile); + Write_AN1_Bitmaps(outfile); + Write_AN1_Waypoints(outfile); + Write_AN1_Lines(outfile); } ff_vecs_t an1_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_write /* tracks */, - ff_cap_read | ff_cap_write /* routes */, - }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - my_read, - my_write, - NULL, - an1_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + ff_cap_write /* tracks */, + (ff_cap)(ff_cap_read | ff_cap_write) /* routes */, + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + my_read, + my_write, + NULL, + an1_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/an1sym.h b/gpsbabel/an1sym.h index bf25c9303..c2ef4582c 100644 --- a/gpsbabel/an1sym.h +++ b/gpsbabel/an1sym.h @@ -1,4 +1,4 @@ -/* +/* @@ -41,7 +41,7 @@ /* Read DeLorme drawing files (.an1) - supplemental (included by an1.c) - + Copyright (C) 2005 Ron Parker and Robert Lipe. This program is free software; you can redistribute it and/or modify @@ -61,459 +61,673 @@ */ struct defguid { - GUID guid; - char *name; + GUID guid; + const char* name; } default_guids[] = { - {{0xb610bc70,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Hiker"}, - {{0xb610bc71,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Canoe"}, - {{0xb610bc72,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Kayak"}, - {{0xb610bc73,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Bike"}, - {{0xb610bc74,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Four wheeler"}, - {{0xb610bc75,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Jeep"}, - {{0xb610bc76,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Snowmobile"}, - {{0xb610bc78,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Rec Vehicle"}, - {{0xb610bc79,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Fire"}, - {{0xb610bc7a,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Fishing"}, - {{0xb610bc7b,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Tree"}, - {{0xb610bc7c,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Pine Tree"}, - {{0xb610bc7d,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Birch"}, - {{0xb610bc7e,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Deer"}, - {{0xb610bc7f,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Moose"}, - {{0x99d8c163,{0x7622, 0x11d5, 0xe8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Mud"}, - {{0x012dfac2,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Tractor"}, - {{0x012dfac3,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Combine Harvester"}, - {{0x012dfac7,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Front-End Loader"}, - {{0xfd163780,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Power Shovel"}, - {{0xfd163781,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Road Grader"}, - {{0xfd163784,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Road Roller"}, - {{0xfd163787,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dump Truck"}, - {{0x5673d712,{0xb28d, 0x11d5, 0x13b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Skid-Steer Loader"}, - {{0xb86045ac,{0x390f, 0x420f, 0x91a7}, {0x76, 0x2f, 0x48, 0xea, 0xe2, 0xd7}}, - "Highway Sign"}, - {{0x1e129e95,{0x13b6, 0x48d8, 0x3fa3}, {0x9c, 0xc8, 0x20, 0x8e, 0x1d, 0x9d}}, - "Orange Cone"}, - {{0xadee7d54,{0xf7c9, 0x4ab6, 0xfb93}, {0x99, 0xc3, 0xbc, 0x9d, 0x15, 0x47}}, - "Barricade"}, - {{0xa170000f,{0x8bd8, 0x4574, 0x58ac}, {0x55, 0x41, 0x67, 0xef, 0x64, 0x62}}, - "Flagger"}, - {{0xa425f90e,{0x6ab6, 0x4ca9, 0x8997}, {0xbf, 0xca, 0xe0, 0xc2, 0x2b, 0x53}}, - "Construction Sign"}, - {{0x0805b240,{0x6b26, 0x4300, 0xebb1}, {0xea, 0x9b, 0xcf, 0x68, 0xc6, 0x18}}, - "Construction Flasher"}, - {{0x56721a6c,{0x8e77, 0x4b62, 0x09aa}, {0xce, 0xdc, 0x69, 0x4a, 0x16, 0x05}}, - "Transit"}, - {{0x623e1ee9,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Left"}, - {{0x623e1eea,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Right"}, - {{0x623e1eeb,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Up"}, - {{0x623e1eec,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Down"}, - {{0x623e1eed,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Up Left"}, - {{0x623e1eee,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Up Right"}, - {{0x623e1eef,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Down Left"}, - {{0x623e1ef0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Down Right"}, - {{0x83f91421,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Left"}, - {{0x83f91422,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Right"}, - {{0x83f91423,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Up"}, - {{0x83f91424,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Down"}, - {{0x83f91425,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Up Left"}, - {{0x83f91426,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Up Right"}, - {{0x83f91427,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Down Left"}, - {{0x83f91428,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Down Right"}, - {{0x83f91429,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Left"}, - {{0x83f9142a,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Right"}, - {{0x83f9142b,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Up"}, - {{0x83f9142c,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Down"}, - {{0x83f9142d,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Down Right"}, - {{0x83f9142e,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Down Left"}, - {{0x83f9142f,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Up Left"}, - {{0x83f91430,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Up Right"}, - {{0x8ff0aad1,{0xc53d, 0x4998, 0x7ebd}, {0x06, 0x60, 0x25, 0x6c, 0x4f, 0x6d}}, - "Accommodation"}, - {{0xaf7bf199,{0x6a8b, 0x49fe, 0xae92}, {0xa3, 0x09, 0x7b, 0xb8, 0x81, 0x6a}}, - "Australia"}, - {{0x6bbcc9d1,{0x6a19, 0x4c7b, 0xc6a2}, {0x3e, 0x17, 0x02, 0xd6, 0xee, 0x3a}}, - "Blue Dome Cross"}, - {{0xfff920fe,{0xd780, 0x49d4, 0x1bad}, {0x55, 0x2e, 0xc7, 0xdf, 0xa2, 0xaa}}, - "Green Dome Cross"}, - {{0x57e75924,{0xd6fa, 0x4666, 0x84bf}, {0x5b, 0x76, 0xa1, 0xd0, 0x14, 0x5f}}, - "Business"}, - {{0xb09ef4a7,{0x95e4, 0x4e5e, 0x5e84}, {0xbe, 0x2b, 0x86, 0xdd, 0x50, 0x65}}, - "Airplane"}, - {{0xf2833c22,{0x3592, 0x4a8a, 0x5693}, {0xee, 0x6c, 0x83, 0xb6, 0x3c, 0x19}}, - "Amusement Recreation"}, - {{0x6f0317d6,{0x7fa3, 0x4dcc, 0x6187}, {0x7e, 0xca, 0xcb, 0x65, 0x49, 0x12}}, - "Green Square"}, - {{0x18a6d3c0,{0x45cb, 0x4d19, 0xf5b9}, {0xc7, 0x9c, 0xbf, 0x8f, 0x6d, 0x46}}, - "Red Triangle"}, - {{0x86e68ea7,{0xb9ab, 0x4bc8, 0xa1bf}, {0xc1, 0x22, 0x13, 0x97, 0x95, 0xe8}}, - "Red Triangle and Green Square"}, - {{0x6afd74bf,{0x0ea5, 0x4680, 0xcd88}, {0x15, 0x87, 0x2f, 0x6c, 0xd2, 0xd8}}, - "City 4"}, - {{0x49dfeb74,{0xbb09, 0x4df1, 0x5687}, {0xd8, 0xa0, 0xff, 0x36, 0x89, 0x3d}}, - "White Square"}, - {{0x3eed62c6,{0xdab9, 0x42b0, 0xe4a3}, {0xd2, 0xf1, 0x7d, 0x54, 0xbf, 0x77}}, - "White Triangle"}, - {{0x6b521940,{0x4492, 0x4c48, 0x58a0}, {0xfc, 0xd1, 0x1f, 0x5e, 0x0c, 0xea}}, - "Red Black Diamond Flag"}, - {{0xbb8ebaa3,{0xac59, 0x4411, 0x9c94}, {0x30, 0xd4, 0xe1, 0x21, 0x25, 0x46}}, - "Yellow Diamond Flag"}, - {{0x8e118862,{0xf6aa, 0x4b34, 0x2b82}, {0x8f, 0x3b, 0x5a, 0x2b, 0x59, 0xeb}}, - "Small Pink Square"}, - {{0xd0ef64c2,{0xe319, 0x4876, 0x1b85}, {0x0e, 0x90, 0x50, 0x89, 0xb7, 0xc5}}, - "Store"}, - {{0xa22b08fb,{0x6193, 0x4f5c, 0xdaa4}, {0xfa, 0xdf, 0xa7, 0x6e, 0x23, 0xe1}}, - "Camping"}, - {{0x27f57c69,{0x575b, 0x4b56, 0x288c}, {0xe8, 0xe1, 0xc7, 0x05, 0x1f, 0x1f}}, - "Green Diamond Flag"}, - {{0xe07abb38,{0x219f, 0x4b52, 0x868b}, {0x45, 0x0f, 0xbc, 0xc1, 0x4f, 0x6a}}, - "Red Diamond Flag"}, - {{0x3a124ac9,{0x3973, 0x4e27, 0x4b82}, {0xa6, 0x3a, 0x94, 0x5c, 0xf8, 0xb3}}, - "Red Green Diamond Flag"}, - {{0x64ed669b,{0x0db8, 0x4ec9, 0xd181}, {0x98, 0x50, 0xb3, 0x8b, 0x2f, 0x2e}}, - "White Globe"}, - {{0x3cb10adc,{0xb090, 0x4960, 0x9f8a}, {0xec, 0xaf, 0x6c, 0xd7, 0xaa, 0x8b}}, - "Yellow Globe"}, - {{0x2779347d,{0x17d4, 0x4021, 0xa6a8}, {0x51, 0x9a, 0xb6, 0xf8, 0x21, 0xff}}, - ""}, - {{0x3ad63f7b,{0x4339, 0x427d, 0x5797}, {0xce, 0xa9, 0x96, 0x33, 0x8b, 0x3c}}, - "Black Cross"}, - {{0x3e89481e,{0x35ff, 0x48b6, 0xc7ae}, {0xb0, 0x75, 0xf6, 0x43, 0xc4, 0xc7}}, - "Church"}, - {{0x68622c10,{0x79b6, 0x466d, 0xa8a3}, {0x27, 0xc6, 0x25, 0x34, 0xfa, 0xa9}}, - "Small Dark Green Square"}, - {{0x42c6a873,{0x2d0c, 0x46e7, 0x9989}, {0xdd, 0x86, 0x01, 0x6e, 0xa4, 0xc9}}, - "Small Black Square"}, - {{0x50e3b06e,{0xbe81, 0x4b2c, 0x1f92}, {0x80, 0xa5, 0x72, 0x9b, 0x33, 0x05}}, - "Danger"}, - {{0x369d0b22,{0xed07, 0x421f, 0x8780}, {0x33, 0x0e, 0xbd, 0x27, 0x4f, 0x3c}}, - "Construction Business"}, - {{0x10603b6c,{0xb02e, 0x49ee, 0x60b9}, {0xed, 0x7e, 0x31, 0x16, 0x27, 0x89}}, - "Airport"}, - {{0x8328aab7,{0xfe04, 0x46dc, 0x7bbf}, {0x29, 0x34, 0x30, 0xd3, 0x4d, 0xeb}}, - "City 5"}, - {{0x96411287,{0xda33, 0x40e3, 0xaa9c}, {0x75, 0x83, 0x78, 0x2d, 0xa6, 0xf3}}, - "USA"}, - {{0xb2f98627,{0x1211, 0x40e8, 0xb287}, {0x6d, 0x66, 0xfd, 0x15, 0x1e, 0xd4}}, - "Diver Down"}, - {{0x3fce26d0,{0xfec6, 0x4f8b, 0x55a2}, {0x89, 0x3a, 0x8e, 0x59, 0x08, 0x0a}}, - "Light Yellow Square"}, - {{0xb4b68597,{0x1aed, 0x4918, 0xd492}, {0x1f, 0xd1, 0x5e, 0xf2, 0x55, 0xc1}}, - "Education Technology"}, - {{0x35d2e6a8,{0xda88, 0x4edb, 0x4b80}, {0x2b, 0x1b, 0xcf, 0xc0, 0xd4, 0x6d}}, - "Computer"}, - {{0x4ddc4e96,{0x8d19, 0x4079, 0x4488}, {0xc0, 0x8f, 0x0f, 0x8e, 0xb5, 0xd7}}, - "Amusement Recreation Red"}, - {{0x79f58929,{0x46c6, 0x4337, 0xc0b1}, {0xf0, 0x09, 0x55, 0xbb, 0x1f, 0xc3}}, - "Telephone Red"}, - {{0x0083b377,{0xfb80, 0x4a83, 0x3593}, {0x56, 0xe5, 0xfe, 0xc4, 0xcd, 0x43}}, - "Exit"}, - {{0x0c232891,{0xab4d, 0x440e, 0x7083}, {0x05, 0x63, 0x3a, 0xf5, 0x66, 0x11}}, - "Exit with Services"}, - {{0xaf63e7c2,{0x03fa, 0x418e, 0xc68b}, {0x02, 0xb8, 0xf5, 0x61, 0xb6, 0x61}}, - "Pizza"}, - {{0xd419c693,{0x39e6, 0x43db, 0xa1b8}, {0x7f, 0xcc, 0x2c, 0xb8, 0x51, 0x4a}}, - "Financial Services"}, - {{0x70740a81,{0xe4ca, 0x4ac2, 0xa498}, {0x21, 0xc8, 0x5b, 0xc0, 0xb7, 0xae}}, - "City 3"}, - {{0x9a582ff6,{0x34c4, 0x41c6, 0xf0a3}, {0x99, 0x69, 0x9d, 0xbe, 0x2e, 0x08}}, - "Food Store"}, - {{0x3cd31689,{0x2f8f, 0x4fb0, 0xcb88}, {0x34, 0x84, 0xfc, 0x8b, 0x03, 0xe4}}, - ""}, - {{0x952557a6,{0xe29e, 0x4512, 0x1184}, {0x1a, 0x3c, 0x9c, 0xd4, 0x83, 0x7d}}, - ""}, - {{0x03dc278c,{0xe8ff, 0x46ac, 0x3daa}, {0x9f, 0xe9, 0x1e, 0xcf, 0x10, 0x35}}, - "Driving Range"}, - {{0xacd28bab,{0x0ec0, 0x4393, 0xaf8b}, {0xbb, 0x5e, 0x74, 0xb3, 0x87, 0x12}}, - "Golf Municipal"}, - {{0x984e7139,{0xeab8, 0x49f6, 0x55a0}, {0x8d, 0x51, 0xe6, 0xdd, 0xcc, 0xf4}}, - "Golf Private"}, - {{0xec5828ab,{0x2a9d, 0x48f8, 0xd79b}, {0xc9, 0xc3, 0x30, 0x8e, 0xe4, 0xea}}, - "Golf Public"}, - {{0xb0120d99,{0x683a, 0x4ecc, 0x129a}, {0x29, 0x94, 0x1f, 0x04, 0xae, 0x10}}, - "Golf Resort"}, - {{0x2ce7685a,{0x6eaf, 0x4061, 0x29a5}, {0x87, 0x5e, 0xfa, 0x41, 0x75, 0x1a}}, - "Golf Semi Private"}, - {{0x10397049,{0x9fc9, 0x4380, 0x5680}, {0x81, 0xd9, 0xe7, 0x43, 0x1f, 0x11}}, - "Medical Service"}, - {{0x2fc28df6,{0xe806, 0x436e, 0xe0b9}, {0x46, 0x1d, 0xeb, 0xad, 0x56, 0x60}}, - "Home Furnishings"}, - {{0x910313db,{0xafce, 0x4019, 0x1aa4}, {0xe6, 0x2c, 0xe6, 0xd1, 0xfd, 0xf7}}, - "Industrial"}, - {{0x9e442c6e,{0xe12a, 0x4407, 0xd68a}, {0x1c, 0x5e, 0x19, 0xe7, 0xfe, 0x01}}, - ""}, - {{0x37e2fe4a,{0xcd71, 0x413f, 0x0cad}, {0x81, 0xc5, 0x2c, 0xf4, 0x78, 0x79}}, - ""}, - {{0x3c756e09,{0xb2dc, 0x48a6, 0x04a9}, {0x20, 0xb7, 0xc9, 0x9d, 0x14, 0x51}}, - ""}, - {{0xa1245b1c,{0x156a, 0x48fc, 0x6f96}, {0xa5, 0xa3, 0x22, 0x54, 0x13, 0x97}}, - "Manufacturing"}, - {{0x5bddbd7a,{0xf3cb, 0x454c, 0x06af}, {0x46, 0x1a, 0x68, 0xea, 0x60, 0x1a}}, - "Note"}, - {{0xcb6777e1,{0xe0e0, 0x45ce, 0x309f}, {0x8d, 0x61, 0x7a, 0xd9, 0x89, 0xf5}}, - "City"}, - {{0xbc168c08,{0x2b7f, 0x44be, 0x3883}, {0x81, 0x31, 0x4a, 0x09, 0xf5, 0x78}}, - "Air Base"}, - {{0xa8857b0f,{0xfc3b, 0x4cd1, 0x9e91}, {0xf5, 0x3b, 0x21, 0xa8, 0x3b, 0xb9}}, - "Battlefield"}, - {{0x06db55c1,{0xf687, 0x4840, 0x7c80}, {0x95, 0x58, 0x77, 0x8e, 0x5a, 0xdd}}, - "Mining"}, - {{0xcc61b277,{0xa48c, 0x445a, 0xd9b9}, {0xe5, 0x91, 0x36, 0x18, 0x4e, 0x09}}, - "Mountain"}, - {{0xfde13186,{0xb6cb, 0x4374, 0xc880}, {0x56, 0x99, 0xeb, 0x51, 0x68, 0x87}}, - "Capital"}, - {{0xb14d90d1,{0xd943, 0x40ff, 0x9fb7}, {0x9b, 0x92, 0xd1, 0x23, 0xca, 0xef}}, - "Route"}, - {{0x7eabc63f,{0x05d0, 0x4465, 0xb1b0}, {0x61, 0x2a, 0xf7, 0x4d, 0x0f, 0x4e}}, - "Overnight"}, - {{0xac39d8b9,{0xfcdc, 0x4b50, 0x9ca6}, {0xea, 0x6c, 0x4b, 0xb5, 0x96, 0x0f}}, - "Route End Active"}, - {{0xe1b9d86b,{0x95e6, 0x4bd8, 0xd880}, {0x7b, 0x6c, 0xc6, 0xd2, 0x00, 0x34}}, - "Route End Inactive"}, - {{0x98712315,{0x7e1e, 0x4024, 0x8392}, {0xe3, 0xb8, 0x5a, 0x51, 0x45, 0xb4}}, - "Fuel Stop"}, - {{0xe5ea5b38,{0x7b80, 0x4b42, 0x0aba}, {0x3d, 0x38, 0xf0, 0xe1, 0x17, 0x9a}}, - "Route Start Active"}, - {{0x18fd0d49,{0x0a29, 0x433a, 0xd584}, {0xe5, 0xb7, 0x5b, 0xe8, 0x25, 0xbc}}, - "Route Start Inactive"}, - {{0x2f52144b,{0x903e, 0x4dd9, 0x79af}, {0xe1, 0x66, 0x9b, 0xfc, 0xa9, 0xc1}}, - "Route Stop Active"}, - {{0xfaf8d826,{0xd27d, 0x4316, 0x0e92}, {0xce, 0x8d, 0x85, 0x93, 0x4c, 0xf5}}, - "Route Stop Inactive"}, - {{0xff44cae2,{0x707c, 0x4a1c, 0x43af}, {0x8b, 0xb6, 0xb1, 0x19, 0x9c, 0xf2}}, - "Route Via"}, - {{0x5a50d59b,{0xc15b, 0x49c4, 0x9faa}, {0xc4, 0x1c, 0x4f, 0xe2, 0x95, 0x2a}}, - "Radiation Green"}, - {{0x19556023,{0xb1e5, 0x4c9c, 0x49ba}, {0x08, 0x52, 0xa1, 0x24, 0x3d, 0x9f}}, - "Radiation Red"}, - {{0xa54be251,{0x6688, 0x49fb, 0x60b3}, {0x89, 0x56, 0x37, 0x68, 0xc5, 0xb0}}, - "Electricity"}, - {{0xd793ff0c,{0xfbe0, 0x4383, 0x3183}, {0xcf, 0x4f, 0x04, 0xb7, 0xee, 0x0a}}, - "Personal Furnishings"}, - {{0x00f90733,{0x7ab5, 0x42cf, 0x468c}, {0xbf, 0x91, 0x27, 0xd3, 0xa8, 0x9c}}, - "Personal Services"}, - {{0xea677f24,{0xbbe8, 0x4238, 0xee9c}, {0x6c, 0x0a, 0xec, 0x0e, 0x34, 0xf4}}, - "Telephone Black"}, - {{0x2d8a05b5,{0x8baf, 0x4f28, 0xf58b}, {0xfb, 0x7f, 0x37, 0x34, 0x28, 0xa7}}, - "Government Light"}, - {{0x40c64dfc,{0xc2d0, 0x4b0e, 0x6582}, {0x3f, 0x26, 0x9c, 0xcb, 0x6f, 0x1d}}, - "Airport Red Square"}, - {{0xf27adb5d,{0x3629, 0x44c7, 0x95a2}, {0x25, 0x2c, 0x95, 0x24, 0x98, 0x2f}}, - "Propeller Aircraft"}, - {{0x5a718e13,{0x3547, 0x42c5, 0x6d9d}, {0xb2, 0x82, 0xa5, 0x53, 0xbd, 0x3a}}, - "Jet Aircraft"}, - {{0x0a471039,{0x2dfe, 0x447e, 0x54be}, {0xa3, 0x93, 0xae, 0x9a, 0xdd, 0xac}}, - "Government"}, - {{0x4a59da2f,{0xe1c3, 0x42c3, 0x6ca1}, {0x06, 0xb9, 0x14, 0x1b, 0x89, 0x99}}, - "USA Regional"}, - {{0xf16500a9,{0xa845, 0x4293, 0xae89}, {0x5c, 0x29, 0xbb, 0x0d, 0x06, 0xf7}}, - "House 2"}, - {{0x7b05524d,{0xcb5a, 0x456f, 0x96b3}, {0x03, 0x61, 0x24, 0x54, 0x6a, 0x54}}, - "Picnic"}, - {{0xb88ad7a1,{0xb94d, 0x42e8, 0x2b9d}, {0xf5, 0x4c, 0x2b, 0xff, 0x57, 0xdc}}, - "Restaurant"}, - {{0xdc48a20a,{0x54a2, 0x4c61, 0x1fbe}, {0x02, 0x74, 0x5b, 0xe9, 0x18, 0x99}}, - "Store 2"}, - {{0x6b5ab040,{0x96df, 0x46ae, 0xacb8}, {0xe4, 0x47, 0x66, 0x3f, 0xec, 0x9b}}, - ""}, - {{0x153b2cff,{0x6232, 0x4294, 0xd59a}, {0xc5, 0xa0, 0x7b, 0xe0, 0x16, 0xeb}}, - "Blue Star"}, - {{0xf276f6b3,{0x586a, 0x4bf8, 0x2f82}, {0xf2, 0x69, 0xe3, 0x76, 0x7e, 0xd5}}, - ""}, - {{0x91d242c8,{0x0986, 0x4fad, 0x8286}, {0xec, 0x79, 0x79, 0xcd, 0xab, 0x02}}, - "Running"}, - {{0x8b0078db,{0x6ee0, 0x4caa, 0xd3b5}, {0xfe, 0xe1, 0xc2, 0xbf, 0x94, 0x7d}}, - "Transportation"}, - {{0x0599f6c9,{0x478e, 0x4f63, 0x78a5}, {0xed, 0x31, 0xb5, 0xae, 0xda, 0x89}}, - "Fishing 2"}, - {{0x7389128c,{0x0e78, 0x4d5d, 0x4189}, {0xb8, 0xf3, 0xb5, 0xbd, 0x70, 0xb1}}, - "Automotive"}, - {{0x0362b593,{0x3df6, 0x48ed, 0xc489}, {0x85, 0x13, 0xc1, 0xc0, 0xb9, 0x0d}}, - "Cloudy"}, - {{0xf0717a94,{0xd048, 0x4770, 0x9bab}, {0x80, 0x09, 0xbd, 0x4b, 0x1e, 0x75}}, - "Partly Cloudy"}, - {{0x14486bbc,{0xae6b, 0x44ea, 0xd6b9}, {0xbf, 0x9a, 0x39, 0x7a, 0x51, 0x6c}}, - "Mostly Cloudy"}, - {{0x7a258c70,{0xabec, 0x4cff, 0x4983}, {0x84, 0xdc, 0x2f, 0x2e, 0xff, 0x28}}, - "Hurricane"}, - {{0xeff260d4,{0x46d5, 0x4fb5, 0xc79c}, {0x5e, 0x06, 0xc8, 0xab, 0x7a, 0x2b}}, - "Lightning"}, - {{0xc3d70220,{0x5154, 0x4766, 0xf0af}, {0xdf, 0x86, 0x74, 0x40, 0x5f, 0x8c}}, - "Rain"}, - {{0xf2dfbc91,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue Flag"}, - {{0xf2dfbc92,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Blue Flag"}, - {{0xf2dfbc93,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Brown Flag"}, - {{0xf2dfbc94,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Yellow Flag"}, - {{0xf2dfbc95,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Red Flag 2"}, - {{0xf2dfbc96,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Red Flag"}, - {{0xf2dfbc97,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Green Flag"}, - {{0xf2dfbc98,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Green Flag"}, - {{0xf2dfbc99,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue-Green Flag"}, - {{0xf2dfbc9a,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Light Blue Flag"}, - {{0x623e1ee1,{0xaf27, 0x100f, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Dark Blue Map Pin"}, - {{0xf2dfbc9d,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue Map Pin"}, - {{0xf2dfbc9e,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Yellow Map Pin"}, - {{0xf2dfbc9f,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Brown Map Pin"}, - {{0xf2dfbca0,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Red Map Pin"}, - {{0xf2dfbca1,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Red Map Pin"}, - {{0xf2dfbca2,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Green Map Pin"}, - {{0xf2dfbca3,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Green Map Pin"}, - {{0xf2dfbca4,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Gray Map Pin"}, - {{0xf2dfbca5,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Gray Map Pin"}, - {{0xd1703de0,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Green Dot"}, - {{0xd1703de1,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Green Dot"}, - {{0xd1703de2,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue Dot"}, - {{0xd1703de3,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Blue Dot"}, - {{0xd1703de5,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Red Dot"}, - {{0x45c088e0,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Red Dot"}, - {{0x45c088e1,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Yellow Dot"}, - {{0x45c088e2,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Brown Dot"}, - {{0x45c088e3,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Light Blue Dot"}, - {{0xbde3a8a1,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue-Green Dot"}, - {{0xbde3a8a2,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Green Dot"}, - {{0xbde3a8a3,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Dark Green Dot"}, - {{0xbde3a8a4,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Blue Dot"}, - {{0xbde3a8a5,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Dark Blue Dot"}, - {{0xbde3a8a6,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Red Dot"}, - {{0xbde3a8a7,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Dark Red Dot"}, - {{0xbde3a8a8,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Yellow Dot"}, - {{0xbde3a8a9,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Brown Dot"}, - {{0xbde3a8aa,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Light Blue Dot"}, - {{0xbde3a8ab,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Blue-Green Dot"}, - {{0x623e1ee0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Red Flag"}, - {{0x623e1ee1,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Map Pin"}, - {{0x623e1ee2,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Yellow Square"}, - {{0x623e1ee3,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Red X"}, - {{0x623e1ee4,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Blue Circle"}, - {{0x623e1ee5,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "House"}, - {{0x623e1ee7,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Triangle"}, - {{0x623e1ee8,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Green Star"}, - {{0x9d277805,{0xe2f8, 0x4f43, 0x3f97}, {0x35, 0x0d, 0x40, 0xae, 0x5c, 0xd3}}, - "Geocache"}, - {{0xcb8aad04,{0xcc2d, 0x47f2, 0x428a}, {0x80, 0xf7, 0xd6, 0x68, 0xed, 0x32}}, - "Geocache Found"}, - {{0x7341c1f4,{0xdecd, 0x4d35, 0x45a5}, {0x52, 0x25, 0x5e, 0xbf, 0xe6, 0x51}}, - "Tent"}, - {{0x835b84e2,{0xf10c, 0x45cb, 0x958f}, {0x18, 0x3a, 0xc2, 0x2a, 0xe5, 0x28}}, - "Tipup Up"}, - {{0xce06fc92,{0xbb0c, 0x4ec1, 0xda93}, {0x64, 0x4a, 0x60, 0xbe, 0x40, 0x90}}, - "Topup Down"}, + { {0xb610bc70,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Hiker" + }, + { {0xb610bc71,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Canoe" + }, + { {0xb610bc72,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Kayak" + }, + { {0xb610bc73,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Bike" + }, + { {0xb610bc74,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Four wheeler" + }, + { {0xb610bc75,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Jeep" + }, + { {0xb610bc76,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Snowmobile" + }, + { {0xb610bc78,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Rec Vehicle" + }, + { {0xb610bc79,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Fire" + }, + { {0xb610bc7a,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Fishing" + }, + { {0xb610bc7b,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Tree" + }, + { {0xb610bc7c,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Pine Tree" + }, + { {0xb610bc7d,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Birch" + }, + { {0xb610bc7e,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Deer" + }, + { {0xb610bc7f,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Moose" + }, + { {0x99d8c163,{0x7622, 0x11d5, 0xe8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Mud" + }, + { {0x012dfac2,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Tractor" + }, + { {0x012dfac3,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Combine Harvester" + }, + { {0x012dfac7,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Front-End Loader" + }, + { {0xfd163780,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Power Shovel" + }, + { {0xfd163781,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Road Grader" + }, + { {0xfd163784,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Road Roller" + }, + { {0xfd163787,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dump Truck" + }, + { {0x5673d712,{0xb28d, 0x11d5, 0x13b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Skid-Steer Loader" + }, + { {0xb86045ac,{0x390f, 0x420f, 0x91a7}, {0x76, 0x2f, 0x48, 0xea, 0xe2, 0xd7}}, + "Highway Sign" + }, + { {0x1e129e95,{0x13b6, 0x48d8, 0x3fa3}, {0x9c, 0xc8, 0x20, 0x8e, 0x1d, 0x9d}}, + "Orange Cone" + }, + { {0xadee7d54,{0xf7c9, 0x4ab6, 0xfb93}, {0x99, 0xc3, 0xbc, 0x9d, 0x15, 0x47}}, + "Barricade" + }, + { {0xa170000f,{0x8bd8, 0x4574, 0x58ac}, {0x55, 0x41, 0x67, 0xef, 0x64, 0x62}}, + "Flagger" + }, + { {0xa425f90e,{0x6ab6, 0x4ca9, 0x8997}, {0xbf, 0xca, 0xe0, 0xc2, 0x2b, 0x53}}, + "Construction Sign" + }, + { {0x0805b240,{0x6b26, 0x4300, 0xebb1}, {0xea, 0x9b, 0xcf, 0x68, 0xc6, 0x18}}, + "Construction Flasher" + }, + { {0x56721a6c,{0x8e77, 0x4b62, 0x09aa}, {0xce, 0xdc, 0x69, 0x4a, 0x16, 0x05}}, + "Transit" + }, + { {0x623e1ee9,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Left" + }, + { {0x623e1eea,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Right" + }, + { {0x623e1eeb,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up" + }, + { {0x623e1eec,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down" + }, + { {0x623e1eed,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up Left" + }, + { {0x623e1eee,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up Right" + }, + { {0x623e1eef,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down Left" + }, + { {0x623e1ef0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down Right" + }, + { {0x83f91421,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Left" + }, + { {0x83f91422,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Right" + }, + { {0x83f91423,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up" + }, + { {0x83f91424,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down" + }, + { {0x83f91425,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up Left" + }, + { {0x83f91426,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up Right" + }, + { {0x83f91427,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down Left" + }, + { {0x83f91428,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down Right" + }, + { {0x83f91429,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Left" + }, + { {0x83f9142a,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Right" + }, + { {0x83f9142b,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up" + }, + { {0x83f9142c,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down" + }, + { {0x83f9142d,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down Right" + }, + { {0x83f9142e,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down Left" + }, + { {0x83f9142f,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up Left" + }, + { {0x83f91430,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up Right" + }, + { {0x8ff0aad1,{0xc53d, 0x4998, 0x7ebd}, {0x06, 0x60, 0x25, 0x6c, 0x4f, 0x6d}}, + "Accommodation" + }, + { {0xaf7bf199,{0x6a8b, 0x49fe, 0xae92}, {0xa3, 0x09, 0x7b, 0xb8, 0x81, 0x6a}}, + "Australia" + }, + { {0x6bbcc9d1,{0x6a19, 0x4c7b, 0xc6a2}, {0x3e, 0x17, 0x02, 0xd6, 0xee, 0x3a}}, + "Blue Dome Cross" + }, + { {0xfff920fe,{0xd780, 0x49d4, 0x1bad}, {0x55, 0x2e, 0xc7, 0xdf, 0xa2, 0xaa}}, + "Green Dome Cross" + }, + { {0x57e75924,{0xd6fa, 0x4666, 0x84bf}, {0x5b, 0x76, 0xa1, 0xd0, 0x14, 0x5f}}, + "Business" + }, + { {0xb09ef4a7,{0x95e4, 0x4e5e, 0x5e84}, {0xbe, 0x2b, 0x86, 0xdd, 0x50, 0x65}}, + "Airplane" + }, + { {0xf2833c22,{0x3592, 0x4a8a, 0x5693}, {0xee, 0x6c, 0x83, 0xb6, 0x3c, 0x19}}, + "Amusement Recreation" + }, + { {0x6f0317d6,{0x7fa3, 0x4dcc, 0x6187}, {0x7e, 0xca, 0xcb, 0x65, 0x49, 0x12}}, + "Green Square" + }, + { {0x18a6d3c0,{0x45cb, 0x4d19, 0xf5b9}, {0xc7, 0x9c, 0xbf, 0x8f, 0x6d, 0x46}}, + "Red Triangle" + }, + { {0x86e68ea7,{0xb9ab, 0x4bc8, 0xa1bf}, {0xc1, 0x22, 0x13, 0x97, 0x95, 0xe8}}, + "Red Triangle and Green Square" + }, + { {0x6afd74bf,{0x0ea5, 0x4680, 0xcd88}, {0x15, 0x87, 0x2f, 0x6c, 0xd2, 0xd8}}, + "City 4" + }, + { {0x49dfeb74,{0xbb09, 0x4df1, 0x5687}, {0xd8, 0xa0, 0xff, 0x36, 0x89, 0x3d}}, + "White Square" + }, + { {0x3eed62c6,{0xdab9, 0x42b0, 0xe4a3}, {0xd2, 0xf1, 0x7d, 0x54, 0xbf, 0x77}}, + "White Triangle" + }, + { {0x6b521940,{0x4492, 0x4c48, 0x58a0}, {0xfc, 0xd1, 0x1f, 0x5e, 0x0c, 0xea}}, + "Red Black Diamond Flag" + }, + { {0xbb8ebaa3,{0xac59, 0x4411, 0x9c94}, {0x30, 0xd4, 0xe1, 0x21, 0x25, 0x46}}, + "Yellow Diamond Flag" + }, + { {0x8e118862,{0xf6aa, 0x4b34, 0x2b82}, {0x8f, 0x3b, 0x5a, 0x2b, 0x59, 0xeb}}, + "Small Pink Square" + }, + { {0xd0ef64c2,{0xe319, 0x4876, 0x1b85}, {0x0e, 0x90, 0x50, 0x89, 0xb7, 0xc5}}, + "Store" + }, + { {0xa22b08fb,{0x6193, 0x4f5c, 0xdaa4}, {0xfa, 0xdf, 0xa7, 0x6e, 0x23, 0xe1}}, + "Camping" + }, + { {0x27f57c69,{0x575b, 0x4b56, 0x288c}, {0xe8, 0xe1, 0xc7, 0x05, 0x1f, 0x1f}}, + "Green Diamond Flag" + }, + { {0xe07abb38,{0x219f, 0x4b52, 0x868b}, {0x45, 0x0f, 0xbc, 0xc1, 0x4f, 0x6a}}, + "Red Diamond Flag" + }, + { {0x3a124ac9,{0x3973, 0x4e27, 0x4b82}, {0xa6, 0x3a, 0x94, 0x5c, 0xf8, 0xb3}}, + "Red Green Diamond Flag" + }, + { {0x64ed669b,{0x0db8, 0x4ec9, 0xd181}, {0x98, 0x50, 0xb3, 0x8b, 0x2f, 0x2e}}, + "White Globe" + }, + { {0x3cb10adc,{0xb090, 0x4960, 0x9f8a}, {0xec, 0xaf, 0x6c, 0xd7, 0xaa, 0x8b}}, + "Yellow Globe" + }, + { {0x2779347d,{0x17d4, 0x4021, 0xa6a8}, {0x51, 0x9a, 0xb6, 0xf8, 0x21, 0xff}}, + "" + }, + { {0x3ad63f7b,{0x4339, 0x427d, 0x5797}, {0xce, 0xa9, 0x96, 0x33, 0x8b, 0x3c}}, + "Black Cross" + }, + { {0x3e89481e,{0x35ff, 0x48b6, 0xc7ae}, {0xb0, 0x75, 0xf6, 0x43, 0xc4, 0xc7}}, + "Church" + }, + { {0x68622c10,{0x79b6, 0x466d, 0xa8a3}, {0x27, 0xc6, 0x25, 0x34, 0xfa, 0xa9}}, + "Small Dark Green Square" + }, + { {0x42c6a873,{0x2d0c, 0x46e7, 0x9989}, {0xdd, 0x86, 0x01, 0x6e, 0xa4, 0xc9}}, + "Small Black Square" + }, + { {0x50e3b06e,{0xbe81, 0x4b2c, 0x1f92}, {0x80, 0xa5, 0x72, 0x9b, 0x33, 0x05}}, + "Danger" + }, + { {0x369d0b22,{0xed07, 0x421f, 0x8780}, {0x33, 0x0e, 0xbd, 0x27, 0x4f, 0x3c}}, + "Construction Business" + }, + { {0x10603b6c,{0xb02e, 0x49ee, 0x60b9}, {0xed, 0x7e, 0x31, 0x16, 0x27, 0x89}}, + "Airport" + }, + { {0x8328aab7,{0xfe04, 0x46dc, 0x7bbf}, {0x29, 0x34, 0x30, 0xd3, 0x4d, 0xeb}}, + "City 5" + }, + { {0x96411287,{0xda33, 0x40e3, 0xaa9c}, {0x75, 0x83, 0x78, 0x2d, 0xa6, 0xf3}}, + "USA" + }, + { {0xb2f98627,{0x1211, 0x40e8, 0xb287}, {0x6d, 0x66, 0xfd, 0x15, 0x1e, 0xd4}}, + "Diver Down" + }, + { {0x3fce26d0,{0xfec6, 0x4f8b, 0x55a2}, {0x89, 0x3a, 0x8e, 0x59, 0x08, 0x0a}}, + "Light Yellow Square" + }, + { {0xb4b68597,{0x1aed, 0x4918, 0xd492}, {0x1f, 0xd1, 0x5e, 0xf2, 0x55, 0xc1}}, + "Education Technology" + }, + { {0x35d2e6a8,{0xda88, 0x4edb, 0x4b80}, {0x2b, 0x1b, 0xcf, 0xc0, 0xd4, 0x6d}}, + "Computer" + }, + { {0x4ddc4e96,{0x8d19, 0x4079, 0x4488}, {0xc0, 0x8f, 0x0f, 0x8e, 0xb5, 0xd7}}, + "Amusement Recreation Red" + }, + { {0x79f58929,{0x46c6, 0x4337, 0xc0b1}, {0xf0, 0x09, 0x55, 0xbb, 0x1f, 0xc3}}, + "Telephone Red" + }, + { {0x0083b377,{0xfb80, 0x4a83, 0x3593}, {0x56, 0xe5, 0xfe, 0xc4, 0xcd, 0x43}}, + "Exit" + }, + { {0x0c232891,{0xab4d, 0x440e, 0x7083}, {0x05, 0x63, 0x3a, 0xf5, 0x66, 0x11}}, + "Exit with Services" + }, + { {0xaf63e7c2,{0x03fa, 0x418e, 0xc68b}, {0x02, 0xb8, 0xf5, 0x61, 0xb6, 0x61}}, + "Pizza" + }, + { {0xd419c693,{0x39e6, 0x43db, 0xa1b8}, {0x7f, 0xcc, 0x2c, 0xb8, 0x51, 0x4a}}, + "Financial Services" + }, + { {0x70740a81,{0xe4ca, 0x4ac2, 0xa498}, {0x21, 0xc8, 0x5b, 0xc0, 0xb7, 0xae}}, + "City 3" + }, + { {0x9a582ff6,{0x34c4, 0x41c6, 0xf0a3}, {0x99, 0x69, 0x9d, 0xbe, 0x2e, 0x08}}, + "Food Store" + }, + { {0x3cd31689,{0x2f8f, 0x4fb0, 0xcb88}, {0x34, 0x84, 0xfc, 0x8b, 0x03, 0xe4}}, + "" + }, + { {0x952557a6,{0xe29e, 0x4512, 0x1184}, {0x1a, 0x3c, 0x9c, 0xd4, 0x83, 0x7d}}, + "" + }, + { {0x03dc278c,{0xe8ff, 0x46ac, 0x3daa}, {0x9f, 0xe9, 0x1e, 0xcf, 0x10, 0x35}}, + "Driving Range" + }, + { {0xacd28bab,{0x0ec0, 0x4393, 0xaf8b}, {0xbb, 0x5e, 0x74, 0xb3, 0x87, 0x12}}, + "Golf Municipal" + }, + { {0x984e7139,{0xeab8, 0x49f6, 0x55a0}, {0x8d, 0x51, 0xe6, 0xdd, 0xcc, 0xf4}}, + "Golf Private" + }, + { {0xec5828ab,{0x2a9d, 0x48f8, 0xd79b}, {0xc9, 0xc3, 0x30, 0x8e, 0xe4, 0xea}}, + "Golf Public" + }, + { {0xb0120d99,{0x683a, 0x4ecc, 0x129a}, {0x29, 0x94, 0x1f, 0x04, 0xae, 0x10}}, + "Golf Resort" + }, + { {0x2ce7685a,{0x6eaf, 0x4061, 0x29a5}, {0x87, 0x5e, 0xfa, 0x41, 0x75, 0x1a}}, + "Golf Semi Private" + }, + { {0x10397049,{0x9fc9, 0x4380, 0x5680}, {0x81, 0xd9, 0xe7, 0x43, 0x1f, 0x11}}, + "Medical Service" + }, + { {0x2fc28df6,{0xe806, 0x436e, 0xe0b9}, {0x46, 0x1d, 0xeb, 0xad, 0x56, 0x60}}, + "Home Furnishings" + }, + { {0x910313db,{0xafce, 0x4019, 0x1aa4}, {0xe6, 0x2c, 0xe6, 0xd1, 0xfd, 0xf7}}, + "Industrial" + }, + { {0x9e442c6e,{0xe12a, 0x4407, 0xd68a}, {0x1c, 0x5e, 0x19, 0xe7, 0xfe, 0x01}}, + "" + }, + { {0x37e2fe4a,{0xcd71, 0x413f, 0x0cad}, {0x81, 0xc5, 0x2c, 0xf4, 0x78, 0x79}}, + "" + }, + { {0x3c756e09,{0xb2dc, 0x48a6, 0x04a9}, {0x20, 0xb7, 0xc9, 0x9d, 0x14, 0x51}}, + "" + }, + { {0xa1245b1c,{0x156a, 0x48fc, 0x6f96}, {0xa5, 0xa3, 0x22, 0x54, 0x13, 0x97}}, + "Manufacturing" + }, + { {0x5bddbd7a,{0xf3cb, 0x454c, 0x06af}, {0x46, 0x1a, 0x68, 0xea, 0x60, 0x1a}}, + "Note" + }, + { {0xcb6777e1,{0xe0e0, 0x45ce, 0x309f}, {0x8d, 0x61, 0x7a, 0xd9, 0x89, 0xf5}}, + "City" + }, + { {0xbc168c08,{0x2b7f, 0x44be, 0x3883}, {0x81, 0x31, 0x4a, 0x09, 0xf5, 0x78}}, + "Air Base" + }, + { {0xa8857b0f,{0xfc3b, 0x4cd1, 0x9e91}, {0xf5, 0x3b, 0x21, 0xa8, 0x3b, 0xb9}}, + "Battlefield" + }, + { {0x06db55c1,{0xf687, 0x4840, 0x7c80}, {0x95, 0x58, 0x77, 0x8e, 0x5a, 0xdd}}, + "Mining" + }, + { {0xcc61b277,{0xa48c, 0x445a, 0xd9b9}, {0xe5, 0x91, 0x36, 0x18, 0x4e, 0x09}}, + "Mountain" + }, + { {0xfde13186,{0xb6cb, 0x4374, 0xc880}, {0x56, 0x99, 0xeb, 0x51, 0x68, 0x87}}, + "Capital" + }, + { {0xb14d90d1,{0xd943, 0x40ff, 0x9fb7}, {0x9b, 0x92, 0xd1, 0x23, 0xca, 0xef}}, + "Route" + }, + { {0x7eabc63f,{0x05d0, 0x4465, 0xb1b0}, {0x61, 0x2a, 0xf7, 0x4d, 0x0f, 0x4e}}, + "Overnight" + }, + { {0xac39d8b9,{0xfcdc, 0x4b50, 0x9ca6}, {0xea, 0x6c, 0x4b, 0xb5, 0x96, 0x0f}}, + "Route End Active" + }, + { {0xe1b9d86b,{0x95e6, 0x4bd8, 0xd880}, {0x7b, 0x6c, 0xc6, 0xd2, 0x00, 0x34}}, + "Route End Inactive" + }, + { {0x98712315,{0x7e1e, 0x4024, 0x8392}, {0xe3, 0xb8, 0x5a, 0x51, 0x45, 0xb4}}, + "Fuel Stop" + }, + { {0xe5ea5b38,{0x7b80, 0x4b42, 0x0aba}, {0x3d, 0x38, 0xf0, 0xe1, 0x17, 0x9a}}, + "Route Start Active" + }, + { {0x18fd0d49,{0x0a29, 0x433a, 0xd584}, {0xe5, 0xb7, 0x5b, 0xe8, 0x25, 0xbc}}, + "Route Start Inactive" + }, + { {0x2f52144b,{0x903e, 0x4dd9, 0x79af}, {0xe1, 0x66, 0x9b, 0xfc, 0xa9, 0xc1}}, + "Route Stop Active" + }, + { {0xfaf8d826,{0xd27d, 0x4316, 0x0e92}, {0xce, 0x8d, 0x85, 0x93, 0x4c, 0xf5}}, + "Route Stop Inactive" + }, + { {0xff44cae2,{0x707c, 0x4a1c, 0x43af}, {0x8b, 0xb6, 0xb1, 0x19, 0x9c, 0xf2}}, + "Route Via" + }, + { {0x5a50d59b,{0xc15b, 0x49c4, 0x9faa}, {0xc4, 0x1c, 0x4f, 0xe2, 0x95, 0x2a}}, + "Radiation Green" + }, + { {0x19556023,{0xb1e5, 0x4c9c, 0x49ba}, {0x08, 0x52, 0xa1, 0x24, 0x3d, 0x9f}}, + "Radiation Red" + }, + { {0xa54be251,{0x6688, 0x49fb, 0x60b3}, {0x89, 0x56, 0x37, 0x68, 0xc5, 0xb0}}, + "Electricity" + }, + { {0xd793ff0c,{0xfbe0, 0x4383, 0x3183}, {0xcf, 0x4f, 0x04, 0xb7, 0xee, 0x0a}}, + "Personal Furnishings" + }, + { {0x00f90733,{0x7ab5, 0x42cf, 0x468c}, {0xbf, 0x91, 0x27, 0xd3, 0xa8, 0x9c}}, + "Personal Services" + }, + { {0xea677f24,{0xbbe8, 0x4238, 0xee9c}, {0x6c, 0x0a, 0xec, 0x0e, 0x34, 0xf4}}, + "Telephone Black" + }, + { {0x2d8a05b5,{0x8baf, 0x4f28, 0xf58b}, {0xfb, 0x7f, 0x37, 0x34, 0x28, 0xa7}}, + "Government Light" + }, + { {0x40c64dfc,{0xc2d0, 0x4b0e, 0x6582}, {0x3f, 0x26, 0x9c, 0xcb, 0x6f, 0x1d}}, + "Airport Red Square" + }, + { {0xf27adb5d,{0x3629, 0x44c7, 0x95a2}, {0x25, 0x2c, 0x95, 0x24, 0x98, 0x2f}}, + "Propeller Aircraft" + }, + { {0x5a718e13,{0x3547, 0x42c5, 0x6d9d}, {0xb2, 0x82, 0xa5, 0x53, 0xbd, 0x3a}}, + "Jet Aircraft" + }, + { {0x0a471039,{0x2dfe, 0x447e, 0x54be}, {0xa3, 0x93, 0xae, 0x9a, 0xdd, 0xac}}, + "Government" + }, + { {0x4a59da2f,{0xe1c3, 0x42c3, 0x6ca1}, {0x06, 0xb9, 0x14, 0x1b, 0x89, 0x99}}, + "USA Regional" + }, + { {0xf16500a9,{0xa845, 0x4293, 0xae89}, {0x5c, 0x29, 0xbb, 0x0d, 0x06, 0xf7}}, + "House 2" + }, + { {0x7b05524d,{0xcb5a, 0x456f, 0x96b3}, {0x03, 0x61, 0x24, 0x54, 0x6a, 0x54}}, + "Picnic" + }, + { {0xb88ad7a1,{0xb94d, 0x42e8, 0x2b9d}, {0xf5, 0x4c, 0x2b, 0xff, 0x57, 0xdc}}, + "Restaurant" + }, + { {0xdc48a20a,{0x54a2, 0x4c61, 0x1fbe}, {0x02, 0x74, 0x5b, 0xe9, 0x18, 0x99}}, + "Store 2" + }, + { {0x6b5ab040,{0x96df, 0x46ae, 0xacb8}, {0xe4, 0x47, 0x66, 0x3f, 0xec, 0x9b}}, + "" + }, + { {0x153b2cff,{0x6232, 0x4294, 0xd59a}, {0xc5, 0xa0, 0x7b, 0xe0, 0x16, 0xeb}}, + "Blue Star" + }, + { {0xf276f6b3,{0x586a, 0x4bf8, 0x2f82}, {0xf2, 0x69, 0xe3, 0x76, 0x7e, 0xd5}}, + "" + }, + { {0x91d242c8,{0x0986, 0x4fad, 0x8286}, {0xec, 0x79, 0x79, 0xcd, 0xab, 0x02}}, + "Running" + }, + { {0x8b0078db,{0x6ee0, 0x4caa, 0xd3b5}, {0xfe, 0xe1, 0xc2, 0xbf, 0x94, 0x7d}}, + "Transportation" + }, + { {0x0599f6c9,{0x478e, 0x4f63, 0x78a5}, {0xed, 0x31, 0xb5, 0xae, 0xda, 0x89}}, + "Fishing 2" + }, + { {0x7389128c,{0x0e78, 0x4d5d, 0x4189}, {0xb8, 0xf3, 0xb5, 0xbd, 0x70, 0xb1}}, + "Automotive" + }, + { {0x0362b593,{0x3df6, 0x48ed, 0xc489}, {0x85, 0x13, 0xc1, 0xc0, 0xb9, 0x0d}}, + "Cloudy" + }, + { {0xf0717a94,{0xd048, 0x4770, 0x9bab}, {0x80, 0x09, 0xbd, 0x4b, 0x1e, 0x75}}, + "Partly Cloudy" + }, + { {0x14486bbc,{0xae6b, 0x44ea, 0xd6b9}, {0xbf, 0x9a, 0x39, 0x7a, 0x51, 0x6c}}, + "Mostly Cloudy" + }, + { {0x7a258c70,{0xabec, 0x4cff, 0x4983}, {0x84, 0xdc, 0x2f, 0x2e, 0xff, 0x28}}, + "Hurricane" + }, + { {0xeff260d4,{0x46d5, 0x4fb5, 0xc79c}, {0x5e, 0x06, 0xc8, 0xab, 0x7a, 0x2b}}, + "Lightning" + }, + { {0xc3d70220,{0x5154, 0x4766, 0xf0af}, {0xdf, 0x86, 0x74, 0x40, 0x5f, 0x8c}}, + "Rain" + }, + { {0xf2dfbc91,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Flag" + }, + { {0xf2dfbc92,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Blue Flag" + }, + { {0xf2dfbc93,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Flag" + }, + { {0xf2dfbc94,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Flag" + }, + { {0xf2dfbc95,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Flag 2" + }, + { {0xf2dfbc96,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Flag" + }, + { {0xf2dfbc97,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Flag" + }, + { {0xf2dfbc98,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Flag" + }, + { {0xf2dfbc99,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue-Green Flag" + }, + { {0xf2dfbc9a,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Light Blue Flag" + }, + { {0x623e1ee1,{0xaf27, 0x100f, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Dark Blue Map Pin" + }, + { {0xf2dfbc9d,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Map Pin" + }, + { {0xf2dfbc9e,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Map Pin" + }, + { {0xf2dfbc9f,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Map Pin" + }, + { {0xf2dfbca0,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Map Pin" + }, + { {0xf2dfbca1,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Map Pin" + }, + { {0xf2dfbca2,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Map Pin" + }, + { {0xf2dfbca3,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Map Pin" + }, + { {0xf2dfbca4,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Gray Map Pin" + }, + { {0xf2dfbca5,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Gray Map Pin" + }, + { {0xd1703de0,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Dot" + }, + { {0xd1703de1,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Dot" + }, + { {0xd1703de2,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Dot" + }, + { {0xd1703de3,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Blue Dot" + }, + { {0xd1703de5,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Dot" + }, + { {0x45c088e0,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Dot" + }, + { {0x45c088e1,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Dot" + }, + { {0x45c088e2,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Dot" + }, + { {0x45c088e3,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Light Blue Dot" + }, + { {0xbde3a8a1,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue-Green Dot" + }, + { {0xbde3a8a2,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Green Dot" + }, + { {0xbde3a8a3,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Green Dot" + }, + { {0xbde3a8a4,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Blue Dot" + }, + { {0xbde3a8a5,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Blue Dot" + }, + { {0xbde3a8a6,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Red Dot" + }, + { {0xbde3a8a7,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Red Dot" + }, + { {0xbde3a8a8,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Yellow Dot" + }, + { {0xbde3a8a9,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Brown Dot" + }, + { {0xbde3a8aa,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Light Blue Dot" + }, + { {0xbde3a8ab,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Blue-Green Dot" + }, + { {0x623e1ee0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Red Flag" + }, + { {0x623e1ee1,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Map Pin" + }, + { {0x623e1ee2,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Yellow Square" + }, + { {0x623e1ee3,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Red X" + }, + { {0x623e1ee4,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Blue Circle" + }, + { {0x623e1ee5,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "House" + }, + { {0x623e1ee7,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Triangle" + }, + { {0x623e1ee8,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Green Star" + }, + { {0x9d277805,{0xe2f8, 0x4f43, 0x3f97}, {0x35, 0x0d, 0x40, 0xae, 0x5c, 0xd3}}, + "Geocache" + }, + { {0xcb8aad04,{0xcc2d, 0x47f2, 0x428a}, {0x80, 0xf7, 0xd6, 0x68, 0xed, 0x32}}, + "Geocache Found" + }, + { {0x7341c1f4,{0xdecd, 0x4d35, 0x45a5}, {0x52, 0x25, 0x5e, 0xbf, 0xe6, 0x51}}, + "Tent" + }, + { {0x835b84e2,{0xf10c, 0x45cb, 0x958f}, {0x18, 0x3a, 0xc2, 0x2a, 0xe5, 0x28}}, + "Tipup Up" + }, + { {0xce06fc92,{0xbb0c, 0x4ec1, 0xda93}, {0x64, 0x4a, 0x60, 0xbe, 0x40, 0x90}}, + "Topup Down" + }, }; -int FindIconByName( const char *name, GUID *guid ) { - int i = 0; - for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ ) - { - if ( !case_ignore_strcmp(name, default_guids[i].name)) { - memcpy( guid, &(default_guids[i].guid), sizeof(GUID)); - return 1; - } - } - return 0; +int FindIconByName(const char* name, GUID* guid) +{ + int i = 0; + for (i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++) { + if (!case_ignore_strcmp(name, default_guids[i].name)) { + memcpy(guid, &(default_guids[i].guid), sizeof(GUID)); + return 1; + } + } + return 0; } -int FindIconByGuid( GUID *guid, char **name ) { - int i = 0; - for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ ) - { - if ( !memcmp(guid, &default_guids[i].guid, sizeof(GUID))) { - *name = default_guids[i].name; - return 1; - } - } - return 0; +int FindIconByGuid(GUID* guid, char** name) +{ + int i = 0; + for (i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++) { + if (!memcmp(guid, &default_guids[i].guid, sizeof(GUID))) { + *name = (char*) default_guids[i].name; + return 1; + } + } + return 0; } diff --git a/gpsbabel/arcdist.c b/gpsbabel/arcdist.c index ecbc75db2..f622033ad 100644 --- a/gpsbabel/arcdist.c +++ b/gpsbabel/arcdist.c @@ -26,145 +26,278 @@ #define MYNAME "Arc filter" static double pos_dist; -static char *distopt = NULL; -static char *arcfileopt = NULL; -static char *exclopt = NULL; -static char *ptsopt = NULL; +static char* distopt = NULL; +static char* arcfileopt = NULL; +static char* rteopt = NULL; +static char* trkopt = NULL; +static char* exclopt = NULL; +static char* ptsopt = NULL; +static char* projectopt = NULL; typedef struct { - double distance; + double distance; + double prjlatitude, prjlongitude; + double frac; + waypoint* arcpt1, * arcpt2; } extra_data; static arglist_t arcdist_args[] = { - {"file", &arcfileopt, "File containing vertices of arc", - NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX}, - {"distance", &distopt, "Maximum distance from arc", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX}, - {"exclude", &exclopt, "Exclude points close to the arc", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX}, - {"points", &ptsopt, "Use distance from vertices not lines", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "file", &arcfileopt, "File containing vertices of arc", + NULL, ARGTYPE_FILE, ARG_NOMINMAX + }, + { + "rte", &rteopt, "Route(s) are vertices of arc", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "trk", &trkopt, "Track(s) are vertices of arc", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "distance", &distopt, "Maximum distance from arc", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "exclude", &exclopt, "Exclude points close to the arc", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "points", &ptsopt, "Use distance from vertices not lines", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "project", &projectopt, "Move waypoints to its projection on lines or vertices", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #define BADVAL 999999 -void +static void +arcdist_arc_disp_wpt_cb(const waypoint *arcpt2) +{ + queue* elem, * tmp; + waypoint* waypointp; + extra_data* ed; + double dist; + double prjlat, prjlon, frac; + static waypoint* arcpt1 = NULL; + + if (arcpt2 && arcpt2->latitude != BADVAL && arcpt2->longitude != BADVAL && + (ptsopt || (arcpt1 && + (arcpt1->latitude != BADVAL && arcpt1->longitude != BADVAL)))) { + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + + waypointp = (waypoint*) elem; + if (waypointp->extra_data) { + ed = (extra_data*) waypointp->extra_data; + } else { + ed = (extra_data*) xcalloc(1, sizeof(*ed)); + ed->distance = BADVAL; + } + if (ed->distance == BADVAL || projectopt || ed->distance >= pos_dist) { + if (ptsopt) { + dist = gcdist(RAD(arcpt2->latitude), + RAD(arcpt2->longitude), + RAD(waypointp->latitude), + RAD(waypointp->longitude)); + prjlat = arcpt2->latitude; + prjlon = arcpt2->longitude; + frac = 1.0; + } else { + dist = linedistprj(arcpt1->latitude, + arcpt1->longitude, + arcpt2->latitude, + arcpt2->longitude, + waypointp->latitude, + waypointp->longitude, + &prjlat, &prjlon, &frac); + } + + /* convert radians to float point statute miles */ + dist = radtomiles(dist); + + if (ed->distance > dist) { + ed->distance = dist; + if (projectopt) { + ed->prjlatitude = prjlat; + ed->prjlongitude = prjlon; + ed->frac = frac; + ed->arcpt1 = arcpt1; + ed->arcpt2 = (waypoint*) arcpt2; + } + } + waypointp->extra_data = ed; + } + } + } + arcpt1 = (waypoint*) arcpt2; +} + +static void +arcdist_arc_disp_hdr_cb(const route_head *rte) +{ + /* Set arcpt1 to NULL */ + arcdist_arc_disp_wpt_cb(NULL); +} + +void arcdist_process(void) { - queue * elem, * tmp; - waypoint * waypointp; - double dist; - extra_data *ed; - double lat1, lon1, lat2, lon2; - int fileline = 0; - char *line; - gbfile *file_in; - - file_in = gbfopen(arcfileopt, "r", MYNAME); - - lat1 = lon1 = lat2 = lon2 = BADVAL; - while ((line = gbfgetstr(file_in))) { - char *pound = NULL; - int argsfound = 0; - - fileline++; - - pound = strchr( line, '#' ); - if ( pound ) { - if ( 0 == strncmp( pound, "#break", 6)) { - lat1 = lon1 = BADVAL; - } - *pound = '\0'; - } - - lat2 = lon2 = BADVAL; - argsfound = sscanf( line, "%lf %lf", &lat2, &lon2 ); - - if ( argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { - warning(MYNAME ": Warning: Arc file contains unusable vertex on line %d.\n", fileline ); - } - else if ( lat2 != BADVAL && lon2 != BADVAL && - (ptsopt || (lat1 != BADVAL && lon1 != BADVAL ))) { - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - - waypointp = (waypoint *)elem; - if ( waypointp->extra_data ) { - ed = (extra_data *) waypointp->extra_data; - } - else { - ed = (extra_data *) xcalloc(1, sizeof(*ed)); - ed->distance = BADVAL; - } - if ( ed->distance == BADVAL || ed->distance >= pos_dist ) { - if ( ptsopt ) { - dist = gcdist( RAD(lat2), RAD(lon2), - RAD(waypointp->latitude), - RAD(waypointp->longitude) ); - } - else { - dist = linedist(lat1, lon1, lat2, lon2, - waypointp->latitude, - waypointp->longitude ); - } - - /* convert radians to float point statute miles */ - dist = radtomiles(dist); - - if ( ed->distance > dist ) { - ed->distance = dist; - } - waypointp->extra_data = ed; - } - } - } - lat1 = lat2; - lon1 = lon2; - } - - gbfclose(file_in); - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wp = (waypoint *) elem; - ed = (extra_data *) wp->extra_data; - wp->extra_data = NULL; - if ( ed ) { - if ((ed->distance >= pos_dist) == (exclopt == NULL)) { - waypt_del(wp); - waypt_free(wp); - } - xfree( ed ); - } - } + queue* elem, * tmp; + unsigned removed; + + if (arcfileopt) { + int fileline = 0; + char* line; + gbfile* file_in; + waypoint* arcpt2, * arcpt1; + + file_in = gbfopen(arcfileopt, "r", MYNAME); + + arcpt1 = waypt_new(); + arcpt2 = waypt_new(); + arcdist_arc_disp_hdr_cb(NULL); + + arcpt2->latitude = arcpt2->longitude = BADVAL; + while ((line = gbfgetstr(file_in))) { + char * pound = NULL; + int argsfound = 0; + + fileline++; + + pound = strchr(line, '#'); + if (pound) { + if (0 == strncmp(pound, "#break", 6)) { + arcdist_arc_disp_hdr_cb(NULL); + } + *pound = '\0'; + } + + arcpt2->latitude = arcpt2->longitude = BADVAL; + argsfound = sscanf(line, "%lf %lf", &arcpt2->latitude, &arcpt2->longitude); + + if (argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { + warning(MYNAME ": Warning: Arc file contains unusable vertex on line %d.\n", fileline); + } + else { + waypoint* arcpttmp = arcpt1; + arcdist_arc_disp_wpt_cb(arcpt2); + arcpt1 = arcpt2; + arcpt2 = arcpttmp; + } + } + waypt_free(arcpt1); + waypt_free(arcpt2); + + gbfclose(file_in); + } else if (rteopt) { + route_disp_all(arcdist_arc_disp_hdr_cb, NULL, arcdist_arc_disp_wpt_cb); + } else if (trkopt) { + track_disp_all(arcdist_arc_disp_hdr_cb, NULL, arcdist_arc_disp_wpt_cb); + } + + removed = 0; + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint* wp = (waypoint*) elem; + extra_data* ed; + ed = (extra_data*) wp->extra_data; + wp->extra_data = NULL; + if (ed) { + if ((ed->distance >= pos_dist) == (exclopt == NULL)) { + waypt_del(wp); + waypt_free(wp); + removed++; + } else if (projectopt) { + wp->longitude = ed->prjlongitude; + wp->latitude = ed->prjlatitude; + wp->route_priority = 1; + if (!arcfileopt && + (ed->arcpt2->altitude != unknown_alt) && + (ptsopt || (ed->arcpt1->altitude != unknown_alt))) { + /* Interpolate alititude */ + if (ptsopt) { + wp->altitude = ed->arcpt2->altitude; + } else { + wp->altitude = ed->arcpt1->altitude + + ed->frac * (ed->arcpt2->altitude - ed->arcpt1->altitude); + } + } + if (trkopt && + (ed->arcpt2->creation_time != 0) && + (ptsopt || (ed->arcpt1->creation_time != 0))) { + /* Interpolate time */ + if (ptsopt) { + wp->creation_time = ed->arcpt2->creation_time; + wp->microseconds = ed->arcpt2->microseconds; + } else { + double wptimes = ed->arcpt1->creation_time + + ed->frac * (ed->arcpt2->creation_time - ed->arcpt1->creation_time); + wp->creation_time = floor(wptimes); + wp->microseconds = 1000000.0 * (wptimes - wp->creation_time); + if (ed->arcpt1->microseconds <= ed->arcpt2->microseconds) { + wp->microseconds += ed->arcpt1->microseconds + + ed->frac * (ed->arcpt1->microseconds - ed->arcpt1->microseconds); + } else { + wp->microseconds += ed->arcpt1->microseconds + + ed->frac * (1000000 - ed->arcpt1->creation_time + + ed->arcpt2->creation_time); + wp->creation_time--; + } + + wp->creation_time += wp->microseconds / 1000000; + wp->microseconds %= 1000000; + } + } + if (global_opts.debug_level >= 1) { + warning("Including waypoint %s at dist:%f lat:%f lon:%f\n", wp->shortname, ed->distance, wp->latitude, wp->longitude); + } + } + xfree(ed); + } + } + if (global_opts.verbose_status > 0) { + printf(MYNAME "-arc: %d waypoint(s) removed.\n", removed); + } } void -arcdist_init(const char *args) { - char *fm; +arcdist_init(const char* args) +{ + char* fm; + + if ((!arcfileopt && !rteopt && !trkopt) || + (arcfileopt && (rteopt || trkopt)) || + (rteopt && trkopt)) { + fatal(MYNAME ": Incompatible or incomplete option values!\n"); + } - pos_dist = 0; + pos_dist = 0; - if (distopt) { - pos_dist = strtod(distopt, &fm); + if (distopt) { + pos_dist = strtod(distopt, &fm); - if ((*fm == 'k') || (*fm == 'K')) { - /* distance is kilometers, convert to feet */ - pos_dist *= .6214; - } - } + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to mile */ + pos_dist *= .6214; + } + } } void -arcdist_deinit(void) { - /* do nothing */ +arcdist_deinit(void) +{ + /* do nothing */ } filter_vecs_t arcdist_vecs = { - arcdist_init, - arcdist_process, - arcdist_deinit, - NULL, - arcdist_args + arcdist_init, + arcdist_process, + arcdist_deinit, + NULL, + arcdist_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/avltree.c b/gpsbabel/avltree.c index 08c6c6e87..caccace9c 100644 --- a/gpsbabel/avltree.c +++ b/gpsbabel/avltree.c @@ -25,26 +25,26 @@ #define MYNAME "avltree" #ifdef DEBUG_MEM -# define AVLTREE_MAGIC 0x41564c53 +# define AVLTREE_MAGIC 0x41564c53 /* ((((((0L | 'A') << 8) | 'V') << 8) | 'L') << 8) | 'T'; */ #endif #ifdef MEM_DEBUG -void avltree_check_handle(const void *tree); +void avltree_check_handle(const void* tree); #endif -static void avltree_node_free(const avltree_t *tree, avlnode_t *node); -static int avltree_node_height(avlnode_t *node); -static int avltree_insert_node(avltree_t *tree, avlnode_t **root, const char *key, const void *data); -static int avltree_delete_node(avltree_t *tree, const char *key, avlnode_t **root, int *changed); -static avlnode_t *avltree_right_rotation(avlnode_t *A); -static avlnode_t *avltree_left_rotation(avlnode_t *A); -static avlnode_t *avltree_left_right_rotation(avlnode_t *A); -static avlnode_t *avltree_right_left_rotation(avlnode_t *A); -static avlnode_t *avltree_dupe_node(const avltree_t *tree, const avlnode_t *node); -static int avltree_strcmpr(const char *s1, const char *s2); -static int avltree_case_ignore_strcmpr(const char *s1, const char *s2); -static avlnode_t *avltree_find_next(const avltree_t *tree, avlnode_t *node, const char *key); -static void avltree_save_key(avltree_t *tree, const char *key); +static void avltree_node_free(const avltree_t* tree, avlnode_t* node); +static int avltree_node_height(avlnode_t* node); +static int avltree_insert_node(avltree_t* tree, avlnode_t** root, const char* key, const void* data); +static int avltree_delete_node(avltree_t* tree, const char* key, avlnode_t** root, int* changed); +static avlnode_t* avltree_right_rotation(avlnode_t* A); +static avlnode_t* avltree_left_rotation(avlnode_t* A); +static avlnode_t* avltree_left_right_rotation(avlnode_t* A); +static avlnode_t* avltree_right_left_rotation(avlnode_t* A); +static avlnode_t* avltree_dupe_node(const avltree_t* tree, const avlnode_t* node); +static int avltree_strcmpr(const char* s1, const char* s2); +static int avltree_case_ignore_strcmpr(const char* s1, const char* s2); +static avlnode_t* avltree_find_next(const avltree_t* tree, avlnode_t* node, const char* key); +static void avltree_save_key(avltree_t* tree, const char* key); #ifdef MEM_DEBUG @@ -59,215 +59,229 @@ static void avltree_save_key(avltree_t *tree, const char *key); /* Allocate and initialize an AVL Tree */ -avltree_t * -avltree_init(const int options, const char *module) +avltree_t* +avltree_init(const int options, const char* module) { - avltree_t *tree; - - if ((module == NULL) || (*module == '\0')) - fatal(MYNAME ": 'avltree_init' should be called with a valid module name!\n"); - - tree = (avltree_t*) xcalloc(1, sizeof(*tree)); - tree->options = options; - tree->module = module; - - if (options & AVLTREE_NON_CASE_SENSITIVE) { - if (options & AVLTREE_DESCENDING) - tree->compare = avltree_case_ignore_strcmpr; /* descending, non-case-sensitive */ - else - tree->compare = case_ignore_strcmp; /* ascending, non-case-sensitive */ - } - else { - if (options & AVLTREE_DESCENDING) - tree->compare = avltree_strcmpr; /* descending, case-sensitive */ - else - tree->compare = strcmp; /* ascending, case-sensitive */ - } - - return tree; + avltree_t* tree; + + if ((module == NULL) || (*module == '\0')) { + fatal(MYNAME ": 'avltree_init' should be called with a valid module name!\n"); + } + + tree = (avltree_t*) xcalloc(1, sizeof(*tree)); + tree->options = options; + tree->module = module; + + if (options & AVLTREE_NON_CASE_SENSITIVE) { + if (options & AVLTREE_DESCENDING) { + tree->compare = avltree_case_ignore_strcmpr; /* descending, non-case-sensitive */ + } else { + tree->compare = case_ignore_strcmp; /* ascending, non-case-sensitive */ + } + } else { + if (options & AVLTREE_DESCENDING) { + tree->compare = avltree_strcmpr; /* descending, case-sensitive */ + } else { + tree->compare = strcmp; /* ascending, case-sensitive */ + } + } + + return tree; } /* Delete all items of tree [tree] */ int -avltree_clear(avltree_t *tree) +avltree_clear(avltree_t* tree) { - int res; - - AVLTREE_CHECK_HANDLE(tree); - - res = tree->count; - avltree_save_key(tree, NULL); - if (res) { - avltree_node_free(tree, tree->root); - /* avltree_node_free doesn't touch 'count' */ - tree->count = 0; - tree->root = NULL; - } - return res; + int res; + + AVLTREE_CHECK_HANDLE(tree); + + res = tree->count; + avltree_save_key(tree, NULL); + if (res) { + avltree_node_free(tree, tree->root); + /* avltree_node_free doesn't touch 'count' */ + tree->count = 0; + tree->root = NULL; + } + return res; } /* Destroy an AVL Tree */ void -avltree_done(avltree_t *tree) +avltree_done(avltree_t* tree) { - avltree_clear(tree); - xfree(tree); + avltree_clear(tree); + xfree(tree); } /* Get number of items in tree */ int -avltree_count(const avltree_t *tree) +avltree_count(const avltree_t* tree) { - AVLTREE_CHECK_HANDLE(tree); + AVLTREE_CHECK_HANDLE(tree); - return tree->count; + return tree->count; } /* Delete item with key [key] */ int -avltree_delete(avltree_t *tree, const char *key) +avltree_delete(avltree_t* tree, const char* key) { - int changed = 0; - - AVLTREE_CHECK_HANDLE(tree); + int changed = 0; - if (key == NULL) - fatal("%s/%s.%d: Attempt to delete a NULL-pointer!\n", - tree->module, MYNAME, __LINE__); + AVLTREE_CHECK_HANDLE(tree); - return avltree_delete_node(tree, key, &tree->root, &changed); + if (key == NULL) + fatal("%s/%s.%d: Attempt to delete a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); + + return avltree_delete_node(tree, key, &tree->root, &changed); } /* Duplicate an existing tree */ -avltree_t * -avltree_dupe(const avltree_t *tree, const char *module) +avltree_t* +avltree_dupe(const avltree_t* tree, const char* module) { - avltree_t *dupe; - - AVLTREE_CHECK_HANDLE(tree); - - dupe = avltree_init(tree->options, module); - if ((dupe->count = tree->count)) - dupe->root = avltree_dupe_node(tree, tree->root); - - return dupe; + avltree_t* dupe; + + AVLTREE_CHECK_HANDLE(tree); + + dupe = avltree_init(tree->options, module); + if ((dupe->count = tree->count)) { + dupe->root = avltree_dupe_node(tree, tree->root); + } + + return dupe; } /* Find key [key] in tree */ int -avltree_find(const avltree_t *tree, const char *key, const void **data) +avltree_find(const avltree_t* tree, const char* key, const void** data) { - avlnode_t *node; - - AVLTREE_CHECK_HANDLE(tree); - - node = tree->root; - while (node) { - int compare = tree->compare(key, node->key); - - if (compare < 0) - node = node->left; - else if (compare > 0) - node = node->right; - else { - if (data) - (*data) = node->data; - break; - } - } - - return (node) ? 1 : 0; + avlnode_t* node; + + AVLTREE_CHECK_HANDLE(tree); + + node = tree->root; + while (node) { + int compare = tree->compare(key, node->key); + + if (compare < 0) { + node = node->left; + } else if (compare > 0) { + node = node->right; + } else { + if (data) { + (*data) = node->data; + } + break; + } + } + + return (node) ? 1 : 0; } /* Get the first (the MIN-) entry of the tree */ -const char * -avltree_first(const avltree_t *tree, const void **data) +const char* +avltree_first(const avltree_t* tree, const void** data) { - avlnode_t *node; + avlnode_t* node; + + AVLTREE_CHECK_HANDLE(tree); - AVLTREE_CHECK_HANDLE(tree); + node = tree->root; + if (! node) { + return NULL; + } - node = tree->root; - if (! node) return NULL; - - while (node->left) node = node->left; - avltree_save_key((avltree_t *)tree, node->key); - if (data) (*data) = node->data; + while (node->left) { + node = node->left; + } + avltree_save_key((avltree_t*)tree, node->key); + if (data) { + (*data) = node->data; + } - return tree->key; + return tree->key; } /* Get the current height of the tree */ int -avltree_height(const avltree_t *tree) +avltree_height(const avltree_t* tree) { - AVLTREE_CHECK_HANDLE(tree); + AVLTREE_CHECK_HANDLE(tree); - if (tree->count) - return avltree_node_height(tree->root); - else - return 0; + if (tree->count) { + return avltree_node_height(tree->root); + } else { + return 0; + } } /* Insert key [key] and [data] into tree */ int -avltree_insert(avltree_t *tree, const char *key, const void *data) +avltree_insert(avltree_t* tree, const char* key, const void* data) { - int count; - - AVLTREE_CHECK_HANDLE(tree); + int count; + + AVLTREE_CHECK_HANDLE(tree); - if (key == NULL) - fatal("%s/%s.%d: Attempt to insert a NULL-pointer!\n", - tree->module, MYNAME, __LINE__); + if (key == NULL) + fatal("%s/%s.%d: Attempt to insert a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); - count = tree->count; - avltree_insert_node(tree, &tree->root, key, data); - return (count != tree->count) ? 1 : 0; + count = tree->count; + avltree_insert_node(tree, &tree->root, key, data); + return (count != tree->count) ? 1 : 0; } /* Get the next (the entry above [key]) */ -const char * -avltree_next(const avltree_t *tree, const char *key, const void **data) +const char* +avltree_next(const avltree_t* tree, const char* key, const void** data) { - avlnode_t *node; - - AVLTREE_CHECK_HANDLE(tree); - - if (key == NULL) - fatal("%s/%s.%d: Attempt to look for a NULL-pointer!\n", - tree->module, MYNAME, __LINE__); - - node = tree->root; - if (! node) return NULL; - - if ((node = avltree_find_next(tree, node, key))) { - avltree_save_key((avltree_t *)tree, node->key); - if (data) - (*data) = node->data; - } - else - avltree_save_key((avltree_t *)tree, NULL); + avlnode_t* node; + + AVLTREE_CHECK_HANDLE(tree); + + if (key == NULL) + fatal("%s/%s.%d: Attempt to look for a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); - return tree->key; + node = tree->root; + if (! node) { + return NULL; + } + + if ((node = avltree_find_next(tree, node, key))) { + avltree_save_key((avltree_t*)tree, node->key); + if (data) { + (*data) = node->data; + } + } else { + avltree_save_key((avltree_t*)tree, NULL); + } + + return tree->key; } @@ -277,473 +291,490 @@ avltree_next(const avltree_t *tree, const char *key, const void **data) #ifdef MEM_DEBUG void -avltree_check_handle(const avltree_t *tree) +avltree_check_handle(const avltree_t* tree) { - if (! tree) - fatal(MYNAME ": Invalid (NULL-) pointer!\n"); - if (tree->magic != AVLTREE_MAGIC) - fatal(MYNAME ": Invalid (no AVL tree object) pointer!\n"); + if (! tree) { + fatal(MYNAME ": Invalid (NULL-) pointer!\n"); + } + if (tree->magic != AVLTREE_MAGIC) { + fatal(MYNAME ": Invalid (no AVL tree object) pointer!\n"); + } } -#endif +#endif -static void -avltree_node_free(const avltree_t *tree, avlnode_t *node) +static void +avltree_node_free(const avltree_t* tree, avlnode_t* node) { - if ((! (tree->options & AVLTREE_STATIC_KEYS)) && node->key) - xfree((char *)node->key); - if (node->left) - avltree_node_free(tree, node->left); - if (node->right) - avltree_node_free(tree, node->right); - xfree(node); + if ((!(tree->options & AVLTREE_STATIC_KEYS)) && node->key) { + xfree((char*)node->key); + } + if (node->left) { + avltree_node_free(tree, node->left); + } + if (node->right) { + avltree_node_free(tree, node->right); + } + xfree(node); } static int -avltree_node_height(avlnode_t *node) +avltree_node_height(avlnode_t* node) { - int height = 1; - - if (node->balance < 0) - height += avltree_node_height(node->left); - else if (node->right) - height += avltree_node_height(node->right); - - return height; + int height = 1; + + if (node->balance < 0) { + height += avltree_node_height(node->left); + } else if (node->right) { + height += avltree_node_height(node->right); + } + + return height; } -static avlnode_t * -avltree_right_rotation(avlnode_t *A) +static avlnode_t* +avltree_right_rotation(avlnode_t* A) { -/* -> A B -> / \ / \ -> \ / \ -> B -->> A . -> / \ / \ / \ -> \ -> . -> / \ -*/ - avlnode_t *B; - - B = A->right; - A->right = B->left; - B->left = A; - - /* update balance of all touched nodes */ - /* reference: */ - - B->balance--; - A->balance = -(B->balance); - - return B; + /* + > A B + > / \ / \ + > \ / \ + > B -->> A . + > / \ / \ / \ + > \ + > . + > / \ + */ + avlnode_t* B; + + B = A->right; + A->right = B->left; + B->left = A; + + /* update balance of all touched nodes */ + /* reference: */ + + B->balance--; + A->balance = -(B->balance); + + return B; } -static avlnode_t * -avltree_left_rotation(avlnode_t *A) +static avlnode_t* +avltree_left_rotation(avlnode_t* A) { -/* -> A B -> / \ / \ -> / / \ -> B -->> . A -> / \ / \ / \ -> / -> . -> / \ -*/ - avlnode_t *B; - - B = A->left; - A->left = B->right; - B->right = A; - - /* update balance of all touched nodes */ - /* reference: */ - - B->balance++; - A->balance = -(B->balance); - - return B; + /* + > A B + > / \ / \ + > / / \ + > B -->> . A + > / \ / \ / \ + > / + > . + > / \ + */ + avlnode_t* B; + + B = A->left; + A->left = B->right; + B->right = A; + + /* update balance of all touched nodes */ + /* reference: */ + + B->balance++; + A->balance = -(B->balance); + + return B; } - - -static avlnode_t * -avltree_left_right_rotation(avlnode_t *A) + + +static avlnode_t* +avltree_left_right_rotation(avlnode_t* A) { -/* -> A C -> / \ / \ -> / / \ -> B -->> B A -> / \ / \ / \ -> \ -> C -*/ - avlnode_t *B, *C; - - B = A->left; - C = B->right; - A->left = C->right; - B->right = C->left; - C->right = A; - C->left = B; - - /* update balance of all touched nodes */ - /* reference: */ - - A->balance = (C->balance > 0) ? 0 : -(C->balance); - B->balance = (C->balance < 0) ? 0 : -(C->balance); - C->balance = 0; - - return C; + /* + > A C + > / \ / \ + > / / \ + > B -->> B A + > / \ / \ / \ + > \ + > C + */ + avlnode_t* B, *C; + + B = A->left; + C = B->right; + A->left = C->right; + B->right = C->left; + C->right = A; + C->left = B; + + /* update balance of all touched nodes */ + /* reference: */ + + A->balance = (C->balance > 0) ? 0 : -(C->balance); + B->balance = (C->balance < 0) ? 0 : -(C->balance); + C->balance = 0; + + return C; } -static avlnode_t * -avltree_right_left_rotation(avlnode_t *A) +static avlnode_t* +avltree_right_left_rotation(avlnode_t* A) { -/* -> A C -> / \ / \ -> \ / \ -> B -->> B A -> / \ / \ / \ -> / -> C -*/ - avlnode_t *B, *C; - - B = A->right; - C = B->left; - A->right = C->left; - B->left = C->right; - C->left = A; - C->right = B; - - /* update balance of all touched nodes */ - /* reference: */ - - A->balance = (C->balance < 0) ? 0 : -(C->balance); - B->balance = (C->balance > 0) ? 0 : -(C->balance); - C->balance = 0; - - return C; + /* + > A C + > / \ / \ + > \ / \ + > B -->> B A + > / \ / \ / \ + > / + > C + */ + avlnode_t* B, *C; + + B = A->right; + C = B->left; + A->right = C->left; + B->left = C->right; + C->left = A; + C->right = B; + + /* update balance of all touched nodes */ + /* reference: */ + + A->balance = (C->balance < 0) ? 0 : -(C->balance); + B->balance = (C->balance > 0) ? 0 : -(C->balance); + C->balance = 0; + + return C; } static int -avltree_insert_node(avltree_t *tree, avlnode_t **root, const char *key, const void *data) +avltree_insert_node(avltree_t* tree, avlnode_t** root, const char* key, const void* data) { - int changed = 0; - int compare; - avlnode_t *node = (*root); - - if (node == NULL) { - (*root) = node = (avlnode_t*) xcalloc(1, sizeof(*node)); - if (tree->options & AVLTREE_STATIC_KEYS) - node->key = key; - else - node->key = xstrdup(key); - node->data = data; - tree->count++; - return 1; /* anyway, our tree has been changed */ - } - - compare = tree->compare(key, node->key); - - if (compare < 0) { - if (avltree_insert_node(tree, &node->left, key, data)) { - changed = (--node->balance != 0); - switch(node->balance) { - case -2: - if (node->left->balance < 0) - node = avltree_left_rotation(node); - else - node = avltree_left_right_rotation(node); - (*root) = node; - case 0: - changed = 0; - case -1: - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - else - changed = 0; - } - else if (compare > 0) { - if (avltree_insert_node(tree, &node->right, key, data)) { - changed = (++node->balance != 0); - switch(node->balance) { - case +2: - if (node->right->balance > 0) - node = avltree_right_rotation(node); - else - node = avltree_right_left_rotation(node); - (*root) = node; - case 0: - changed = 0; - case +1: - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - else - changed = 0; - } - else { - if (tree->options & AVLTREE_PARANOIAC) - fatal("%s/%s.%d: Duplicate keys are not allowed (\"%s\")!\n", - tree->module, MYNAME, __LINE__, key); - changed = 0; - } - - return changed; + int changed = 0; + int compare; + avlnode_t* node = (*root); + + if (node == NULL) { + (*root) = node = (avlnode_t*) xcalloc(1, sizeof(*node)); + if (tree->options & AVLTREE_STATIC_KEYS) { + node->key = key; + } else { + node->key = xstrdup(key); + } + node->data = data; + tree->count++; + return 1; /* anyway, our tree has been changed */ + } + + compare = tree->compare(key, node->key); + + if (compare < 0) { + if (avltree_insert_node(tree, &node->left, key, data)) { + changed = (--node->balance != 0); + switch (node->balance) { + case -2: + if (node->left->balance < 0) { + node = avltree_left_rotation(node); + } else { + node = avltree_left_right_rotation(node); + } + (*root) = node; + case 0: + changed = 0; + case -1: + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } else { + changed = 0; + } + } else if (compare > 0) { + if (avltree_insert_node(tree, &node->right, key, data)) { + changed = (++node->balance != 0); + switch (node->balance) { + case +2: + if (node->right->balance > 0) { + node = avltree_right_rotation(node); + } else { + node = avltree_right_left_rotation(node); + } + (*root) = node; + case 0: + changed = 0; + case +1: + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } else { + changed = 0; + } + } else { + if (tree->options & AVLTREE_PARANOIAC) + fatal("%s/%s.%d: Duplicate keys are not allowed (\"%s\")!\n", + tree->module, MYNAME, __LINE__, key); + changed = 0; + } + + return changed; } static int -avltree_delete_node(avltree_t *tree, const char *key, avlnode_t **root, int *changed) +avltree_delete_node(avltree_t* tree, const char* key, avlnode_t** root, int* changed) { - avlnode_t *node = (*root); - int deleted = 0; - int compare; - - if (node == NULL) { - if (tree->options & AVLTREE_PARANOIAC) - fatal("%s/%s.%d: Key to delete \"%s\" not found!\n", - tree->module, MYNAME, __LINE__, key); - return 0; - } - - compare = tree->compare(key, node->key); - - if (compare < 0) { - deleted = avltree_delete_node(tree, key, &node->left, changed); - if (*changed) { - node->balance++; /* shift weight to right */ - switch(node->balance) { - case +1: - (*changed) = 0; /* stop rebalancing */ - case 0: - break; - case +2: - if (node->right->balance >= 0) - node = avltree_right_rotation(node); - else - node = avltree_right_left_rotation(node); - (*root) = node; - if (node->balance == -1) - (*changed) = 0; - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - } - else if (compare > 0) { - deleted = avltree_delete_node(tree, key, &node->right, changed); - if (*changed) { - node->balance--; /* shift weight to left */ - switch(node->balance) { - case -1: - (*changed) = 0; /* stop rebalancing */ - case 0: - break; - case -2: - if (node->left->balance <= 0) - node = avltree_left_rotation(node); - else - node = avltree_left_right_rotation(node); - (*root) = node; - if (node->balance == +1) - (*changed) = 0; - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - } - else { - if (node->left) { - if (node->right) { - const char *temp_key; - const void *temp_data; - avlnode_t *succ = node->right; - - while (succ->left) succ = succ->left; /* find successor */ - - temp_key = succ->key; /* swap contents */ - temp_data = succ->data; - succ->key = node->key; - succ->data = node->data; - node->key = temp_key; - node->data = temp_data; - - deleted = avltree_delete_node(tree, key, &node->right, changed); - - if (*changed) { - node->balance--; /* shift weight to left */ - switch(node->balance) { - case -1: - (*changed) = 0; /* stop rebalancing */ - case 0: - break; - case -2: - if (node->left->balance <= 0) - node = avltree_left_rotation(node); - else - node = avltree_left_right_rotation(node); - (*root) = node; - if (node->balance == +1) - (*changed) = 0; - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - return deleted; - } - else { /* only left branch */ - (*root) = node->left; - node->left = NULL; - } - } - else if (node->right) { /* only right branch */ - (*root) = node->right; - node->right = NULL; - } - else /* only a simple leaf */ - (*root) = NULL; - - avltree_node_free(tree, node); - tree->count--; - (*changed) = 1; - deleted = 1; - } - - return deleted; + avlnode_t* node = (*root); + int deleted = 0; + int compare; + + if (node == NULL) { + if (tree->options & AVLTREE_PARANOIAC) + fatal("%s/%s.%d: Key to delete \"%s\" not found!\n", + tree->module, MYNAME, __LINE__, key); + return 0; + } + + compare = tree->compare(key, node->key); + + if (compare < 0) { + deleted = avltree_delete_node(tree, key, &node->left, changed); + if (*changed) { + node->balance++; /* shift weight to right */ + switch (node->balance) { + case +1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case +2: + if (node->right->balance >= 0) { + node = avltree_right_rotation(node); + } else { + node = avltree_right_left_rotation(node); + } + (*root) = node; + if (node->balance == -1) { + (*changed) = 0; + } + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + } else if (compare > 0) { + deleted = avltree_delete_node(tree, key, &node->right, changed); + if (*changed) { + node->balance--; /* shift weight to left */ + switch (node->balance) { + case -1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case -2: + if (node->left->balance <= 0) { + node = avltree_left_rotation(node); + } else { + node = avltree_left_right_rotation(node); + } + (*root) = node; + if (node->balance == +1) { + (*changed) = 0; + } + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + } else { + if (node->left) { + if (node->right) { + const char* temp_key; + const void* temp_data; + avlnode_t* succ = node->right; + + while (succ->left) { + succ = succ->left; /* find successor */ + } + + temp_key = succ->key; /* swap contents */ + temp_data = succ->data; + succ->key = node->key; + succ->data = node->data; + node->key = temp_key; + node->data = temp_data; + + deleted = avltree_delete_node(tree, key, &node->right, changed); + + if (*changed) { + node->balance--; /* shift weight to left */ + switch (node->balance) { + case -1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case -2: + if (node->left->balance <= 0) { + node = avltree_left_rotation(node); + } else { + node = avltree_left_right_rotation(node); + } + (*root) = node; + if (node->balance == +1) { + (*changed) = 0; + } + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + return deleted; + } else { /* only left branch */ + (*root) = node->left; + node->left = NULL; + } + } else if (node->right) { /* only right branch */ + (*root) = node->right; + node->right = NULL; + } else { /* only a simple leaf */ + (*root) = NULL; + } + + avltree_node_free(tree, node); + tree->count--; + (*changed) = 1; + deleted = 1; + } + + return deleted; } -static avlnode_t * -avltree_dupe_node(const avltree_t *tree, const avlnode_t *node) +static avlnode_t* +avltree_dupe_node(const avltree_t* tree, const avlnode_t* node) { - avlnode_t *res = (avlnode_t*) xcalloc(1, sizeof(*res)); - - if (tree->options & AVLTREE_STATIC_KEYS) - res->key = node->key; - else - res->key = xstrdup(node->key); - - res->balance = node->balance; - if (node->left) - res->left = avltree_dupe_node(tree, node->left); - if (node->right) - res->right = avltree_dupe_node(tree, node->right); - - return res; + avlnode_t* res = (avlnode_t*) xcalloc(1, sizeof(*res)); + + if (tree->options & AVLTREE_STATIC_KEYS) { + res->key = node->key; + } else { + res->key = xstrdup(node->key); + } + + res->balance = node->balance; + if (node->left) { + res->left = avltree_dupe_node(tree, node->left); + } + if (node->right) { + res->right = avltree_dupe_node(tree, node->right); + } + + return res; } static int -avltree_strcmpr(const char *s1, const char *s2) +avltree_strcmpr(const char* s1, const char* s2) { - return -(strcmp(s1, s2)); + return -(strcmp(s1, s2)); } static int -avltree_case_ignore_strcmpr(const char *s1, const char *s2) +avltree_case_ignore_strcmpr(const char* s1, const char* s2) { - return -(case_ignore_strcmp(s1, s2)); + return -(case_ignore_strcmp(s1, s2)); } -static avlnode_t * -avltree_find_next(const avltree_t *tree, avlnode_t *node, const char *key) +static avlnode_t* +avltree_find_next(const avltree_t* tree, avlnode_t* node, const char* key) { - avlnode_t *prev = NULL; - - if (key == NULL) { - if ((node = tree->root)) { - while (node->left) - node = node->left; - } - return node; - } - - while (node) { - int compare = tree->compare(key, node->key); - - if (compare < 0) { - prev = node; - node = node->left; - } - else if (compare > 0) - node = node->right; - else { - if ((node = node->right)) - while (node->left) node = node->left; - else - node = prev; - return node; - } - } - /* The previous node was deleted and we could not find it. */ - return prev; + avlnode_t* prev = NULL; + + if (key == NULL) { + if ((node = tree->root)) { + while (node->left) { + node = node->left; + } + } + return node; + } + + while (node) { + int compare = tree->compare(key, node->key); + + if (compare < 0) { + prev = node; + node = node->left; + } else if (compare > 0) { + node = node->right; + } else { + if ((node = node->right)) + while (node->left) { + node = node->left; + } + else { + node = prev; + } + return node; + } + } + /* The previous node was deleted and we could not find it. */ + return prev; } /* Save [key] for a possible delete before next op. Now we have no problem with: - + curr = NULL; while ((curr = avtree_next(tree, curr, NULL))) { avltree_delete(tree, curr); } */ static void -avltree_save_key(avltree_t *tree, const char *key) +avltree_save_key(avltree_t* tree, const char* key) { - if (tree->options & AVLTREE_STATIC_KEYS) - tree->key = key; - else { - if (key == NULL) { - if (tree->key_sz) { - xfree((char *)tree->key); - tree->key_sz = 0; - } - tree->key = NULL; - } - else { - int n, n8; - - n = strlen(key) + 1; - n8 = ((n + 7) / 8) * 8; - - if (n8 > tree->key_sz) { - if (tree->key_sz == 0) - tree->key = xmalloc(n8); - else - tree->key = xrealloc((char *)tree->key, n8); - tree->key_sz = n8; - } - strncpy((char *)tree->key, key, n); - } - } + if (tree->options & AVLTREE_STATIC_KEYS) { + tree->key = key; + } else { + if (key == NULL) { + if (tree->key_sz) { + xfree((char*)tree->key); + tree->key_sz = 0; + } + tree->key = NULL; + } else { + int n, n8; + + n = strlen(key) + 1; + n8 = ((n + 7) / 8) * 8; + + if (n8 > tree->key_sz) { + if (tree->key_sz == 0) { + tree->key = (char*) xmalloc(n8); + } else { + tree->key = (char*) xrealloc((char*)tree->key, n8); + } + tree->key_sz = n8; + } + strncpy((char*)tree->key, key, n); + } + } } diff --git a/gpsbabel/avltree.h b/gpsbabel/avltree.h index 8df8ffb67..c08c3a8b3 100644 --- a/gpsbabel/avltree.h +++ b/gpsbabel/avltree.h @@ -1,7 +1,7 @@ /* AVL tree implementation. - + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -27,28 +27,27 @@ #include #include -typedef int (*avltree_compare_cb) (const char *, const char *); +typedef int (*avltree_compare_cb)(const char*, const char*); -typedef struct avltree_s -{ +typedef struct avltree_s { #ifdef MEM_DEBUG - const int magic; + const int magic; #endif - struct avlnode_s *root; - const char *module; - int count; /* number of items in tree */ - int options; - const char *key; - int key_sz; - avltree_compare_cb compare; + struct avlnode_s* root; + const char* module; + int count; /* number of items in tree */ + int options; + const char* key; + int key_sz; + avltree_compare_cb compare; } avltree_t; typedef struct avlnode_s { - int balance; - const char *key; - const void *data; - struct avlnode_s *left; - struct avlnode_s *right; + int balance; + const char* key; + const void* data; + struct avlnode_s* left; + struct avlnode_s* right; } avlnode_t; /* options for avltree_init */ @@ -61,37 +60,37 @@ typedef struct avlnode_s { #define AVLTREE_PARANOIAC 256 /* STOP on "duplicate key" (insert) or on "not found" (delete) */ /* Allocate and initialize an AVL Tree */ -avltree_t *avltree_init(const int options, const char *module); +avltree_t* avltree_init(const int options, const char* module); /* Destroy an AVL Tree */ -void avltree_done(avltree_t *tree); +void avltree_done(avltree_t* tree); /* Delete all items of tree [tree]; returns number of deleted items */ -int avltree_clear(avltree_t *tree); +int avltree_clear(avltree_t* tree); /* Get number of items in tree */ -int avltree_count(const avltree_t *tree); +int avltree_count(const avltree_t* tree); /* Delete item with key [key] */ -int avltree_delete(avltree_t *tree, const char *key); +int avltree_delete(avltree_t* tree, const char* key); /* Duplicate an existing tree */ -avltree_t *avltree_dupe(const avltree_t *tree, const char *module); +avltree_t* avltree_dupe(const avltree_t* tree, const char* module); /* Find key [key] in tree */ -int avltree_find(const avltree_t *tree, const char *key, const void **data); +int avltree_find(const avltree_t* tree, const char* key, const void** data); /* Get the first (the MIN-) entry of the tree */ -const char *avltree_first(const avltree_t *tree, const void **data); +const char* avltree_first(const avltree_t* tree, const void** data); /* Get the current height of the tree */ -int avltree_height(const avltree_t *tree); +int avltree_height(const avltree_t* tree); /* Insert key [key] and [data] into tree */ -int avltree_insert(avltree_t *tree, const char *key, const void *data); +int avltree_insert(avltree_t* tree, const char* key, const void* data); /* Get the next (the entry above [key]) */ -const char *avltree_next(const avltree_t *tree, const char *key, const void **data); +const char* avltree_next(const avltree_t* tree, const char* key, const void** data); #endif /* AVLTREE_H_INCLUDED */ diff --git a/gpsbabel/axim_gpb.c b/gpsbabel/axim_gpb.c index a931ba033..97fcf4bd8 100644 --- a/gpsbabel/axim_gpb.c +++ b/gpsbabel/axim_gpb.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include #include @@ -29,92 +29,92 @@ #define RECORD_LEN 344 -static gbfile *fin; +static gbfile* fin; static arglist_t axim_gpb_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static float -le_read32_float(const void *src) +le_read32_float(const void* src) { - float f; - gbint32 i; - - i = le_read32(src); - memcpy(&f, &i, 4); - - return f; + float f; + gbint32 i; + + i = le_read32(src); + memcpy(&f, &i, 4); + + return f; } static void -decode_buff(const char *buff, route_head *track) +decode_buff(const char* buff, route_head* track) { - struct tm tm; - double lat, lon, alt, dir; - float vdop, hdop, pdop, spd, Uf1; - int sats; - waypoint *wpt; - - wpt = waypt_new(); - - memset(&tm, '\0', sizeof(tm)); - - tm.tm_year = le_read16((void *) (buff + 16)); - tm.tm_mon = le_read16((void *) (buff + 18)); - tm.tm_mday = le_read16((void *) (buff + 22)); - tm.tm_hour = le_read16((void *) (buff + 24)); - tm.tm_min = le_read16((void *) (buff + 26)); - tm.tm_sec = le_read16((void *) (buff + 28)); - lat = le_read_double( (void *) (buff + 32)); - lon = le_read_double( (void *) (buff + 40)); - spd = le_read32_float((void *) (buff + 48)); - dir = le_read32_float((void *) (buff + 52)); - - alt = le_read32_float((void *) (buff + 64)); - Uf1 = le_read32_float((void *) (buff + 68)); - - hdop = le_read32_float((void *) (buff + 84)); - vdop = le_read32_float((void *) (buff + 88)); - pdop = le_read32_float((void *) (buff + 92)); - sats = le_read16((void *) (buff + 96)); - - wpt->latitude = lat; - wpt->longitude = lon; - wpt->altitude = alt; + struct tm tm; + double lat, lon, alt, dir; + float vdop, hdop, pdop, spd, Uf1; + int sats; + waypoint* wpt; + + wpt = waypt_new(); + + memset(&tm, '\0', sizeof(tm)); + + tm.tm_year = le_read16((void*)(buff + 16)); + tm.tm_mon = le_read16((void*)(buff + 18)); + tm.tm_mday = le_read16((void*)(buff + 22)); + tm.tm_hour = le_read16((void*)(buff + 24)); + tm.tm_min = le_read16((void*)(buff + 26)); + tm.tm_sec = le_read16((void*)(buff + 28)); + lat = le_read_double((void*)(buff + 32)); + lon = le_read_double((void*)(buff + 40)); + spd = le_read32_float((void*)(buff + 48)); + dir = le_read32_float((void*)(buff + 52)); + + alt = le_read32_float((void*)(buff + 64)); + Uf1 = le_read32_float((void*)(buff + 68)); + + hdop = le_read32_float((void*)(buff + 84)); + vdop = le_read32_float((void*)(buff + 88)); + pdop = le_read32_float((void*)(buff + 92)); + sats = le_read16((void*)(buff + 96)); + + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; #if 0 - /* These values can be, but must not be right. */ - /* Further checks are needed to verify that. */ - /* (!!! reference data !!!) */ - WAYPT_SET(wpt, course, dir); - wpt->hdop = hdop; - wpt->vdop = vdop; - wpt->pdop = pdop; - wpt->sat = sats; - WAYPT_SET(wpt, speed, spd * 10); + /* These values can be, but must not be right. */ + /* Further checks are needed to verify that. */ + /* (!!! reference data !!!) */ + WAYPT_SET(wpt, course, dir); + wpt->hdop = hdop; + wpt->vdop = vdop; + wpt->pdop = pdop; + wpt->sat = sats; + WAYPT_SET(wpt, speed, spd * 10); #endif - /* We don't have a header with some magic fixed numbers or strings. */ - /* So let us check the range for some basic values */ - - is_fatal( - (tm.tm_year < 2005) || - (tm.tm_mon < 1) || (tm.tm_mon > 12) || - (tm.tm_mday < 1) || (tm.tm_mday > 31) || - (tm.tm_hour > 23) || (tm.tm_min > 60) || (tm.tm_sec > 60), - MYNAME ": Invalid or unsupported file (invalid time-stamp)."); - is_fatal( - (fabs(wpt->latitude) > 90) || - (fabs(wpt->longitude) > 180), - MYNAME ": Invalid or unsupported file (lat or/and lon out of range)."); - - /* post work */ - - tm.tm_year-=1900; - tm.tm_mon--; - wpt->creation_time = mkgmtime(&tm); - - track_add_wpt(track, wpt); + /* We don't have a header with some magic fixed numbers or strings. */ + /* So let us check the range for some basic values */ + + is_fatal( + (tm.tm_year < 2005) || + (tm.tm_mon < 1) || (tm.tm_mon > 12) || + (tm.tm_mday < 1) || (tm.tm_mday > 31) || + (tm.tm_hour > 23) || (tm.tm_min > 60) || (tm.tm_sec > 60), + MYNAME ": Invalid or unsupported file (invalid time-stamp)."); + is_fatal( + (fabs(wpt->latitude) > 90) || + (fabs(wpt->longitude) > 180), + MYNAME ": Invalid or unsupported file (lat or/and lon out of range)."); + + /* post work */ + + tm.tm_year-=1900; + tm.tm_mon--; + wpt->creation_time = mkgmtime(&tm); + + track_add_wpt(track, wpt); } /******************************************************************************* @@ -122,53 +122,51 @@ decode_buff(const char *buff, route_head *track) *******************************************************************************/ static void -axim_gpb_rd_init(const char *fname) +axim_gpb_rd_init(const char* fname) { - fin = gbfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } -static void +static void axim_gpb_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void axim_gpb_read(void) { - char buff[RECORD_LEN]; - route_head *track = NULL; - size_t bytes; - - while ((bytes = gbfread(buff, 1, RECORD_LEN, fin))) - { - is_fatal((bytes != RECORD_LEN), MYNAME ": Invalid or unsupported file (filesize)."); - if (track == NULL) - { - track = route_head_alloc(); - track_add_head(track); - } - decode_buff(buff, track); - } + char buff[RECORD_LEN]; + route_head* track = NULL; + size_t bytes; + + while ((bytes = gbfread(buff, 1, RECORD_LEN, fin))) { + is_fatal((bytes != RECORD_LEN), MYNAME ": Invalid or unsupported file (filesize)."); + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + } + decode_buff(buff, track); + } } /**************************************************************************/ ff_vecs_t axim_gpb_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */, - }, - axim_gpb_rd_init, - NULL, - axim_gpb_rd_deinit, - NULL, - axim_gpb_read, - NULL, - NULL, - axim_gpb_args, - CET_CHARSET_ASCII, 0 + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */, + }, + axim_gpb_rd_init, + NULL, + axim_gpb_rd_deinit, + NULL, + axim_gpb_read, + NULL, + NULL, + axim_gpb_args, + CET_CHARSET_ASCII, 0 }; /**************************************************************************/ diff --git a/gpsbabel/bcr.c b/gpsbabel/bcr.c index 6694a6b7b..5561e379a 100644 --- a/gpsbabel/bcr.c +++ b/gpsbabel/bcr.c @@ -39,200 +39,218 @@ #define MYNAME "bcr" #undef BCR_DEBUG - + #define R_EARTH 6371000 /* radius of our big blue ball */ #define BCR_DEF_ICON "Standort" #define BCR_DEF_MPS_ICON "Waypoint" #define BCR_UNKNOWN (double) 999999999 -/* +/* 6371014 would be a better value when converting to f.e. to mapsoure, - but this seems to be used by Map&Guide when exporting to XML. + but this seems to be used by Map&Guide when exporting to XML. */ -static gbfile *fout; -static char *filename; +static gbfile* fout; +static char* filename; static int curr_rte_num, target_rte_num; static double radius; -static inifile_t *ini; +static inifile_t* ini; /* placeholders for options */ -static char *rtenum_opt; -static char *rtename_opt; -static char *radius_opt; -static char *prefer_shortnames_opt; +static char* rtenum_opt; +static char* rtename_opt; +static char* radius_opt; +static char* prefer_shortnames_opt; static arglist_t bcr_args[] = { - {"index", &rtenum_opt, "Index of route to write (if more than one in source)", - NULL, ARGTYPE_INT, "1", NULL }, - {"name", &rtename_opt, "New name for the route", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", "6371000", - ARGTYPE_FLOAT, ARG_NOMINMAX }, - {"prefer_shortnames", &prefer_shortnames_opt, "Use shortname instead of description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "index", &rtenum_opt, "Index of route to write (if more than one in source)", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "name", &rtename_opt, "New name for the route", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", "6371000", + ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "prefer_shortnames", &prefer_shortnames_opt, "Use shortname instead of description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; typedef struct { - const char *bcr_name; - const char *mps_name; - const char *symbol_DE; - int warned; + const char* bcr_name; + const char* mps_name; + const char* symbol_DE; + int warned; } bcr_icon_mapping_t; static bcr_icon_mapping_t bcr_icon_mapping[] = { - { BCR_DEF_ICON, BCR_DEF_MPS_ICON, BCR_DEF_ICON }, - { "", BCR_DEF_MPS_ICON, "Eigene Adressen" }, - { "AdrMon alpen", "Summit", "Pass-Strassen" }, - { "AdrMon bauern", NULL, "Bauern- und Biohoefe" }, - { "AdrMon cmpngs", "Campground", "Campingplaetzte" }, - { "AdrMon p_aeu", "Scenic Area", "Sehenswertes" }, - { "AdrMon p_beu", "Gas Station", "Tanken" }, - { "AdrMon p_deu", "Parking Area", "Parken" }, - { "AdrMon p_feu", "Restaurant", "Gastro" }, - { "AdrMon p_geu", "Museum", "Freizeit" }, - { "AdrMon p_heu", "Gas Station", "Tankstellen" }, - { "AdrMon p_keu", NULL, "Faehrverbindungen" }, - { "AdrMon p_leu", NULL, "Grenzuebergaenge" }, - { "AdrMon p_teu", NULL, "Wein- und Sektgueter" }, - { "AdrMon RUINEN", "Ghost Town", "Burgen und Schloesser" }, - { "AdrMon NFHAUS", "Residence", "Naturfreundehaeuser" }, - { "AdrMon racing", "Bike Trail", "Rennstrecken" }, - { "AdrMon TNKRST", "Bar", "Tankraststaetten" }, - { "AdrMon tpclub", "Contact, Biker", "Motorrad-Clubs" }, - { "AdrMon tpequ", NULL, "Motorrad-Equipment" }, - { "AdrMon tphot", "Hotel", "Motorrad-Hotels" }, - { "AdrMon tpmh", NULL, "Motorradhaendler" }, - { "AdrMon tpss", "Restricted Area", "Sperrungen" }, - { "AdrMon tpsw", "Scenic Area", "Sehenswertes" }, - { "AdrMon tptref", NULL, "Treffpunkte" }, - { "AdrMon VORTE", "Information", "Ortsinformationen" }, - { "AdrMon WEBCAM", NULL, "WebCam-Standorte" }, - { "AdrMon youthh", NULL, "Jugendherbergen" }, - { "Town", "City (Small)", "Orte" }, - { NULL, NULL, NULL, 0 } + { BCR_DEF_ICON, BCR_DEF_MPS_ICON, BCR_DEF_ICON }, + { "", BCR_DEF_MPS_ICON, "Eigene Adressen" }, + { "AdrMon alpen", "Summit", "Pass-Strassen" }, + { "AdrMon bauern", NULL, "Bauern- und Biohoefe" }, + { "AdrMon cmpngs", "Campground", "Campingplaetzte" }, + { "AdrMon p_aeu", "Scenic Area", "Sehenswertes" }, + { "AdrMon p_beu", "Gas Station", "Tanken" }, + { "AdrMon p_deu", "Parking Area", "Parken" }, + { "AdrMon p_feu", "Restaurant", "Gastro" }, + { "AdrMon p_geu", "Museum", "Freizeit" }, + { "AdrMon p_heu", "Gas Station", "Tankstellen" }, + { "AdrMon p_keu", NULL, "Faehrverbindungen" }, + { "AdrMon p_leu", NULL, "Grenzuebergaenge" }, + { "AdrMon p_teu", NULL, "Wein- und Sektgueter" }, + { "AdrMon RUINEN", "Ghost Town", "Burgen und Schloesser" }, + { "AdrMon NFHAUS", "Residence", "Naturfreundehaeuser" }, + { "AdrMon racing", "Bike Trail", "Rennstrecken" }, + { "AdrMon TNKRST", "Bar", "Tankraststaetten" }, + { "AdrMon tpclub", "Contact, Biker", "Motorrad-Clubs" }, + { "AdrMon tpequ", NULL, "Motorrad-Equipment" }, + { "AdrMon tphot", "Hotel", "Motorrad-Hotels" }, + { "AdrMon tpmh", NULL, "Motorradhaendler" }, + { "AdrMon tpss", "Restricted Area", "Sperrungen" }, + { "AdrMon tpsw", "Scenic Area", "Sehenswertes" }, + { "AdrMon tptref", NULL, "Treffpunkte" }, + { "AdrMon VORTE", "Information", "Ortsinformationen" }, + { "AdrMon WEBCAM", NULL, "WebCam-Standorte" }, + { "AdrMon youthh", NULL, "Jugendherbergen" }, + { "Town", "City (Small)", "Orte" }, + { NULL, NULL, NULL, 0 } }; static void -bcr_handle_icon_str(const char *str, waypoint *wpt) +bcr_handle_icon_str(const char* str, waypoint* wpt) { - bcr_icon_mapping_t *m; - - wpt->icon_descr = BCR_DEF_MPS_ICON; - - for (m = bcr_icon_mapping; (m->bcr_name); m++) { - if (case_ignore_strcmp(str, m->bcr_name) == 0) { - int nr; - - if (m->symbol_DE == NULL) { - if (! m->warned) { - m->warned = 1; - warning(MYNAME ": Unknown icon \"%s\" found. Please report.\n", str); - } - return; - } - wpt->description = xstrdup(m->symbol_DE); - if (m->mps_name != NULL) { - nr = gt_find_icon_number_from_desc(m->mps_name, MAPSOURCE); - wpt->icon_descr = gt_find_desc_from_icon_number(nr, MAPSOURCE, NULL); - } - return; - } - } + bcr_icon_mapping_t* m; + + wpt->icon_descr = BCR_DEF_MPS_ICON; + + for (m = bcr_icon_mapping; (m->bcr_name); m++) { + if (case_ignore_strcmp(str, m->bcr_name) == 0) { + int nr; + + if (m->symbol_DE == NULL) { + if (! m->warned) { + m->warned = 1; + warning(MYNAME ": Unknown icon \"%s\" found. Please report.\n", str); + } + return; + } + wpt->description = xstrdup(m->symbol_DE); + if (m->mps_name != NULL) { + nr = gt_find_icon_number_from_desc(m->mps_name, MAPSOURCE); + wpt->icon_descr = gt_find_desc_from_icon_number(nr, MAPSOURCE, NULL); + } + return; + } + } } -static const char * -get_bcr_icon_from_icon_descr(const char *icon_descr) +static const char* +get_bcr_icon_from_icon_descr(const char* icon_descr) { - const char *result = BCR_DEF_ICON; - - if (icon_descr) { - bcr_icon_mapping_t *m; - - for (m = bcr_icon_mapping; (m->bcr_name); m++) { - if (! m->mps_name) continue; - if (case_ignore_strcmp(icon_descr, m->mps_name) == 0) { - result = m->bcr_name; - break; - } - } - } - return result; + const char* result = BCR_DEF_ICON; + + if (icon_descr) { + bcr_icon_mapping_t* m; + + for (m = bcr_icon_mapping; (m->bcr_name); m++) { + if (! m->mps_name) { + continue; + } + if (case_ignore_strcmp(icon_descr, m->mps_name) == 0) { + result = m->bcr_name; + break; + } + } + } + return result; } static void bcr_init_radius(void) { - if (radius_opt != NULL) /* preinitialize the earth radius */ - { - radius = atof(radius_opt); - if (radius <= 0) - fatal(MYNAME ": Sorry, the radius should be greater than zero!\n"); - } - else - radius = (double)R_EARTH; - - if (global_opts.verbose_status > 0) - printf(MYNAME ": We calculate with radius %f meters.\n", radius); + if (radius_opt != NULL) { /* preinitialize the earth radius */ + radius = atof(radius_opt); + if (radius <= 0) { + fatal(MYNAME ": Sorry, the radius should be greater than zero!\n"); + } + } else { + radius = (double)R_EARTH; + } + + if (global_opts.verbose_status > 0) { + printf(MYNAME ": We calculate with radius %f meters.\n", radius); + } } static void -bcr_rd_init(const char *fname) +bcr_rd_init(const char* fname) { - filename = xstrdup(fname); - ini = inifile_init(fname, MYNAME); - if (ini->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - bcr_init_radius(); + filename = xstrdup(fname); + ini = inifile_init(fname, MYNAME); + if (ini->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + bcr_init_radius(); } static void bcr_rd_deinit(void) { - inifile_done(ini); - xfree(filename); + inifile_done(ini); + xfree(filename); } /* ------------------------------------------------------------*/ static void -bcr_create_waypts_from_route(route_head *route) +bcr_create_waypts_from_route(route_head* route) { - waypoint *wpt; - queue *elem, *tmp; - - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - wpt = waypt_dupe((waypoint *) elem); - waypt_add(wpt); - } + waypoint* wpt; + queue* elem, *tmp; + + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { + wpt = waypt_dupe((waypoint*) elem); + waypt_add(wpt); + } } static void -bcr_wgs84_to_mercator(const double lat, const double lon, int *north, int *east) +bcr_wgs84_to_mercator(const double lat, const double lon, int* north, int* east) { - double N, E; - - N = log(tan(lat * M_PI / 360 + M_PI / 4)) * radius; - E = lon * radius * M_PI / (double)180; - - if (lat > 0) N += 0.500000000001; /* we go from double to integer */ - else N -= 0.500000000001; /* it's time to round a little bit */ - if (lon > 0) E += 0.500000000001; - else E -= 0.500000000001; - - *north = N; - *east = E; + double N, E; + + N = log(tan(lat * M_PI / 360 + M_PI / 4)) * radius; + E = lon * radius * M_PI / (double)180; + + if (lat > 0) { + N += 0.500000000001; /* we go from double to integer */ + } else { + N -= 0.500000000001; /* it's time to round a little bit */ + } + if (lon > 0) { + E += 0.500000000001; + } else { + E -= 0.500000000001; + } + + *north = N; + *east = E; } void -bcr_mercator_to_wgs84(const int north, const int east, double *lat, double *lon) +bcr_mercator_to_wgs84(const int north, const int east, double* lat, double* lon) { - *lat = 2 * (atan(exp(north / radius)) - M_PI / 4) / M_PI * (double)180; - *lon = (double)east * (double)180 / (radius * M_PI); + *lat = 2 * (atan(exp(north / radius)) - M_PI / 4) / M_PI * (double)180; + *lon = (double)east * (double)180 / (radius * M_PI); } /* ------------------------------------------------------------- */ @@ -240,247 +258,277 @@ bcr_mercator_to_wgs84(const int north, const int east, double *lat, double *lon) static void bcr_data_read(void) { - int index; - char *str; - route_head *route; - - route = route_head_alloc(); - - if ((str = inifile_readstr(ini, "client", "routename"))) - route->rte_name = xstrdup(str); - - route_add_head(route); - - for (index = 1; index > 0; index ++) { - - char station[32]; - char *str; - int mlat, mlon; /* mercator data */ - waypoint *wpt; - - snprintf(station, sizeof(station), "STATION%d", index); - if (NULL == (str = inifile_readstr(ini, "coordinates", station))) break; - - if (2 != sscanf(str, "%d,%d", &mlon, &mlat)) - fatal(MYNAME ": structure error at %s (Coordinates)!\n", station); - - wpt = waypt_new(); - - wpt->shortname = xstrdup(station); - bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude); - - if (NULL != (str = inifile_readstr(ini, "client", station))) - { - char *cx; - - cx = strchr(str, ','); - if (cx == NULL) - fatal(MYNAME ": structure error at %s (Client)!\n", station); - *cx++ = '\0'; - bcr_handle_icon_str(str, wpt); - } - - if (NULL != (str = inifile_readstr(ini, "description", station))) { - char *c; - - c = strchr(str, ','); - if (c != NULL) *c = '\0'; - if (*str) wpt->notes = xstrdup(str); - if ((str = c)) { - str++; - c = strchr(str, ','); - if (c != NULL) *c = '\0'; - if (*str) { - xfree(wpt->shortname); - wpt->shortname = xstrdup(str); - } - } - } - - route_add_wpt(route, wpt); - } - - /* remove empty route */ - if (route->rte_waypt_ct == 0) - route_del_head(route); - else - bcr_create_waypts_from_route(route); + int index; + char* str; + route_head* route; + + route = route_head_alloc(); + + if ((str = inifile_readstr(ini, "client", "routename"))) { + route->rte_name = xstrdup(str); + } + + route_add_head(route); + + for (index = 1; index > 0; index ++) { + + char station[32]; + char* str; + int mlat, mlon; /* mercator data */ + waypoint* wpt; + + snprintf(station, sizeof(station), "STATION%d", index); + if (NULL == (str = inifile_readstr(ini, "coordinates", station))) { + break; + } + + if (2 != sscanf(str, "%d,%d", &mlon, &mlat)) { + fatal(MYNAME ": structure error at %s (Coordinates)!\n", station); + } + + wpt = waypt_new(); + + wpt->shortname = xstrdup(station); + bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude); + + if (NULL != (str = inifile_readstr(ini, "client", station))) { + char* cx; + + cx = strchr(str, ','); + if (cx == NULL) { + fatal(MYNAME ": structure error at %s (Client)!\n", station); + } + *cx++ = '\0'; + bcr_handle_icon_str(str, wpt); + } + + if (NULL != (str = inifile_readstr(ini, "description", station))) { + char* c; + + c = strchr(str, ','); + if (c != NULL) { + *c = '\0'; + } + if (*str) { + wpt->notes = xstrdup(str); + } + if ((str = c)) { + str++; + c = strchr(str, ','); + if (c != NULL) { + *c = '\0'; + } + if (*str) { + xfree(wpt->shortname); + wpt->shortname = xstrdup(str); + } + } + } + + route_add_wpt(route, wpt); + } + + /* remove empty route */ + if (route->rte_waypt_ct == 0) { + route_del_head(route); + } else { + bcr_create_waypts_from_route(route); + } } /* %%% bcr write support %%% ----------------------------------- */ static void -bcr_wr_init(const char *fname) +bcr_wr_init(const char* fname) { - filename = xstrdup(fname); - fout = gbfopen(fname, "wb", MYNAME); - bcr_init_radius(); + filename = xstrdup(fname); + fout = gbfopen(fname, "wb", MYNAME); + bcr_init_radius(); } static void bcr_wr_deinit(void) { - gbfclose(fout); - xfree(filename); + gbfclose(fout); + xfree(filename); } -static void -bcr_route_trailer(const route_head *rte) +static void +bcr_route_trailer(const route_head* rte) { } static void -bcr_write_wpt(const waypoint *wpt) +bcr_write_wpt(const waypoint* wpt) { } -void bcr_write_line(gbfile *fout, const char *key, int *index, const char *value) +void bcr_write_line(gbfile* fout, const char* key, int* index, const char* value) { - if (value == NULL) /* this is mostly used in the world of windows */ - { /* so we respectfully add a CR/LF on each line */ - gbfprintf(fout, "%s\r\n", key); - } - else - { - char *tmp; - - tmp = (value != NULL) ? xstrdup(value) : xstrdup(""); - if (index != NULL) - gbfprintf(fout, "%s%d=%s\r\n", key, *index, tmp); - else - gbfprintf(fout, "%s=%s\r\n", key, tmp); - xfree(tmp); - } + if (value == NULL) { /* this is mostly used in the world of windows */ + /* so we respectfully add a CR/LF on each line */ + gbfprintf(fout, "%s\r\n", key); + } else { + char* tmp; + + tmp = (value != NULL) ? xstrdup(value) : xstrdup(""); + if (index != NULL) { + gbfprintf(fout, "%s%d=%s\r\n", key, *index, tmp); + } else { + gbfprintf(fout, "%s=%s\r\n", key, tmp); + } + xfree(tmp); + } } -static void -bcr_route_header(const route_head *route) +static void +bcr_route_header(const route_head* route) { - queue *elem, *tmp; - waypoint *wpt; - char *sout; - int i, north, east, nmin, nmax, emin, emax; - - curr_rte_num++; - if (curr_rte_num != target_rte_num) return; - - bcr_write_line(fout, "[CLIENT]", NULL, NULL); /* client section */ - bcr_write_line(fout, "REQUEST", NULL, "TRUE"); - - sout = route->rte_name; - if (rtename_opt != 0) sout = rtename_opt; - if (sout != NULL) - bcr_write_line(fout, "ROUTENAME", NULL, sout); - else - bcr_write_line(fout, "ROUTENAME", NULL, "Route"); - - bcr_write_line(fout, "DESCRIPTIONLINES", NULL, "0"); - - i = 0; - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - const char *icon; - waypoint *wpt = (waypoint *) elem; - - i++; - - icon = get_bcr_icon_from_icon_descr(wpt->icon_descr); - - xasprintf(&sout, "%s,%.f", icon, BCR_UNKNOWN); - bcr_write_line(fout, "STATION", &i, sout); - xfree(sout); - } - - bcr_write_line(fout, "[COORDINATES]", NULL, NULL); /* coords section */ - - nmin = emin = (1<<30); - emax = nmax = -nmin; - - i = 0; - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - i++; - wpt = (waypoint *) elem; - - bcr_wgs84_to_mercator(wpt->latitude, wpt->longitude, &north, &east); - - if (north > nmax) nmax = north; - if (east > emax) emax = east; - if (north < nmin) nmin = north; - if (east < emin) emin = east; - - xasprintf(&sout, "%d,%d", east, north); - bcr_write_line(fout, "STATION", &i, sout); - xfree(sout); - } - - bcr_write_line(fout, "[DESCRIPTION]", NULL, NULL); /* descr. section */ - - i = 0; - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - char *s1, *s2, *sout; - - i++; - wpt = (waypoint *) elem; - s1 = wpt->notes; - if (s1 == NULL) s1 = wpt->description; - - if (prefer_shortnames_opt || (s1 == NULL) || (*s1 == '\0')) { - s2 = s1; - s1 = wpt->shortname; - } - else s2 = wpt->shortname; - - if (s1 == NULL) s1 = xstrdup(""); - else s1 = csv_stringclean(s1, ",\t\r\n"); - if (s2 == NULL) s2 = xstrdup(""); - else s2 = csv_stringclean(s2, ",\t\r\n"); - - if (*s2) - xasprintf(&sout, "%s,%s,@,0", s1, s2); - else - xasprintf(&sout, "%s,%s,@,0", s1, s1); - bcr_write_line(fout, "STATION", &i, sout); - - xfree(s1); - xfree(s2); - xfree(sout); - } - - bcr_write_line(fout, "[ROUTE]", NULL, NULL); /* route section */ - - xasprintf(&sout, "%d,%d,%d,%d", emin, nmax, emax, nmin); - bcr_write_line(fout, "ROUTERECT", NULL, sout); - xfree(sout); - + queue* elem, *tmp; + waypoint* wpt; + char* sout; + int i, north, east, nmin, nmax, emin, emax; + + curr_rte_num++; + if (curr_rte_num != target_rte_num) { + return; + } + + bcr_write_line(fout, "[CLIENT]", NULL, NULL); /* client section */ + bcr_write_line(fout, "REQUEST", NULL, "TRUE"); + + sout = route->rte_name; + if (rtename_opt != 0) { + sout = rtename_opt; + } + if (sout != NULL) { + bcr_write_line(fout, "ROUTENAME", NULL, sout); + } else { + bcr_write_line(fout, "ROUTENAME", NULL, "Route"); + } + + bcr_write_line(fout, "DESCRIPTIONLINES", NULL, "0"); + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { + const char* icon; + waypoint* wpt = (waypoint*) elem; + + i++; + + icon = get_bcr_icon_from_icon_descr(wpt->icon_descr); + + xasprintf(&sout, "%s,%.f", icon, BCR_UNKNOWN); + bcr_write_line(fout, "STATION", &i, sout); + xfree(sout); + } + + bcr_write_line(fout, "[COORDINATES]", NULL, NULL); /* coords section */ + + nmin = emin = (1<<30); + emax = nmax = -nmin; + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { + i++; + wpt = (waypoint*) elem; + + bcr_wgs84_to_mercator(wpt->latitude, wpt->longitude, &north, &east); + + if (north > nmax) { + nmax = north; + } + if (east > emax) { + emax = east; + } + if (north < nmin) { + nmin = north; + } + if (east < emin) { + emin = east; + } + + xasprintf(&sout, "%d,%d", east, north); + bcr_write_line(fout, "STATION", &i, sout); + xfree(sout); + } + + bcr_write_line(fout, "[DESCRIPTION]", NULL, NULL); /* descr. section */ + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { + char* s1, *s2, *sout; + + i++; + wpt = (waypoint*) elem; + s1 = wpt->notes; + if (s1 == NULL) { + s1 = wpt->description; + } + + if (prefer_shortnames_opt || (s1 == NULL) || (*s1 == '\0')) { + s2 = s1; + s1 = wpt->shortname; + } else { + s2 = wpt->shortname; + } + + if (s1 == NULL) { + s1 = xstrdup(""); + } else { + s1 = csv_stringclean(s1, ",\t\r\n"); + } + if (s2 == NULL) { + s2 = xstrdup(""); + } else { + s2 = csv_stringclean(s2, ",\t\r\n"); + } + + if (*s2) { + xasprintf(&sout, "%s,%s,@,0", s1, s2); + } else { + xasprintf(&sout, "%s,%s,@,0", s1, s1); + } + bcr_write_line(fout, "STATION", &i, sout); + + xfree(s1); + xfree(s2); + xfree(sout); + } + + bcr_write_line(fout, "[ROUTE]", NULL, NULL); /* route section */ + + xasprintf(&sout, "%d,%d,%d,%d", emin, nmax, emax, nmin); + bcr_write_line(fout, "ROUTERECT", NULL, sout); + xfree(sout); + } static void bcr_data_write(void) { - target_rte_num = 1; - - if (rtenum_opt != NULL) { - target_rte_num = atoi(rtenum_opt); - if (((unsigned)target_rte_num > route_count()) || (target_rte_num < 1)) - fatal(MYNAME ": invalid route number %d (1..%d))!\n", - target_rte_num, route_count()); - } - curr_rte_num = 0; - route_disp_all(bcr_route_header, bcr_route_trailer, bcr_write_wpt); + target_rte_num = 1; + + if (rtenum_opt != NULL) { + target_rte_num = atoi(rtenum_opt); + if (((unsigned)target_rte_num > route_count()) || (target_rte_num < 1)) + fatal(MYNAME ": invalid route number %d (1..%d))!\n", + target_rte_num, route_count()); + } + curr_rte_num = 0; + route_disp_all(bcr_route_header, bcr_route_trailer, bcr_write_wpt); } ff_vecs_t bcr_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, - bcr_rd_init, - bcr_wr_init, - bcr_rd_deinit, - bcr_wr_deinit, - bcr_data_read, - bcr_data_write, - NULL, - bcr_args, - CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write)}, + bcr_rd_init, + bcr_wr_init, + bcr_rd_deinit, + bcr_wr_deinit, + bcr_data_read, + bcr_data_write, + NULL, + bcr_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/bend.c b/gpsbabel/bend.c new file mode 100644 index 000000000..78610fc56 --- /dev/null +++ b/gpsbabel/bend.c @@ -0,0 +1,218 @@ +/* + Add route points before and after a bend. + + Copyright (C) 2011 Fernando Arbeiza, fernando.arbeiza@gmail.com + Copyright (C) 2011 Robert Lipe, robertlipe@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" + +#include "grtcirc.h" + +#include + +#define MYNAME "bend" + +#if FILTERS_ENABLED + +static char* distopt = NULL; +static char* minangleopt = NULL; + +static double maxDist; +static double minAngle; + +static queue* routes_orig = NULL; +static int routes_orig_num = 0; + +static +arglist_t bend_args[] = { + { + "distance", &distopt, "Distance to the bend in meters where the new points will be added", + "25", ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "minangle", &minangleopt, "Minimum bend angle in degrees", "5", + ARGTYPE_FLOAT, ARG_NOMINMAX + }, + ARG_TERMINATOR +}; + +static void +bend_init(const char* args) +{ + maxDist = 0.0; + if (distopt) { + maxDist = strtod(distopt, NULL); + } + + minAngle = 0.0; + if (minangleopt) { + minAngle = strtod(minangleopt, NULL); + } + + route_backup(&routes_orig_num, &routes_orig); + route_flush_all_routes(); +} + +static waypoint* +create_wpt_dest(const waypoint* wpt_orig, double lat_orig, + double long_orig, double lat_orig_adj, double long_orig_adj) +{ + double distance = gcdist(lat_orig, long_orig, + lat_orig_adj, long_orig_adj); + double frac; + double lat_dest; + double long_dest; + waypoint* wpt_dest = NULL; + distance = radtometers(distance); + if (distance <= maxDist) { + return NULL; + } + + frac = maxDist / distance; + + linepart(lat_orig, long_orig, lat_orig_adj, long_orig_adj, frac, + &lat_dest, &long_dest); + + wpt_dest = waypt_dupe(wpt_orig); + wpt_dest->latitude = DEG(lat_dest); + wpt_dest->longitude = DEG(long_dest); + + return wpt_dest; +} + +static int +is_small_angle(double lat_orig, double long_orig, double lat_orig_prev, + double long_orig_prev, double lat_orig_next, + double long_orig_next) +{ + double heading_prev = heading_true_degrees(lat_orig, long_orig, + lat_orig_prev, long_orig_prev); + double heading_next = heading_true_degrees(lat_orig, long_orig, + lat_orig_next, long_orig_next); + + double heading_diff = heading_next - heading_prev; + + return ((abs(heading_diff - 0.0) < minAngle) + || (abs(heading_diff - 180.0) < minAngle) + || (abs(heading_diff - 360.0) < minAngle)); +} + +static void +process_route(const route_head* route_orig, route_head* route_dest) +{ + waypoint* wpt_orig_prev = NULL; + waypoint* wpt_orig = NULL; + + queue* elem, *tmp; + QUEUE_FOR_EACH(&route_orig->waypoint_list, elem, tmp) { + waypoint* wpt_orig_next = (waypoint*)elem; + + if (wpt_orig_prev == NULL) { + if (wpt_orig != NULL) { + waypoint* waypoint_dest = waypt_dupe(wpt_orig); + route_add_wpt(route_dest, waypoint_dest); + } + } else { + double lat_orig = RAD(wpt_orig->latitude); + double long_orig = RAD(wpt_orig->longitude); + + double lat_orig_prev = RAD(wpt_orig_prev->latitude); + double long_orig_prev = RAD(wpt_orig_prev->longitude); + + double lat_orig_next = RAD(wpt_orig_next->latitude); + double long_orig_next = RAD(wpt_orig_next->longitude); + waypoint* wpt_dest_next = NULL; + + if (is_small_angle(lat_orig, long_orig, lat_orig_prev, + long_orig_prev, lat_orig_next, long_orig_next)) { + waypoint* waypoint_dest = waypt_dupe(wpt_orig); + route_add_wpt(route_dest, waypoint_dest); + } else { + waypoint* wpt_dest_prev = create_wpt_dest(wpt_orig, + lat_orig, long_orig, lat_orig_prev, long_orig_prev); + if (wpt_dest_prev != NULL) { + route_add_wpt(route_dest, wpt_dest_prev); + } + + wpt_dest_next = create_wpt_dest(wpt_orig, + lat_orig, long_orig, lat_orig_next, long_orig_next); + if (wpt_dest_next != NULL) { + route_add_wpt(route_dest, wpt_dest_next); + + wpt_orig = wpt_dest_next; + } + } + } + + wpt_orig_prev = wpt_orig; + wpt_orig = wpt_orig_next; + } + + if (wpt_orig != NULL) { + waypoint* waypoint_dest = waypt_dupe(wpt_orig); + route_add_wpt(route_dest, waypoint_dest); + } +} + +static void +process_route_orig(const route_head* route_orig) +{ + route_head* route_dest = route_head_alloc(); + route_dest->rte_name = xstrdup(route_orig->rte_name); + route_dest->rte_desc = xstrdup(route_orig->rte_desc); + route_dest->fs = fs_chain_copy(route_orig->fs); + route_dest->rte_num = route_orig->rte_num; + + route_add_head(route_dest); + + process_route(route_orig, route_dest); +} + +static void +bend_process(void) +{ + queue* elem, *tmp; + QUEUE_FOR_EACH(routes_orig, elem, tmp) { + route_head* route_orig = (route_head*)elem; + process_route_orig(route_orig); + } +} + +static void +bend_deinit(void) +{ + route_flush(routes_orig); + xfree(routes_orig); +} + +static void +bend_exit(void) +{ +} + +filter_vecs_t bend_vecs = { + bend_init, + bend_process, + bend_deinit, + bend_exit, + bend_args +}; + +#endif // FILTERS_ENABLED diff --git a/gpsbabel/brauniger_iq.c b/gpsbabel/brauniger_iq.c index eef12030d..30d0024b3 100644 --- a/gpsbabel/brauniger_iq.c +++ b/gpsbabel/brauniger_iq.c @@ -1,268 +1,279 @@ /* * Serial download of barograph data from a Brauniger IQ Variometer. - * + * * Copyright (C) 2004 Chris Jones - * - * This program is free software; you can redistribute it and/or modify it + * + * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111 USA + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111 USA */ #include "defs.h" #include "gbser.h" #include -static void *serial_handle; +static void* serial_handle; #define MYNAME "BRAUNIGER-IQ" #define PRESTRKNAME "PRESALTTRK" -static enum { - st_sync, - st_fl_num, - st_data_len, - st_ser_num, - st_pilot_name, - st_start_date, - st_start_year, - st_max_alt_1, - st_max_alt_2, - st_max_climb, - st_flight_dur, - st_log_ival, - st_start_time, - st_end_time, - st_sample_alt, - st_sample_spd, - num_states -} state; +typedef enum { + st_sync, + st_fl_num, + st_data_len, + st_ser_num, + st_pilot_name, + st_start_date, + st_start_year, + st_max_alt_1, + st_max_alt_2, + st_max_climb, + st_flight_dur, + st_log_ival, + st_start_time, + st_end_time, + st_sample_alt, + st_sample_spd, + num_states +} state_t; +state_t state; +#if __cplusplus +inline state_t operator++(state_t& rs, int) +{ + return rs = (state_t)((int)rs + 1); +} +#endif static const int reqd_bytes[num_states] = { 6, 1, 2, 2, 25, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1 }; -static void rd_init(const char *fname) { - if (serial_handle = gbser_init(fname), NULL == serial_handle) { - fatal(MYNAME ": Can't open port '%s'\n", fname); - } - if (gbser_set_port(serial_handle, 9600, 8, 0, 1) != gbser_OK) { - fatal(MYNAME ": Can't configure port '%s'\n", fname); - } +static void rd_init(const char* fname) +{ + if (serial_handle = gbser_init(fname), NULL == serial_handle) { + fatal(MYNAME ": Can't open port '%s'\n", fname); + } + if (gbser_set_port(serial_handle, 9600, 8, 0, 1) != gbser_OK) { + fatal(MYNAME ": Can't configure port '%s'\n", fname); + } } -static void rd_deinit(void) { - gbser_deinit(serial_handle); - serial_handle = NULL; +static void rd_deinit(void) +{ + gbser_deinit(serial_handle); + serial_handle = NULL; } /** * Process a data record. * @return zero when all expected data has been received */ -static int process_data(const unsigned char *data) { - static int remaining = 100; - static struct tm tm; - static time_t start, creation; - static route_head *track; - static unsigned char interval; - time_t finish; - waypoint *wpt = NULL; - int i; - - if (global_opts.debug_level >= 3) { - for (i = 0; i < reqd_bytes[state]; i++) { - printf("%.2x ", data[i]); - } - puts(""); +static int process_data(const unsigned char* data) +{ + static int remaining = 100; + static struct tm tm; + static time_t start, creation; + static route_head* track; + static unsigned char interval; + time_t finish; + waypoint* wpt = NULL; + int i; + + if (global_opts.debug_level >= 3) { + for (i = 0; i < reqd_bytes[state]; i++) { + printf("%.2x ", data[i]); + } + puts(""); + } + + remaining -= reqd_bytes[state]; + switch (state) { + case st_sync: + if (memcmp(data, "\x30\x31\x32\x33\x34\x35", 6) != 0) { + fatal(MYNAME ": Could not synchronise\n"); } + break; - remaining -= reqd_bytes[state]; - switch (state) { - case st_sync: - if (memcmp(data, "\x30\x31\x32\x33\x34\x35", 6) != 0) { - fatal(MYNAME ": Could not synchronise\n"); - } - break; - - case st_fl_num: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Flight Number: %d\n", data[0]); - } - break; - - case st_data_len: - remaining = (data[0] << 8) + data[1] - 2; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Data Length: %d\n", remaining); - } - break; - - case st_ser_num: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Serial Number: %d\n", (data[0] << 8) + data[1]); - } - break; - - case st_pilot_name: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Pilot Name: %.25s\n", data); - } - break; - - case st_start_date: - i = (data[0] << 8) + data[1]; - tm.tm_mday = i / 100; - tm.tm_mon = (i % 100) - 1; - break; - - case st_start_year: - tm.tm_year = ((data[0] << 8) + data[1]) - 1900; - break; - - case st_max_alt_1: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Max Altitude 1: %dm\n", (data[0] << 8) + data[1]); - } - break; - - case st_max_alt_2: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Max Altitude 2: %dm\n", (data[0] << 8) + data[1]); - } - break; - - case st_max_climb: - if (global_opts.debug_level >= 1) { - i = (data[0] << 8) + data[1]; - printf(MYNAME ": Max climb: %d.%dm/s\n", i / 10, i % 10); - } - break; - - case st_flight_dur: - if (global_opts.debug_level >= 1) { - i = (data[0] << 8) + data[1]; - printf(MYNAME ": Flight Time: %d:%d\n", i / 100, i % 100); - } - break; - - case st_log_ival: - interval = data[0]; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Logging Interval: %ds\n", interval); - } - break; - - case st_start_time: - i = (data[0] << 8) + data[1]; - tm.tm_hour = i / 100; - tm.tm_min = (i % 100) - 1; - tm.tm_sec = 0; - creation = start = mktime(&tm); - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Start Time: %s", ctime(&start)); - } - break; - - case st_end_time: - i = (data[0] << 8) + data[1]; - tm.tm_hour = i / 100; - tm.tm_min = (i % 100) - 1; - finish = mktime(&tm); - if (global_opts.debug_level >= 1) { - printf(MYNAME ": End Time: %s", ctime(&finish)); - } - if (remaining) { - track = route_head_alloc(); - track->rte_name = xstrdup(PRESTRKNAME); - track->rte_desc = xstrdup("Brauniger-IQ Barograph"); - track_add_head(track); - } else { - warning(MYNAME ": No barograph recorded for this flight\n"); - } - break; - - case st_sample_alt: - wpt = waypt_new(); - wpt->latitude = wpt->longitude = 0.0; - wpt->creation_time = creation; - creation += interval; - wpt->altitude = (data[0] << 8) + data[1]; - track_add_wpt(track, wpt); - if (global_opts.debug_level >= 2) { - printf(MYNAME ": remaining=%d, Altitude=%fm, ", remaining, wpt->altitude); - } - break; - - case st_sample_spd: - if (global_opts.debug_level >= 2) { - printf("Airspeed=%dkmh\n", data[0]); - } - state = st_sample_alt; - return remaining; - - default: - fatal(MYNAME ": Bad internal state\n"); + case st_fl_num: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Flight Number: %d\n", data[0]); } - state++; - return remaining; -} + break; + + case st_data_len: + remaining = (data[0] << 8) + data[1] - 2; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Data Length: %d\n", remaining); + } + break; + + case st_ser_num: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Serial Number: %d\n", (data[0] << 8) + data[1]); + } + break; -static void data_read(void) { - unsigned char ibuf[25]; - int rd_cnt; + case st_pilot_name: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Pilot Name: %.25s\n", data); + } + break; + + case st_start_date: + i = (data[0] << 8) + data[1]; + tm.tm_mday = i / 100; + tm.tm_mon = (i % 100) - 1; + break; + + case st_start_year: + tm.tm_year = ((data[0] << 8) + data[1]) - 1900; + break; + + case st_max_alt_1: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Max Altitude 1: %dm\n", (data[0] << 8) + data[1]); + } + break; + + case st_max_alt_2: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Max Altitude 2: %dm\n", (data[0] << 8) + data[1]); + } + break; - if (global_opts.debug_level >= 0) { - puts(MYNAME ": Select recorded flight in memo mode."); - puts(MYNAME ": Press Memo button for two seconds..."); + case st_max_climb: + if (global_opts.debug_level >= 1) { + i = (data[0] << 8) + data[1]; + printf(MYNAME ": Max climb: %d.%dm/s\n", i / 10, i % 10); } + break; - // Wait until something arrives - if (global_opts.debug_level >= 0) { - puts(MYNAME ": Downloading flight..."); + case st_flight_dur: + if (global_opts.debug_level >= 1) { + i = (data[0] << 8) + data[1]; + printf(MYNAME ": Flight Time: %d:%d\n", i / 100, i % 100); } + break; - // Read data until there is none left to read - state = st_sync; - for (;;) { - /* wait up to 5 seconds for more data */ - rd_cnt = gbser_read_wait(serial_handle, ibuf, reqd_bytes[state], 5000); - if (rd_cnt < 0) { - fatal(MYNAME ": Serial error\n"); - } else if (rd_cnt < reqd_bytes[state]) { - fatal(MYNAME ": Incomplete download\n"); - } - - if (!process_data(ibuf)) { - if (global_opts.debug_level >= 0) { - puts(MYNAME " ...Finished"); - } - return; - } - } + case st_log_ival: + interval = data[0]; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Logging Interval: %ds\n", interval); + } + break; + + case st_start_time: + i = (data[0] << 8) + data[1]; + tm.tm_hour = i / 100; + tm.tm_min = (i % 100) - 1; + tm.tm_sec = 0; + creation = start = mktime(&tm); + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Start Time: %s", ctime(&start)); + } + break; + + case st_end_time: + i = (data[0] << 8) + data[1]; + tm.tm_hour = i / 100; + tm.tm_min = (i % 100) - 1; + finish = mktime(&tm); + if (global_opts.debug_level >= 1) { + printf(MYNAME ": End Time: %s", ctime(&finish)); + } + if (remaining) { + track = route_head_alloc(); + track->rte_name = xstrdup(PRESTRKNAME); + track->rte_desc = xstrdup("Brauniger-IQ Barograph"); + track_add_head(track); + } else { + warning(MYNAME ": No barograph recorded for this flight\n"); + } + break; + + case st_sample_alt: + wpt = waypt_new(); + wpt->latitude = wpt->longitude = 0.0; + wpt->creation_time = creation; + creation += interval; + wpt->altitude = (data[0] << 8) + data[1]; + track_add_wpt(track, wpt); + if (global_opts.debug_level >= 2) { + printf(MYNAME ": remaining=%d, Altitude=%fm, ", remaining, wpt->altitude); + } + break; + + case st_sample_spd: + if (global_opts.debug_level >= 2) { + printf("Airspeed=%dkmh\n", data[0]); + } + state = st_sample_alt; + return remaining; + + default: + fatal(MYNAME ": Bad internal state\n"); + } + state++; + return remaining; +} + +static void data_read(void) +{ + unsigned char ibuf[25]; + int rd_cnt; + + if (global_opts.debug_level >= 0) { + puts(MYNAME ": Select recorded flight in memo mode."); + puts(MYNAME ": Press Memo button for two seconds..."); + } + + // Wait until something arrives + if (global_opts.debug_level >= 0) { + puts(MYNAME ": Downloading flight..."); + } + + // Read data until there is none left to read + state = st_sync; + for (;;) { + /* wait up to 5 seconds for more data */ + rd_cnt = gbser_read_wait(serial_handle, ibuf, reqd_bytes[state], 5000); + if (rd_cnt < 0) { + fatal(MYNAME ": Serial error\n"); + } else if (rd_cnt < reqd_bytes[state]) { + fatal(MYNAME ": Incomplete download\n"); + } + + if (!process_data(ibuf)) { + if (global_opts.debug_level >= 0) { + puts(MYNAME " ...Finished"); + } + return; + } + } } static arglist_t brauniger_iq_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; ff_vecs_t brauniger_iq_vecs = { - ff_type_serial, - { ff_cap_none, ff_cap_read, ff_cap_none}, - rd_init, - NULL, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - brauniger_iq_args, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_serial, + { ff_cap_none, ff_cap_read, ff_cap_none}, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + brauniger_iq_args, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; diff --git a/gpsbabel/bushnell.c b/gpsbabel/bushnell.c index a26d9e595..029cbca59 100644 --- a/gpsbabel/bushnell.c +++ b/gpsbabel/bushnell.c @@ -23,21 +23,21 @@ #include "defs.h" #define MYNAME "Bushnell" -static gbfile *file_in; -static char *ofname; -static short_handle mkshort_handle = NULL; +static gbfile* file_in; +static char* ofname; +static short_handle mkshort_handle = NULL; static arglist_t bushnell_args[] = { ARG_TERMINATOR }; -// Apparently, the icons are undocumented, so we made up names, +// Apparently, the icons are undocumented, so we made up names, // preferring them to be consistent with other brands where possiblde. typedef struct { const signed int symbol; - const char *icon; + const char* icon; } icon_mapping_t; icon_mapping_t bushnell_icons[] = { @@ -73,10 +73,10 @@ icon_mapping_t bushnell_icons[] = { { 0x19, "Blue Diamond Checkmark" }, // undocumented. { 0x1a, "Camera" }, - { 0x1b, "Restaraunt" }, // "Fork/Knife (meal place?)" - { 0x1c, "Restroom" }, // (man & Woman icon)" - { 0x1d, "RV Park" }, // "Bus or RV (RV campground?)" - { 0x1e, "Potable Water" }, // (faucet/glass or bucket)" + { 0x1b, "Restaraunt" }, // "Fork/Knife (meal place?)" + { 0x1c, "Restroom" }, // (man & Woman icon)" + { 0x1d, "RV Park" }, // "Bus or RV (RV campground?)" + { 0x1e, "Potable Water" }, // (faucet/glass or bucket)" { 0x1f, "Fishing" }, { 0x20, "Anchor in square" }, { 0x21, "Boat ramp/launch" }, @@ -87,17 +87,17 @@ icon_mapping_t bushnell_icons[] = { { 0x26, "Mouantin/Mountain Peak" }, { 0x27, "Turkey Tracks/animal tracks" }, - { 0x28, "Bank" }, // "Cash (ATM MAybe)" - { 0x29, "Bar" }, // "Martini undocumented" + { 0x28, "Bank" }, // "Cash (ATM MAybe)" + { 0x29, "Bar" }, // "Martini undocumented" { 0x2a, "Lighthouse" }, { 0x2b, "Tent" }, { 0x2c, "Cresent Wrench or can opener" }, - { 0x2d, "School" }, //? White Building with tunnel looking door and flag on top." - { 0x2f, "Information" }, // "i (info/internet maybe?)" - { 0x30, "Picnic" }, //"Picnic table & Tree, maybe forest picnic or day use area?" + { 0x2d, "School" }, //? White Building with tunnel looking door and flag on top." + { 0x2f, "Information" }, // "i (info/internet maybe?)" + { 0x30, "Picnic" }, //"Picnic table & Tree, maybe forest picnic or day use area?" { 0x31, "Phone" }, { 0x32, "Letter/Envelope" }, { 0x33, "Forest/Park Ranger" }, @@ -113,61 +113,70 @@ icon_mapping_t bushnell_icons[] = { { 0x3a, "Swimmer/swimming" }, { 0x3b, "Officer? Looks like man leaned over holding blue cube..." }, - { 0x3c, "Parking" }, //"Car Parked" + { 0x3c, "Parking" }, //"Car Parked" { 0x3d, "Airport" }, - { 0x3e, "Bus Terminal" }, // (guess) Loks like Bus under canopy." + { 0x3e, "Bus Terminal" }, // (guess) Loks like Bus under canopy." { 0x3f, "Red Cross" }, { 0x40, "Red Buidling with flag, Fire Station maybe." }, { 0x41, "Bus" }, - { 0x42, "Officer" }, // "see 3b: duplicate" + { 0x42, "Officer" }, // "see 3b: duplicate" { 0x43, "Railroad" }, { 0x44, "Auto Ferry" }, {-1, NULL} }; static unsigned int -bushnell_get_icon_from_name(const char *name) { - icon_mapping_t *t; +bushnell_get_icon_from_name(const char* name) +{ + icon_mapping_t* t; for (t = bushnell_icons; t->icon > 0; t++) { - if (0 == case_ignore_strcmp(name, t->icon)) - return t->symbol; + if (0 == case_ignore_strcmp(name, t->icon)) { + return t->symbol; + } } return 0; } -static const char * -bushnell_get_name_from_symbol(signed int s) { - icon_mapping_t *t; +static const char* +bushnell_get_name_from_symbol(signed int s) +{ + icon_mapping_t* t; for (t = bushnell_icons; t->icon > 0; t++) { - if (s == t->symbol) - return t->icon; + if (s == t->symbol) { + return t->icon; + } } return "Waypoint"; } static void -rd_init(const char *fname) { +rd_init(const char* fname) +{ file_in = gbfopen_le(fname, "rb", MYNAME); } static void -rd_deinit(void) { +rd_deinit(void) +{ gbfclose(file_in); } static void -wr_init(const char *fname) { - char *dot, *slash; +wr_init(const char* fname) +{ + char* dot, *slash; static char valid_chars [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789" - ".-/\\~@#$%^&*()_+=<>" - "abcdefghijklmnopqrstuvwxyz"; + ".-/\\~@#$%^&*()_+=<>" + "abcdefghijklmnopqrstuvwxyz"; ofname = xstrdup(fname); // If user provided an extension in the pathname, whack it. dot = strrchr(ofname, '.'); slash = strrchr(ofname, GB_PATHSEP); - if (dot > slash) *dot = 0; + if (dot > slash) { + *dot = 0; + } mkshort_handle = mkshort_new_handle(); setshort_length(mkshort_handle, 19); @@ -175,7 +184,8 @@ wr_init(const char *fname) { } static void -wr_deinit(void) { +wr_deinit(void) +{ mkshort_del_handle(&mkshort_handle); xfree(ofname); } @@ -184,11 +194,12 @@ wr_deinit(void) { * Each file contains a single waypoint. */ static void -bushnell_read(void) { +bushnell_read(void) +{ gbint32 lat_tmp,lon_tmp; unsigned int proximity; unsigned int icon; - waypoint *wpt_tmp = waypt_new(); + waypoint* wpt_tmp = waypt_new(); lat_tmp = gbfgetint32(file_in); lon_tmp = gbfgetint32(file_in); @@ -208,19 +219,20 @@ bushnell_read(void) { } static void -bushnell_write_one(const waypoint *wpt) { +bushnell_write_one(const waypoint* wpt) +{ char tbuf[20]; // 19 text bytes + null terminator. char padding[2] = {0, 0}; - gbfile *file_out; + gbfile* file_out; static int wpt_count; - char *fname; - char *ident; + char* fname; + char* ident; xasprintf(&fname, "%s-%d.wpt", ofname, wpt_count++); file_out = gbfopen_le(fname, "wb", MYNAME); gbfputint32(wpt->latitude * 10000000, file_out); gbfputint32(wpt->longitude * 10000000, file_out); - gbfputc(bushnell_get_icon_from_name(wpt->icon_descr ? wpt->icon_descr : + gbfputc(bushnell_get_icon_from_name(wpt->icon_descr ? wpt->icon_descr : "Waypoint"), file_out); gbfputc(0x01, file_out); // Proximity alarm. 1 == "off", 3 == armed. @@ -233,11 +245,13 @@ bushnell_write_one(const waypoint *wpt) { gbfwrite(padding, sizeof(padding), 1, file_out); xfree(fname); + xfree(ident); gbfclose(file_out); } static void -bushnell_write(void) { +bushnell_write(void) +{ waypt_disp_all(bushnell_write_one); } diff --git a/gpsbabel/bushnell_trl.c b/gpsbabel/bushnell_trl.c index 744a26a7c..7d1f17332 100644 --- a/gpsbabel/bushnell_trl.c +++ b/gpsbabel/bushnell_trl.c @@ -23,8 +23,8 @@ #include "defs.h" #define MYNAME "Bushnell Trail" -static gbfile *file_in; -static gbfile *file_out; +static gbfile* file_in; +static gbfile* file_out; static int trkpt_count; static route_head* trk_head; @@ -34,7 +34,8 @@ arglist_t bushnell_args[] = { }; static void -rd_init(const char *fname) { +rd_init(const char* fname) +{ char h[0x14]; // Believed to be zero terminated. file_in = gbfopen_le(fname, "rb", MYNAME); gbfread(h, 1, sizeof(h), file_in); @@ -46,29 +47,34 @@ rd_init(const char *fname) { } static void -rd_deinit(void) { - gbfclose(file_out); +rd_deinit(void) +{ + gbfclose(file_in); } static void -wr_init(const char *fname) { +wr_init(const char* fname) +{ int i,l = strlen(fname); - char obuf[20] = { 0 } ; - char *p = obuf; + char obuf[20] = { 0 } ; + char* p = obuf; file_out = gbfopen_le(fname, "w", MYNAME); trkpt_count = 0; for (i = 0; (i < l) && (i < 20); i++) { char c = toupper(fname[i]); - if (isalnum(c)) + if (isalnum(c)) { *p++ = c; - if (c == '.') + } + if (c == '.') { break; + } } gbfwrite(&obuf, 1, 20, file_out); } static void -wr_deinit(void) { +wr_deinit(void) +{ int i = trkpt_count; while (i < 4502) { gbfputint32(0, file_out); @@ -86,17 +92,19 @@ wr_deinit(void) { * Each file contains a single waypoint. */ static void -bushnell_read(void) { +bushnell_read(void) +{ int lat_tmp,lon_tmp; while (1) { - waypoint *wpt_tmp; + waypoint* wpt_tmp; lat_tmp = gbfgetint32(file_in); lon_tmp = gbfgetint32(file_in); - if (!lat_tmp && !lon_tmp) + if (!lat_tmp && !lon_tmp) { break; + } wpt_tmp = waypt_new(); wpt_tmp->latitude = lat_tmp / 10000000.0; @@ -107,25 +115,28 @@ bushnell_read(void) { } static void -bushnell_write_one(const waypoint *wpt) { +bushnell_write_one(const waypoint* wpt) +{ gbint32 lat = wpt->latitude * 10000000.0; gbint32 lon = wpt->longitude * 10000000.0; trkpt_count++; - if (trkpt_count > 4502) + if (trkpt_count > 4502) { fatal(MYNAME " too many trackpoints. Max is 4502."); + } gbfputint32(lat, file_out); gbfputint32(lon, file_out); } static void -bushnell_write(void) { +bushnell_write(void) +{ track_disp_all(NULL, NULL, bushnell_write_one); } ff_vecs_t bushnell_trl_vecs = { ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, + { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none }, rd_init, wr_init, rd_deinit, diff --git a/gpsbabel/cet.c b/gpsbabel/cet.c index e88c6b316..73dfd93c1 100644 --- a/gpsbabel/cet.c +++ b/gpsbabel/cet.c @@ -28,219 +28,231 @@ #include /* ! ALL vec PARAMETERS HAVE TO BE A VALID POINTER TO A cet_cs_vec_t RECORD ! */ - + /* =========================================================================== */ /* %%% single character or value transmission %%% */ /* --------------------------------------------------------------------------- */ /* %%% cet_char_to_ucs4 %%% * - * single character to UCS-4 code %%% + * single character to UCS-4 code %%% * return values: 0 if convertable character, otherwise 1 */ - + int -cet_char_to_ucs4(const char src, const cet_cs_vec_t *vec, int *value) +cet_char_to_ucs4(const char src, const cet_cs_vec_t* vec, int* value) { - int trash, c; - int *dest; - - c = ((unsigned char)src & 0xFF); - dest = (value != NULL) ? value : &trash; - - *dest = c; - c -= vec->ucs4_offset; - - if (c < 0) return CET_SUCCESS; - else if ((c >= vec->ucs4_count) || (vec->ucs4_map[c] == -1)) return CET_ERROR; - else - { - *dest = vec->ucs4_map[c]; - return CET_SUCCESS; - } + int trash, c; + int* dest; + + c = ((unsigned char)src & 0xFF); + dest = (value != NULL) ? value : &trash; + + *dest = c; + c -= vec->ucs4_offset; + + if (c < 0) { + return CET_SUCCESS; + } else if ((c >= vec->ucs4_count) || (vec->ucs4_map[c] == -1)) { + return CET_ERROR; + } else { + *dest = vec->ucs4_map[c]; + return CET_SUCCESS; + } } /* %%% cet_ucs4_to_utf8 %%% * - * convert single UCS-4 value into UTF-8 sequence + * convert single UCS-4 value into UTF-8 sequence * * return values: >= 0: length of produced UTF-8 sequence * < 0: -bytes more needed in target space */ int -cet_ucs4_to_utf8(char *dest, size_t dest_size, int value) +cet_ucs4_to_utf8(char* dest, size_t dest_size, int value) { - int result; - unsigned char trash[16]; - unsigned char *c; - - c = (dest != NULL) ? (unsigned char *) dest : trash; - - if ((value & 0xffffff80) == 0) /* <= 7 bits */ - { - if (dest_size < 1) return (dest_size - 1); - *c++ = value; - result = 1; - } - else if ((value & 0xfffff800) == 0) /* <= 11 bits */ - { - if (dest_size < 2) return (dest_size - 2); - *c++ = (0xc0 | (value >> 6)); - *c++ = (0x80 | (value & 0x3f)); - result = 2; - - } - else if ((value & 0xffff0000) == 0) /* <= 16 bits */ - { - if (dest_size < 3) return (dest_size - 3); - *c++ = (0xe0 | (value >> 12)); - *c++ = (0x80 | ((value >> 6) & 0x3f)); - *c++ = (0x80 | (value & 0x3f)); - result = 3; - } - else if ((value & 0xffe00000) == 0) /* <= 21 bits */ - { - if (dest_size < 4) return (dest_size - 4); - *c++ = (0xf0 | (value >> 18)); - *c++ = (0x80 | ((value >> 12) & 0x3f)); - *c++ = (0x80 | ((value >> 6) & 0x3f)); - *c++ = (0x80 | (value & 0x3f)); - result = 4; - } - else if ((value & 0xfc000000) == 0) /* <= 26 bits */ - { - if (dest_size < 5) return (dest_size - 5); - *c++ = (0xf8 | (value >> 24)); - *c++ = (0x80 | ((value >> 18) & 0x3f)); - *c++ = (0x80 | ((value >> 12) & 0x3f)); - *c++ = (0x80 | ((value >> 6) & 0x3f)); - *c++ = (0x80 | (value & 0x3f)); - result = 5; - } - else if ((value & 0x80000000) == 0) /* <= 31 bits */ - { - if (dest_size < 6) return (dest_size - 6); - *c++ = (0xfc | (value >> 30)); - *c++ = (0x80 | ((value >> 24) & 0x3f)); - *c++ = (0x80 | ((value >> 18) & 0x3f)); - *c++ = (0x80 | ((value >> 12) & 0x3f)); - *c++ = (0x80 | ((value >> 6) & 0x3f)); - *c++ = (0x80 | (value & 0x3f)); - result = 6; - } - else - { - return 0; /* Value = -1 */ - } - return result; + int result; + unsigned char trash[16]; + unsigned char* c; + + c = (dest != NULL) ? (unsigned char*) dest : trash; + + if ((value & 0xffffff80) == 0) { /* <= 7 bits */ + if (dest_size < 1) { + return (dest_size - 1); + } + *c++ = value; + result = 1; + } else if ((value & 0xfffff800) == 0) { /* <= 11 bits */ + if (dest_size < 2) { + return (dest_size - 2); + } + *c++ = (0xc0 | (value >> 6)); + *c++ = (0x80 | (value & 0x3f)); + result = 2; + + } else if ((value & 0xffff0000) == 0) { /* <= 16 bits */ + if (dest_size < 3) { + return (dest_size - 3); + } + *c++ = (0xe0 | (value >> 12)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 3; + } else if ((value & 0xffe00000) == 0) { /* <= 21 bits */ + if (dest_size < 4) { + return (dest_size - 4); + } + *c++ = (0xf0 | (value >> 18)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 4; + } else if ((value & 0xfc000000) == 0) { /* <= 26 bits */ + if (dest_size < 5) { + return (dest_size - 5); + } + *c++ = (0xf8 | (value >> 24)); + *c++ = (0x80 | ((value >> 18) & 0x3f)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 5; + } else if ((value & 0x80000000) == 0) { /* <= 31 bits */ + if (dest_size < 6) { + return (dest_size - 6); + } + *c++ = (0xfc | (value >> 30)); + *c++ = (0x80 | ((value >> 24) & 0x3f)); + *c++ = (0x80 | ((value >> 18) & 0x3f)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 6; + } else { + return 0; /* Value = -1 */ + } + return result; } -/* %%% cet_utf8_to_ucs4 %%% +/* %%% cet_utf8_to_ucs4 %%% * * decode single UTF-8 sequence into UCS-4 value * * return values: 0 if success, otherwise 1 */ int -cet_utf8_to_ucs4(const char *str, int *bytes, int *value) +cet_utf8_to_ucs4(const char* str, int* bytes, int* value) { - unsigned char *cp = (unsigned char *)str; - - if (*cp < 0x80) - { - if (bytes != NULL) *bytes = 1; - if (value != NULL) *value = *cp; - return CET_SUCCESS; - } - else - { - unsigned char bits = 0xc0; - unsigned char mask = 0xe0; - int len = 0; - - for (len = 1; len <= 6; len++) /* outer loop, test UTF-8 frame */ - { - if ((*cp & mask) == bits) - { - int i = len; - while (i-- > 0) - { - cp++; - if ((*cp & 0xc0) != 0x80) break; /* invalid */ - else if (i == 0) /* all valid */ - { - char *c = (char *)str; /* found valid sequence, now storing value */ - int res = *c++ & (mask ^ 0xFF); - i = len; - while (i-- > 0) - res = (res << 6) | (*c++ & 0x3f); - - if (bytes != NULL) *bytes = len + 1; - if (value != NULL) *value = res; - return CET_SUCCESS; - } - } - } - bits = (bits >> 1) | 0x80; - mask = (mask >> 1) | 0x80; - } - } - if (bytes != NULL) *bytes = 1; - if (value != NULL) *value = *cp; - return CET_ERROR; /* not valid */ + unsigned char* cp = (unsigned char*)str; + + if (*cp < 0x80) { + if (bytes != NULL) { + *bytes = 1; + } + if (value != NULL) { + *value = *cp; + } + return CET_SUCCESS; + } else { + unsigned char bits = 0xc0; + unsigned char mask = 0xe0; + int len = 0; + + for (len = 1; len <= 6; len++) { /* outer loop, test UTF-8 frame */ + if ((*cp & mask) == bits) { + int i = len; + while (i-- > 0) { + cp++; + if ((*cp & 0xc0) != 0x80) { + break; /* invalid */ + } else if (i == 0) { /* all valid */ + char* c = (char*)str; /* found valid sequence, now storing value */ + int res = *c++ & (mask ^ 0xFF); + i = len; + while (i-- > 0) { + res = (res << 6) | (*c++ & 0x3f); + } + + if (bytes != NULL) { + *bytes = len + 1; + } + if (value != NULL) { + *value = res; + } + return CET_SUCCESS; + } + } + } + bits = (bits >> 1) | 0x80; + mask = (mask >> 1) | 0x80; + } + } + if (bytes != NULL) { + *bytes = 1; + } + if (value != NULL) { + *value = *cp; + } + return CET_ERROR; /* not valid */ } /* %%% cet_ucs4_to_char %%% * - * convert single UCS-4 value to original character from CS + * convert single UCS-4 value to original character from CS * * return values: coverted character or "CET_NOT_CONVERTABLE_DEFAULT" * if not possible */ short -cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec) +cet_ucs4_to_char(const int value, const cet_cs_vec_t* vec) { - cet_ucs4_link_t *link; - - if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) - { - int i = 0; - int j = vec->ucs4_links - 1; /* validate ucs value against vec */ - while (i <= j) - { - int a = (i + j) >> 1; - int x = link[a].value; - - if (x < value) i = a + 1; - else if (x > value) j = a - 1; - else return link[a].origin; - } - } - - if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) /* can be NULL */ - { - int i = 0; - int j = vec->ucs4_extras - 1; - while (i <= j) - { - int a = (i + j) >> 1; - int x = link[a].value; - - if (x < value) i = a + 1; - else if (x > value) j = a - 1; - else return link[a].origin; - } - } - - if (value < vec->ucs4_offset + vec->ucs4_count) - return (char)value & 0xFF; - else { - if (vec->fallback && (vec->fallback != vec)) - return cet_ucs4_to_char(value, vec->fallback); - else - return CET_NOT_CONVERTABLE_DEFAULT; - } + cet_ucs4_link_t* link; + + if ((link = (cet_ucs4_link_t*)vec->ucs4_link)) { + int i = 0; + int j = vec->ucs4_links - 1; /* validate ucs value against vec */ + while (i <= j) { + int a = (i + j) >> 1; + int x = link[a].value; + + if (x < value) { + i = a + 1; + } else if (x > value) { + j = a - 1; + } else { + return link[a].origin; + } + } + } + + if ((link = (cet_ucs4_link_t*)vec->ucs4_extra)) { /* can be NULL */ + int i = 0; + int j = vec->ucs4_extras - 1; + while (i <= j) { + int a = (i + j) >> 1; + int x = link[a].value; + + if (x < value) { + i = a + 1; + } else if (x > value) { + j = a - 1; + } else { + return link[a].origin; + } + } + } + + if (value < vec->ucs4_offset + vec->ucs4_count) { + return (char)value & 0xFF; + } else { + if (vec->fallback && (vec->fallback != vec)) { + return cet_ucs4_to_char(value, vec->fallback); + } else { + return CET_NOT_CONVERTABLE_DEFAULT; + } + } } /* %%% cet_utf8_to_char %%% @@ -248,18 +260,22 @@ cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec) * Convert single UTF-8 sequence directly into associated characted * by given character set. */ - + short -cet_utf8_to_char(const char *str, const cet_cs_vec_t *vec, /* out */ int *bytes, int *value) +cet_utf8_to_char(const char* str, const cet_cs_vec_t* vec, /* out */ int* bytes, int* value) { - int b, v; - - cet_utf8_to_ucs4(str, &b, &v); /* decode UTF-8 sequence */ - - if (bytes != NULL) *bytes = b; - if (value != NULL) *value = v; - - return cet_ucs4_to_char(v, vec); + int b, v; + + cet_utf8_to_ucs4(str, &b, &v); /* decode UTF-8 sequence */ + + if (bytes != NULL) { + *bytes = b; + } + if (value != NULL) { + *value = v; + } + + return cet_ucs4_to_char(v, vec); } /* =========================================================================== */ @@ -270,71 +286,74 @@ cet_utf8_to_char(const char *str, const cet_cs_vec_t *vec, /* out */ int *bytes, * * Returns the number of valid (visible) characters. */ -unsigned int -cet_utf8_strlen(const char *str) +unsigned int +cet_utf8_strlen(const char* str) { - if (str) { - const char *cin = str; - int len = 0; - - while (*cin) { - int bytes, value; - if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) len++; - cin += bytes; - } - return len; - } - else - return 0; + if (str) { + const char* cin = str; + int len = 0; + + while (*cin) { + int bytes, value; + if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { + len++; + } + cin += bytes; + } + return len; + } else { + return 0; + } } /* %%% cet_utf8_strdup %%% * - * Checks and duplicates an UTF-8 string + * Checks and duplicates an UTF-8 string */ -char * -cet_utf8_strdup(const char *str) +char* +cet_utf8_strdup(const char* str) { - if (str) - return cet_utf8_strndup(str, strlen(str)); - else - return NULL; + if (str) { + return cet_utf8_strndup(str, strlen(str)); + } else { + return NULL; + } } /* %%% cet_utf8_strndup %%% * - * Checks and duplicates an UTF-8 string + * Checks and duplicates an UTF-8 string */ -char * -cet_utf8_strndup(const char *str, const int maxlen) +char* +cet_utf8_strndup(const char* str, const int maxlen) { - if (str) { - const char *cin = str; - char *res, *cout; - int len = 0; - - res = cout = xstrdup(cin); - - while (*cin && (len < maxlen)) { - int bytes, value; - if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { - cout += cet_ucs4_to_utf8(cout, 6, value); - len += 1; - } - cin += bytes; - } - *cout = '\0'; - - if ((cin - str) != (cout - res)) { - cout = xstrdup(res); - xfree(res); - res = cout; - } - - return res; - } - else - return NULL; + if (str) { + const char* cin = str; + char* res, *cout; + int len = 0; + + res = cout = xstrdup(cin); + + while (*cin && (len < maxlen)) { + int bytes, value; + if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { + cout += cet_ucs4_to_utf8(cout, 6, value); + len += 1; + } + cin += bytes; + } + *cout = '\0'; + + if ((cin - str) != (cout - res)) { + cout = xstrdup(res); + xfree(res); + res = cout; + } + + return res; + } else { + return NULL; + } } /* =========================================================================== */ @@ -343,32 +362,35 @@ cet_utf8_strndup(const char *str, const int maxlen) /* %%% cet_str_utf8_to_any %%% * - * Converts a UTF-8 string to given character set + * Converts a UTF-8 string to given character set */ -char * -cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec) +char* +cet_str_utf8_to_any(const char* src, const cet_cs_vec_t* vec) { - char *c = (char *)src; - int len; - char *res, *dest, *cend; - - if (c == NULL) return NULL; - if (vec->ucs4_count == 0) return xstrdup(src); /* UTF-8 -> UTF-8 */ - - len = strlen(c); - res = dest = (char *) xmalloc(len + 1); /* target will become smaller or equal length */ - - cend = c + len; - - while (c < cend) - { - int bytes; - *dest++ = cet_utf8_to_char(c, vec, &bytes, NULL); - c += bytes; - } - *dest = '\0'; - - return res; + char* c = (char*)src; + int len; + char* res, *dest, *cend; + + if (c == NULL) { + return NULL; + } + if (vec->ucs4_count == 0) { + return xstrdup(src); /* UTF-8 -> UTF-8 */ + } + + len = strlen(c); + res = dest = (char*) xmalloc(len + 1); /* target will become smaller or equal length */ + + cend = c + len; + + while (c < cend) { + int bytes; + *dest++ = cet_utf8_to_char(c, vec, &bytes, NULL); + c += bytes; + } + *dest = '\0'; + + return res; } @@ -376,104 +398,118 @@ cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec) * * Converts a string from given character set to UTF-8 */ -char * -cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec) +char* +cet_str_any_to_utf8(const char* src, const cet_cs_vec_t* vec) { - int len, value; - char *result, *cin, *cout; - char temp = CET_NOT_CONVERTABLE_DEFAULT; - - cin = (char *)src; - if (cin == NULL) return NULL; - if (vec->ucs4_count == 0) return xstrdup(src); /* UTF-8 -> UTF-8 */ - - len = 0; - while (*cin != '\0') /* determine length of resulting UTF-8 string */ - { - if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) - cet_char_to_ucs4(temp, vec, &value); - len += cet_ucs4_to_utf8(NULL, 6, value); - } - - result = cout = (char *) xmalloc(len + 1); - cin = (char *)src; - - while (*cin != '\0') - { - if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) - cet_char_to_ucs4(temp, vec, &value); - cout += cet_ucs4_to_utf8(cout, 6, value); - } - *cout = '\0'; - return result; + int len, value; + char* result, *cin, *cout; + char temp = CET_NOT_CONVERTABLE_DEFAULT; + + cin = (char*)src; + if (cin == NULL) { + return NULL; + } + if (vec->ucs4_count == 0) { + return xstrdup(src); /* UTF-8 -> UTF-8 */ + } + + len = 0; + while (*cin != '\0') { /* determine length of resulting UTF-8 string */ + if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) { + cet_char_to_ucs4(temp, vec, &value); + } + len += cet_ucs4_to_utf8(NULL, 6, value); + } + + result = cout = (char*) xmalloc(len + 1); + cin = (char*)src; + + while (*cin != '\0') { + if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) { + cet_char_to_ucs4(temp, vec, &value); + } + cout += cet_ucs4_to_utf8(cout, 6, value); + } + *cout = '\0'; + return result; } /* %%% cet_str_uni_to_utf8 %%% * * Converts an unicode string to UTF-8 */ -char * -cet_str_uni_to_utf8(const short *src, const int length) +char* +cet_str_uni_to_utf8(const short* src, const int length) { - int i, len; - unsigned short *cin; - char *res, *cout; - - if (src == NULL) return NULL; - - len = 0; - i = length; - cin = (unsigned short *)src; - - while (i-- > 0) - len += cet_ucs4_to_utf8(NULL, 6, le_read16(cin++)); - - res = cout = (char *) xmalloc(len + 1); - cin = (unsigned short *)src; - i = length; - - while (i-- > 0) - cout += cet_ucs4_to_utf8(cout, 6, le_read16(cin++)); - - *cout = '\0'; - - return res; + int i, len; + unsigned short* cin; + char* res, *cout; + + if (src == NULL) { + return NULL; + } + + len = 0; + i = length; + cin = (unsigned short*)src; + + while (i-- > 0) { + len += cet_ucs4_to_utf8(NULL, 6, le_read16(cin++)); + } + + res = cout = (char*) xmalloc(len + 1); + cin = (unsigned short*)src; + i = length; + + while (i-- > 0) { + cout += cet_ucs4_to_utf8(cout, 6, le_read16(cin++)); + } + + *cout = '\0'; + + return res; } /* %%% cet_str_any_to_uni %%% * * Converts a string in given character set to a 'wide string' (unicode) */ -short * -cet_str_any_to_uni(const char *src, const cet_cs_vec_t *vec, int *length) +short* +cet_str_any_to_uni(const char* src, const cet_cs_vec_t* vec, int* length) { - char *utf8; - int len; - short *res, *sout; - - if (! src) utf8 = xstrdup(""); - else if (vec->ucs4_count == 0) utf8 = cet_utf8_strdup(src); /* UTF-8 -> clean UTF-8 */ - else utf8 = cet_str_any_to_utf8(src, vec); - - len = cet_utf8_strlen(utf8); - res = sout = (short int *) xcalloc(2, len + 1); - - if (len) { - char *cin = utf8; - - while (*cin) { - int bytes, value; - if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { - le_write16(sout, value); - sout++; - } - cin += bytes; - } - } - - *sout = 0; - if (length) *length = len; - xfree(utf8); - - return res; + char* utf8; + int len; + short* res, *sout; + + if (! src) { + utf8 = xstrdup(""); + } else if (vec->ucs4_count == 0) { + utf8 = cet_utf8_strdup(src); /* UTF-8 -> clean UTF-8 */ + } else { + utf8 = cet_str_any_to_utf8(src, vec); + } + + len = cet_utf8_strlen(utf8); + res = sout = (short int*) xcalloc(2, len + 1); + + if (len) { + char* cin = utf8; + + while (*cin) { + int bytes, value; + if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { + le_write16(sout, value); + sout++; + } + cin += bytes; + } + } + + *sout = 0; + if (length) { + *length = len; + } + xfree(utf8); + + return res; } diff --git a/gpsbabel/cet.h b/gpsbabel/cet.h index 84099e589..0ba382365 100644 --- a/gpsbabel/cet.h +++ b/gpsbabel/cet.h @@ -28,54 +28,52 @@ #define CET_ERROR 1 #define CET_SUCCESS 0 -typedef struct cet_ucs4_link_s -{ - int value; /* UCS-4 value */ - short origin; /* associeted character */ +typedef struct cet_ucs4_link_s { + int value; /* UCS-4 value */ + short origin; /* associeted character */ } cet_ucs4_link_t; -typedef struct cet_cs_vec_s -{ - const char *name; /* name of character set */ - const char **alias; /* alias table */ - struct cet_cs_vec_s *fallback; /* fallback character set */ - void *unused; - const int *ucs4_map; /* char to UCS-4 value table */ - const int ucs4_offset; /* first non standard character */ - const int ucs4_count; /* values in table */ - const cet_ucs4_link_t *ucs4_link; /* UCS-4 to char backward links */ - const int ucs4_links; /* number of links */ - const cet_ucs4_link_t *ucs4_extra; /* Non standard UCS-4 to ... */ - const int ucs4_extras; /* number of extra links */ - struct cet_cs_vec_s *next; +typedef struct cet_cs_vec_s { + const char* name; /* name of character set */ + const char** alias; /* alias table */ + struct cet_cs_vec_s* fallback; /* fallback character set */ + void* unused; + const int* ucs4_map; /* char to UCS-4 value table */ + const int ucs4_offset; /* first non standard character */ + const int ucs4_count; /* values in table */ + const cet_ucs4_link_t* ucs4_link; /* UCS-4 to char backward links */ + const int ucs4_links; /* number of links */ + const cet_ucs4_link_t* ucs4_extra; /* Non standard UCS-4 to ... */ + const int ucs4_extras; /* number of extra links */ + struct cet_cs_vec_s* next; } cet_cs_vec_t; /* single char/value transmission */ -int cet_utf8_to_ucs4(const char *str, int *bytes, int *value); -int cet_ucs4_to_utf8(char *dest, size_t dest_size, int value); +int cet_utf8_to_ucs4(const char* str, int* bytes, int* value); +int cet_ucs4_to_utf8(char* dest, size_t dest_size, int value); /* single char/value transmission - vec based */ -int cet_char_to_ucs4(const char src, const cet_cs_vec_t *vec, int *value); -short cet_utf8_to_char(const char *str, const cet_cs_vec_t *vecint, int *bytes, int *value); -short cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec); +int cet_char_to_ucs4(const char src, const cet_cs_vec_t* vec, int* value); +short cet_utf8_to_char(const char* str, const cet_cs_vec_t* vecint, int* bytes, int* value); +short cet_ucs4_to_char(const int value, const cet_cs_vec_t* vec); /* string to string - vector based */ -char *cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec); -char *cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec); +char* cet_str_utf8_to_any(const char* src, const cet_cs_vec_t* vec); +char* cet_str_any_to_utf8(const char* src, const cet_cs_vec_t* vec); -char *cet_str_uni_to_utf8(const short *src, const int length); +char* cet_str_uni_to_utf8(const short* src, const int length); /* UTF-8 string manipulation functions */ -unsigned int cet_utf8_strlen(const char *str); -char *cet_utf8_strdup(const char *str); -char *cet_utf8_strndup(const char *str, const int maxlen); +unsigned int cet_utf8_strlen(const char* str); +char* cet_utf8_strdup(const char* str); +char* cet_utf8_strndup(const char* str, const int maxlen); /* unicode functions */ -short *cet_str_any_to_uni(const char *src, const cet_cs_vec_t *vec, int *length); +short* cet_str_any_to_uni(const char* src, const cet_cs_vec_t* vec, int* length); #endif diff --git a/gpsbabel/cet/ansi_x3_4_1968.h b/gpsbabel/cet/ansi_x3_4_1968.h index 3305fb6bf..78574c0f0 100644 --- a/gpsbabel/cet/ansi_x3_4_1968.h +++ b/gpsbabel/cet/ansi_x3_4_1968.h @@ -37,11 +37,11 @@ const char *cet_cs_alias_ansi_x3_4_1968[] = #define cet_ucs4_ofs_ansi_x3_4_1968 128 #define cet_ucs4_cnt_ansi_x3_4_1968 1 -const int cet_ucs4_map_ansi_x3_4_1968[cet_ucs4_cnt_ansi_x3_4_1968]; +const int cet_ucs4_map_ansi_x3_4_1968[cet_ucs4_cnt_ansi_x3_4_1968] = {0}; #define cet_ucs4_to_ansi_x3_4_1968_ct 1 -const cet_ucs4_link_t cet_ucs4_to_ansi_x3_4_1968_links[cet_ucs4_to_ansi_x3_4_1968_ct]; +const cet_ucs4_link_t cet_ucs4_to_ansi_x3_4_1968_links[cet_ucs4_to_ansi_x3_4_1968_ct] = {{0}}; // #define cet_ucs4_to_ansi_x3_4_1968_extra_ct 200 diff --git a/gpsbabel/cet/ibm891.h b/gpsbabel/cet/ibm891.h index 2d0f3a6ab..85132b473 100644 --- a/gpsbabel/cet/ibm891.h +++ b/gpsbabel/cet/ibm891.h @@ -34,15 +34,15 @@ const char *cet_cs_alias_ibm891[] = #define cet_ucs4_ofs_ibm891 128 #define cet_ucs4_cnt_ibm891 1 -const int cet_ucs4_map_ibm891[cet_ucs4_cnt_ibm891]; +const int cet_ucs4_map_ibm891[cet_ucs4_cnt_ibm891] = {0}; #define cet_ucs4_to_ibm891_ct 1 -const cet_ucs4_link_t cet_ucs4_to_ibm891_links[cet_ucs4_to_ibm891_ct]; +const cet_ucs4_link_t cet_ucs4_to_ibm891_links[cet_ucs4_to_ibm891_ct] = {0}; /* #define cet_ucs4_to_ibm891_extra_ct 0 -const cet_ucs4_link_t cet_ucs4_to_ibm891_extra[cet_ucs4_to_ibm891_extra_ct] = {}; +const cet_ucs4_link_t cet_ucs4_to_ibm891_extra[cet_ucs4_to_ibm891_extra_ct] = {0}; */ cet_cs_vec_t cet_cs_vec_ibm891 = /* defined in cet.h */ diff --git a/gpsbabel/cet/ibm903.h b/gpsbabel/cet/ibm903.h index b9a4d6c19..eeadd40a9 100644 --- a/gpsbabel/cet/ibm903.h +++ b/gpsbabel/cet/ibm903.h @@ -34,15 +34,15 @@ const char *cet_cs_alias_ibm903[] = #define cet_ucs4_ofs_ibm903 128 #define cet_ucs4_cnt_ibm903 1 -const int cet_ucs4_map_ibm903[cet_ucs4_cnt_ibm903]; +const int cet_ucs4_map_ibm903[cet_ucs4_cnt_ibm903] = {0}; #define cet_ucs4_to_ibm903_ct 1 -const cet_ucs4_link_t cet_ucs4_to_ibm903_links[cet_ucs4_to_ibm903_ct]; +const cet_ucs4_link_t cet_ucs4_to_ibm903_links[cet_ucs4_to_ibm903_ct] = {0}; /* #define cet_ucs4_to_ibm903_extra_ct 0 -const cet_ucs4_link_t cet_ucs4_to_ibm903_extra[cet_ucs4_to_ibm903_extra_ct] = {}; +const cet_ucs4_link_t cet_ucs4_to_ibm903_extra[cet_ucs4_to_ibm903_extra_ct] = {0}; */ cet_cs_vec_t cet_cs_vec_ibm903 = /* defined in cet.h */ diff --git a/gpsbabel/cet/iso_8859_1.h b/gpsbabel/cet/iso_8859_1.h index 7df74cc0c..70b71664c 100644 --- a/gpsbabel/cet/iso_8859_1.h +++ b/gpsbabel/cet/iso_8859_1.h @@ -37,11 +37,11 @@ const char *cet_cs_alias_iso_8859_1[] = #define cet_ucs4_ofs_iso_8859_1 256 #define cet_ucs4_cnt_iso_8859_1 1 -const int cet_ucs4_map_iso_8859_1[cet_ucs4_cnt_iso_8859_1]; +const int cet_ucs4_map_iso_8859_1[cet_ucs4_cnt_iso_8859_1] = {0}; #define cet_ucs4_to_iso_8859_1_ct 1 -const cet_ucs4_link_t cet_ucs4_to_iso_8859_1_links[cet_ucs4_to_iso_8859_1_ct]; +const cet_ucs4_link_t cet_ucs4_to_iso_8859_1_links[cet_ucs4_to_iso_8859_1_ct] = {{0}}; /* #define cet_ucs4_to_iso_8859_1_extra_ct 0 diff --git a/gpsbabel/cet_util.c b/gpsbabel/cet_util.c index 205c23d25..b7721cef3 100644 --- a/gpsbabel/cet_util.c +++ b/gpsbabel/cet_util.c @@ -36,15 +36,14 @@ #define MYNAME "cet_util" -static cet_cs_vec_t *cet_cs_vec_root = NULL; +static cet_cs_vec_t* cet_cs_vec_root = NULL; -typedef struct cet_cs_alias_s -{ - char *name; - cet_cs_vec_t *vec; +typedef struct cet_cs_alias_s { + char* name; + cet_cs_vec_t* vec; } cet_cs_alias_t; -static cet_cs_alias_t *cet_cs_alias; +static cet_cs_alias_t* cet_cs_alias; static int cet_cs_alias_ct = 0; static int cet_cs_vec_ct = 0; static int cet_output = 0; @@ -60,81 +59,81 @@ static int cet_output = 0; /* %%% short hand strings transmission for main character sets %%% */ -char * -cet_str_utf8_to_iso8859_1(const char *src) +char* +cet_str_utf8_to_iso8859_1(const char* src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_1); + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_1); } -char * -cet_str_iso8859_1_to_utf8(const char *src) +char* +cet_str_iso8859_1_to_utf8(const char* src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_1); + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_1); } -char * -cet_str_utf8_to_iso8859_8(const char *src) +char* +cet_str_utf8_to_iso8859_8(const char* src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_8); + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_8); } -char * -cet_str_iso8859_8_to_utf8(const char *src) +char* +cet_str_iso8859_8_to_utf8(const char* src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_8); + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_8); } -char * -cet_str_utf8_to_iso8859_15(const char *src) +char* +cet_str_utf8_to_iso8859_15(const char* src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_15); + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_15); } -char * -cet_str_iso8859_15_to_utf8(const char *src) +char* +cet_str_iso8859_15_to_utf8(const char* src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_15); + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_15); } -char * -cet_str_utf8_to_us_ascii(const char *src) +char* +cet_str_utf8_to_us_ascii(const char* src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_ansi_x3_4_1968); + return cet_str_utf8_to_any(src, &cet_cs_vec_ansi_x3_4_1968); } -char * -cet_str_us_ascii_to_utf8(const char *src) +char* +cet_str_us_ascii_to_utf8(const char* src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_ansi_x3_4_1968); + return cet_str_any_to_utf8(src, &cet_cs_vec_ansi_x3_4_1968); } -char * -cet_str_utf8_to_cp1252(const char *src) +char* +cet_str_utf8_to_cp1252(const char* src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_cp1252); + return cet_str_utf8_to_any(src, &cet_cs_vec_cp1252); } -char * -cet_str_cp1252_to_utf8(const char *src) +char* +cet_str_cp1252_to_utf8(const char* src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_cp1252); + return cet_str_any_to_utf8(src, &cet_cs_vec_cp1252); } -char * -cet_str_utf8_to_cp1255(const char *src) +char* +cet_str_utf8_to_cp1255(const char* src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_cp1255); + return cet_str_utf8_to_any(src, &cet_cs_vec_cp1255); } -char * -cet_str_cp1255_to_utf8(const char *src) +char* +cet_str_cp1255_to_utf8(const char* src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_cp1255); + return cet_str_any_to_utf8(src, &cet_cs_vec_cp1255); } -short * -cet_str_utf8_to_uni(const char *src, int *length) +short* +cet_str_utf8_to_uni(const char* src, int* length) { - return cet_str_any_to_uni(src, &cet_cs_vec_utf8, length); + return cet_str_any_to_uni(src, &cet_cs_vec_utf8, length); } @@ -146,79 +145,87 @@ cet_str_utf8_to_uni(const char *src, int *length) * */ #if HAVE_LIBEXPAT -int XMLCALL cet_lib_expat_UnknownEncodingHandler(void *data, const XML_Char *xml_encoding, XML_Encoding *info) +int XMLCALL cet_lib_expat_UnknownEncodingHandler(void* data, const XML_Char* xml_encoding, XML_Encoding* info) { - cet_cs_vec_t *cs; - int i, c, ucs4_def; - const char *encoding; - - encoding = xml_convert_to_char_string(xml_encoding); - cs = cet_find_cs_by_name(encoding); - if (cs == NULL) return XML_STATUS_ERROR; /* fatal(MYNAME ": Unknown character set \"%s\"!\n", encoding); */ - - cet_char_to_ucs4(CET_NOT_CONVERTABLE_DEFAULT, cs, &ucs4_def); - - for (i = 0; i < cs->ucs4_offset; i++) info->map[i] = i; /* equal to ascii part */ - for (i = 0; i < cs->ucs4_count; i++) /* mixed table */ - { - c = cs->ucs4_map[i]; - if (c == -1) c = ucs4_def; - info->map[i + cs->ucs4_offset] = c; - } - for (i = cs->ucs4_offset + cs->ucs4_count; i < 256; i++) info->map[i] = ucs4_def; /* non convertable trailer */ - - info->data = NULL; - info->convert = NULL; - info->release = NULL; - - cet_convert_init(CET_CHARSET_UTF8, 1); /* We do not need to transform any string */ - - if (global_opts.verbose_status > 0) - printf(MYNAME ": XML parser - encoding handler for character set \"%s\" established.\n", encoding); - - xml_free_converted_string(encoding); - return XML_STATUS_OK; + cet_cs_vec_t* cs; + int i, c, ucs4_def; + const char* encoding; + + encoding = xml_convert_to_char_string(xml_encoding); + cs = cet_find_cs_by_name(encoding); + if (cs == NULL) { + return XML_STATUS_ERROR; /* fatal(MYNAME ": Unknown character set \"%s\"!\n", encoding); */ + } + + cet_char_to_ucs4(CET_NOT_CONVERTABLE_DEFAULT, cs, &ucs4_def); + + for (i = 0; i < cs->ucs4_offset; i++) { + info->map[i] = i; /* equal to ascii part */ + } + for (i = 0; i < cs->ucs4_count; i++) { /* mixed table */ + c = cs->ucs4_map[i]; + if (c == -1) { + c = ucs4_def; + } + info->map[i + cs->ucs4_offset] = c; + } + for (i = cs->ucs4_offset + cs->ucs4_count; i < 256; i++) { + info->map[i] = ucs4_def; /* non convertable trailer */ + } + + info->data = NULL; + info->convert = NULL; + info->release = NULL; + + cet_convert_init(CET_CHARSET_UTF8, 1); /* We do not need to transform any string */ + + if (global_opts.verbose_status > 0) { + printf(MYNAME ": XML parser - encoding handler for character set \"%s\" established.\n", encoding); + } + + xml_free_converted_string(encoding); + return XML_STATUS_OK; } #endif -char * -cet_str_uni_to_any(const short *src, int length, const cet_cs_vec_t *dest_vec) +char* +cet_str_uni_to_any(const short* src, int length, const cet_cs_vec_t* dest_vec) { - char *res, *c; - const cet_cs_vec_t *cs = (dest_vec != NULL) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; - - res = cet_str_uni_to_utf8(src, length); - if (cs != &cet_cs_vec_utf8) - { - c = cet_str_utf8_to_any(res, cs); - xfree(res); - res = c; - } - return res; + char* res, *c; + const cet_cs_vec_t* cs = (dest_vec != NULL) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; + + res = cet_str_uni_to_utf8(src, length); + if (cs != &cet_cs_vec_utf8) { + c = cet_str_utf8_to_any(res, cs); + xfree(res); + res = c; + } + return res; } -/* %%% cet_str_any_to_any %%% +/* %%% cet_str_any_to_any %%% * * -->> for use in mkshort */ -char * -cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_vec_t *dest_vec) +char* +cet_str_any_to_any(const char* src, const cet_cs_vec_t* src_vec, const cet_cs_vec_t* dest_vec) { - char *c0, *c1; - const cet_cs_vec_t *v_in = (src_vec != NULL ) ? src_vec : &cet_cs_vec_ansi_x3_4_1968; - const cet_cs_vec_t *v_out = (dest_vec != NULL ) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; - - if (src == NULL) - return NULL; - else - if ((*src == '\0') || (v_in == v_out)) return xstrdup(src); - - c0 = (v_in == &cet_cs_vec_utf8) ? xstrdup(src) : cet_str_any_to_utf8(src, v_in); - c1 = (v_out == &cet_cs_vec_utf8) ? xstrdup(c0) : cet_str_utf8_to_any(c0, v_out); - xfree(c0); - - return c1; + char* c0, *c1; + const cet_cs_vec_t* v_in = (src_vec != NULL) ? src_vec : &cet_cs_vec_ansi_x3_4_1968; + const cet_cs_vec_t* v_out = (dest_vec != NULL) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; + + if (src == NULL) { + return NULL; + } else if ((*src == '\0') || (v_in == v_out)) { + return xstrdup(src); + } + + c0 = (v_in == &cet_cs_vec_utf8) ? xstrdup(src) : cet_str_any_to_utf8(src, v_in); + c1 = (v_out == &cet_cs_vec_utf8) ? xstrdup(c0) : cet_str_utf8_to_any(c0, v_out); + xfree(c0); + + return c1; } /* %%% cet_valid_char %%% @@ -228,12 +235,12 @@ cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_ve */ int -cet_valid_char(const char *src, const cet_cs_vec_t *vec) +cet_valid_char(const char* src, const cet_cs_vec_t* vec) { - int value; + int value; - const cet_cs_vec_t *v = (vec != NULL) ? vec : &cet_cs_vec_ansi_x3_4_1968; - return cet_char_to_ucs4(*src, v, &value); + const cet_cs_vec_t* v = (vec != NULL) ? vec : &cet_cs_vec_ansi_x3_4_1968; + return cet_char_to_ucs4(*src, v, &value); } /* %%% include character set headers %%% */ @@ -362,714 +369,716 @@ cet_valid_char(const char *src, const cet_cs_vec_t *vec) #ifdef DEBUG_MEM void -cet_check_cs(cet_cs_vec_t *vec) /* test well sorted link & extra tables */ +cet_check_cs(cet_cs_vec_t* vec) /* test well sorted link & extra tables */ { - cet_ucs4_link_t *link; - - if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) - { - int i, j; - - for (i = 0, j = 1; j < vec->ucs4_links; i++, j++) - { - if (link[i].value >= link[j].value) - { - printf(MYNAME ": checked 0x%04x with 0x%04x\n", link[i].value, link[j].value); - fatal(MYNAME ": \"%s\"-link-table unsorted !!!\n", vec->name); - } - - } - } - if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) - { - int i, j; - - for (i = 0, j = 1; j < vec->ucs4_extras; i++, j++) - { - if (link[i].value >= link[j].value) - { - printf(MYNAME ": check 0x%04x with 0x%04x\n", link[i].value, link[j].value); - fatal(MYNAME ": \"%s\"-extra-table unsorted !!!\n", vec->name); - } - - } - } + cet_ucs4_link_t* link; + + if ((link = (cet_ucs4_link_t*)vec->ucs4_link)) { + int i, j; + + for (i = 0, j = 1; j < vec->ucs4_links; i++, j++) { + if (link[i].value >= link[j].value) { + printf(MYNAME ": checked 0x%04x with 0x%04x\n", link[i].value, link[j].value); + fatal(MYNAME ": \"%s\"-link-table unsorted !!!\n", vec->name); + } + + } + } + if ((link = (cet_ucs4_link_t*)vec->ucs4_extra)) { + int i, j; + + for (i = 0, j = 1; j < vec->ucs4_extras; i++, j++) { + if (link[i].value >= link[j].value) { + printf(MYNAME ": check 0x%04x with 0x%04x\n", link[i].value, link[j].value); + fatal(MYNAME ": \"%s\"-extra-table unsorted !!!\n", vec->name); + } + + } + } } #endif static signed int -cet_cs_alias_qsort_cb(const void *a, const void *b) +cet_cs_alias_qsort_cb(const void* a, const void* b) { - const cet_cs_alias_t *va = a; - const cet_cs_alias_t *vb = b; - return case_ignore_strcmp(va->name, vb->name); + const cet_cs_alias_t* va = (const cet_cs_alias_t*) a; + const cet_cs_alias_t* vb = (const cet_cs_alias_t*) b; + return case_ignore_strcmp(va->name, vb->name); } static signed int -cet_cs_vec_qsort_cb(const void *a, const void *b) +cet_cs_vec_qsort_cb(const void* a, const void* b) { - const cet_cs_vec_t *va = *(cet_cs_vec_t **)a; - const cet_cs_vec_t *vb = *(cet_cs_vec_t **)b; - return case_ignore_strcmp(va->name, vb->name); + const cet_cs_vec_t* va = *(cet_cs_vec_t**)a; + const cet_cs_vec_t* vb = *(cet_cs_vec_t**)b; + return case_ignore_strcmp(va->name, vb->name); } -void -cet_register_cs(cet_cs_vec_t *vec) +void +cet_register_cs(cet_cs_vec_t* vec) { - if (vec->next == NULL) - { - vec->next = cet_cs_vec_root; - cet_cs_vec_root = vec; - cet_cs_vec_ct++; + if (vec->next == NULL) { + vec->next = cet_cs_vec_root; + cet_cs_vec_root = vec; + cet_cs_vec_ct++; #ifdef DEBUG_MEM - cet_check_cs(vec); + cet_check_cs(vec); #endif - } + } } /* Dummy vector for our native character set */ -const char *cet_cs_utf8_alias[] = -{ - "utf8", NULL +const char* cet_cs_utf8_alias[] = { + "utf8", NULL }; -cet_cs_vec_t cet_cs_vec_utf8 = -{ - CET_CHARSET_UTF8, - cet_cs_utf8_alias, - NULL, /* dec */ - NULL, /* enc */ - NULL, /* link */ - 0, - 0, - NULL, /* extra */ - 0, /* extras */ - NULL +cet_cs_vec_t cet_cs_vec_utf8 = { + CET_CHARSET_UTF8, + cet_cs_utf8_alias, + NULL, /* dec */ + NULL, /* enc */ + NULL, /* link */ + 0, + 0, + NULL, /* extra */ + 0, /* extras */ + NULL, + 0 }; void cet_register(void) { - int i, c; - - if (cet_cs_vec_root != NULL) return; - - cet_cs_vec_ct = 0; - cet_register_cs(&cet_cs_vec_utf8); /* internal place holder */ - + int i, c; + + if (cet_cs_vec_root != NULL) { + return; + } + + cet_cs_vec_ct = 0; + cet_register_cs(&cet_cs_vec_utf8); /* internal place holder */ + #ifdef cet_cs_name_ansi_x3_4_1968 -cet_register_cs(&cet_cs_vec_ansi_x3_4_1968); + cet_register_cs(&cet_cs_vec_ansi_x3_4_1968); #endif #ifdef cet_cs_name_atarist -cet_register_cs(&cet_cs_vec_atarist); + cet_register_cs(&cet_cs_vec_atarist); #endif #ifdef cet_cs_name_baltic -cet_register_cs(&cet_cs_vec_baltic); + cet_register_cs(&cet_cs_vec_baltic); #endif #ifdef cet_cs_name_bs_4730 -cet_register_cs(&cet_cs_vec_bs_4730); + cet_register_cs(&cet_cs_vec_bs_4730); #endif #ifdef cet_cs_name_bs_viewdata -cet_register_cs(&cet_cs_vec_bs_viewdata); + cet_register_cs(&cet_cs_vec_bs_viewdata); #endif #ifdef cet_cs_name_cp1250 -cet_register_cs(&cet_cs_vec_cp1250); + cet_register_cs(&cet_cs_vec_cp1250); #endif #ifdef cet_cs_name_cp1251 -cet_register_cs(&cet_cs_vec_cp1251); + cet_register_cs(&cet_cs_vec_cp1251); #endif #ifdef cet_cs_name_cp1252 -cet_register_cs(&cet_cs_vec_cp1252); + cet_register_cs(&cet_cs_vec_cp1252); #endif #ifdef cet_cs_name_cp1253 -cet_register_cs(&cet_cs_vec_cp1253); + cet_register_cs(&cet_cs_vec_cp1253); #endif #ifdef cet_cs_name_cp1254 -cet_register_cs(&cet_cs_vec_cp1254); + cet_register_cs(&cet_cs_vec_cp1254); #endif #ifdef cet_cs_name_cp1255 -cet_register_cs(&cet_cs_vec_cp1255); + cet_register_cs(&cet_cs_vec_cp1255); #endif #ifdef cet_cs_name_cp1256 -cet_register_cs(&cet_cs_vec_cp1256); + cet_register_cs(&cet_cs_vec_cp1256); #endif #ifdef cet_cs_name_cp1257 -cet_register_cs(&cet_cs_vec_cp1257); + cet_register_cs(&cet_cs_vec_cp1257); #endif #ifdef cet_cs_name_csa_z243_4_1985_1 -cet_register_cs(&cet_cs_vec_csa_z243_4_1985_1); + cet_register_cs(&cet_cs_vec_csa_z243_4_1985_1); #endif #ifdef cet_cs_name_csa_z243_4_1985_2 -cet_register_cs(&cet_cs_vec_csa_z243_4_1985_2); + cet_register_cs(&cet_cs_vec_csa_z243_4_1985_2); #endif #ifdef cet_cs_name_csa_z243_4_1985_gr -cet_register_cs(&cet_cs_vec_csa_z243_4_1985_gr); + cet_register_cs(&cet_cs_vec_csa_z243_4_1985_gr); #endif #ifdef cet_cs_name_csn_369103 -cet_register_cs(&cet_cs_vec_csn_369103); + cet_register_cs(&cet_cs_vec_csn_369103); #endif #ifdef cet_cs_name_cwi -cet_register_cs(&cet_cs_vec_cwi); + cet_register_cs(&cet_cs_vec_cwi); #endif #ifdef cet_cs_name_dec_mcs -cet_register_cs(&cet_cs_vec_dec_mcs); + cet_register_cs(&cet_cs_vec_dec_mcs); #endif #ifdef cet_cs_name_din_66003 -cet_register_cs(&cet_cs_vec_din_66003); + cet_register_cs(&cet_cs_vec_din_66003); #endif #ifdef cet_cs_name_ds_2089 -cet_register_cs(&cet_cs_vec_ds_2089); + cet_register_cs(&cet_cs_vec_ds_2089); #endif #ifdef cet_cs_name_ecma_cyrillic -cet_register_cs(&cet_cs_vec_ecma_cyrillic); + cet_register_cs(&cet_cs_vec_ecma_cyrillic); #endif #ifdef cet_cs_name_es -cet_register_cs(&cet_cs_vec_es); + cet_register_cs(&cet_cs_vec_es); #endif #ifdef cet_cs_name_es2 -cet_register_cs(&cet_cs_vec_es2); + cet_register_cs(&cet_cs_vec_es2); #endif #ifdef cet_cs_name_gb_1988_80 -cet_register_cs(&cet_cs_vec_gb_1988_80); + cet_register_cs(&cet_cs_vec_gb_1988_80); #endif #ifdef cet_cs_name_gost_19768_87 -cet_register_cs(&cet_cs_vec_gost_19768_87); + cet_register_cs(&cet_cs_vec_gost_19768_87); #endif #ifdef cet_cs_name_hp_roman8 -cet_register_cs(&cet_cs_vec_hp_roman8); + cet_register_cs(&cet_cs_vec_hp_roman8); #endif #ifdef cet_cs_name_ibm037 -cet_register_cs(&cet_cs_vec_ibm037); + cet_register_cs(&cet_cs_vec_ibm037); #endif #ifdef cet_cs_name_ibm1004 -cet_register_cs(&cet_cs_vec_ibm1004); + cet_register_cs(&cet_cs_vec_ibm1004); #endif #ifdef cet_cs_name_ibm1026 -cet_register_cs(&cet_cs_vec_ibm1026); + cet_register_cs(&cet_cs_vec_ibm1026); #endif #ifdef cet_cs_name_ibm1047 -cet_register_cs(&cet_cs_vec_ibm1047); + cet_register_cs(&cet_cs_vec_ibm1047); #endif #ifdef cet_cs_name_ibm256 -cet_register_cs(&cet_cs_vec_ibm256); + cet_register_cs(&cet_cs_vec_ibm256); #endif #ifdef cet_cs_name_ibm273 -cet_register_cs(&cet_cs_vec_ibm273); + cet_register_cs(&cet_cs_vec_ibm273); #endif #ifdef cet_cs_name_ibm277 -cet_register_cs(&cet_cs_vec_ibm277); + cet_register_cs(&cet_cs_vec_ibm277); #endif #ifdef cet_cs_name_ibm278 -cet_register_cs(&cet_cs_vec_ibm278); + cet_register_cs(&cet_cs_vec_ibm278); #endif #ifdef cet_cs_name_ibm280 -cet_register_cs(&cet_cs_vec_ibm280); + cet_register_cs(&cet_cs_vec_ibm280); #endif #ifdef cet_cs_name_ibm284 -cet_register_cs(&cet_cs_vec_ibm284); + cet_register_cs(&cet_cs_vec_ibm284); #endif #ifdef cet_cs_name_ibm285 -cet_register_cs(&cet_cs_vec_ibm285); + cet_register_cs(&cet_cs_vec_ibm285); #endif #ifdef cet_cs_name_ibm297 -cet_register_cs(&cet_cs_vec_ibm297); + cet_register_cs(&cet_cs_vec_ibm297); #endif #ifdef cet_cs_name_ibm437 -cet_register_cs(&cet_cs_vec_ibm437); + cet_register_cs(&cet_cs_vec_ibm437); #endif #ifdef cet_cs_name_ibm500 -cet_register_cs(&cet_cs_vec_ibm500); + cet_register_cs(&cet_cs_vec_ibm500); #endif #ifdef cet_cs_name_ibm850 -cet_register_cs(&cet_cs_vec_ibm850); + cet_register_cs(&cet_cs_vec_ibm850); #endif #ifdef cet_cs_name_ibm851 -cet_register_cs(&cet_cs_vec_ibm851); + cet_register_cs(&cet_cs_vec_ibm851); #endif #ifdef cet_cs_name_ibm852 -cet_register_cs(&cet_cs_vec_ibm852); + cet_register_cs(&cet_cs_vec_ibm852); #endif #ifdef cet_cs_name_ibm855 -cet_register_cs(&cet_cs_vec_ibm855); + cet_register_cs(&cet_cs_vec_ibm855); #endif #ifdef cet_cs_name_ibm857 -cet_register_cs(&cet_cs_vec_ibm857); + cet_register_cs(&cet_cs_vec_ibm857); #endif #ifdef cet_cs_name_ibm860 -cet_register_cs(&cet_cs_vec_ibm860); + cet_register_cs(&cet_cs_vec_ibm860); #endif #ifdef cet_cs_name_ibm861 -cet_register_cs(&cet_cs_vec_ibm861); + cet_register_cs(&cet_cs_vec_ibm861); #endif #ifdef cet_cs_name_ibm862 -cet_register_cs(&cet_cs_vec_ibm862); + cet_register_cs(&cet_cs_vec_ibm862); #endif #ifdef cet_cs_name_ibm863 -cet_register_cs(&cet_cs_vec_ibm863); + cet_register_cs(&cet_cs_vec_ibm863); #endif #ifdef cet_cs_name_ibm864 -cet_register_cs(&cet_cs_vec_ibm864); + cet_register_cs(&cet_cs_vec_ibm864); #endif #ifdef cet_cs_name_ibm865 -cet_register_cs(&cet_cs_vec_ibm865); + cet_register_cs(&cet_cs_vec_ibm865); #endif #ifdef cet_cs_name_ibm868 -cet_register_cs(&cet_cs_vec_ibm868); + cet_register_cs(&cet_cs_vec_ibm868); #endif #ifdef cet_cs_name_ibm869 -cet_register_cs(&cet_cs_vec_ibm869); + cet_register_cs(&cet_cs_vec_ibm869); #endif #ifdef cet_cs_name_ibm871 -cet_register_cs(&cet_cs_vec_ibm871); + cet_register_cs(&cet_cs_vec_ibm871); #endif #ifdef cet_cs_name_ibm891 -cet_register_cs(&cet_cs_vec_ibm891); + cet_register_cs(&cet_cs_vec_ibm891); #endif #ifdef cet_cs_name_ibm903 -cet_register_cs(&cet_cs_vec_ibm903); + cet_register_cs(&cet_cs_vec_ibm903); #endif #ifdef cet_cs_name_ibm904 -cet_register_cs(&cet_cs_vec_ibm904); + cet_register_cs(&cet_cs_vec_ibm904); #endif #ifdef cet_cs_name_iec_p27_1 -cet_register_cs(&cet_cs_vec_iec_p27_1); + cet_register_cs(&cet_cs_vec_iec_p27_1); #endif #ifdef cet_cs_name_iso_10367_box -cet_register_cs(&cet_cs_vec_iso_10367_box); + cet_register_cs(&cet_cs_vec_iso_10367_box); #endif #ifdef cet_cs_name_iso_5427 -cet_register_cs(&cet_cs_vec_iso_5427); + cet_register_cs(&cet_cs_vec_iso_5427); #endif #ifdef cet_cs_name_iso_646_irv -cet_register_cs(&cet_cs_vec_iso_646_irv); + cet_register_cs(&cet_cs_vec_iso_646_irv); #endif #ifdef cet_cs_name_iso_6937_2_25 -cet_register_cs(&cet_cs_vec_iso_6937_2_25); + cet_register_cs(&cet_cs_vec_iso_6937_2_25); #endif #ifdef cet_cs_name_iso_8859_1 -cet_register_cs(&cet_cs_vec_iso_8859_1); + cet_register_cs(&cet_cs_vec_iso_8859_1); #endif #ifdef cet_cs_name_iso_8859_10 -cet_register_cs(&cet_cs_vec_iso_8859_10); + cet_register_cs(&cet_cs_vec_iso_8859_10); #endif #ifdef cet_cs_name_iso_8859_13 -cet_register_cs(&cet_cs_vec_iso_8859_13); + cet_register_cs(&cet_cs_vec_iso_8859_13); #endif #ifdef cet_cs_name_iso_8859_14 -cet_register_cs(&cet_cs_vec_iso_8859_14); + cet_register_cs(&cet_cs_vec_iso_8859_14); #endif #ifdef cet_cs_name_iso_8859_15 -cet_register_cs(&cet_cs_vec_iso_8859_15); + cet_register_cs(&cet_cs_vec_iso_8859_15); #endif #ifdef cet_cs_name_iso_8859_2 -cet_register_cs(&cet_cs_vec_iso_8859_2); + cet_register_cs(&cet_cs_vec_iso_8859_2); #endif #ifdef cet_cs_name_iso_8859_3 -cet_register_cs(&cet_cs_vec_iso_8859_3); + cet_register_cs(&cet_cs_vec_iso_8859_3); #endif #ifdef cet_cs_name_iso_8859_4 -cet_register_cs(&cet_cs_vec_iso_8859_4); + cet_register_cs(&cet_cs_vec_iso_8859_4); #endif #ifdef cet_cs_name_iso_8859_5 -cet_register_cs(&cet_cs_vec_iso_8859_5); + cet_register_cs(&cet_cs_vec_iso_8859_5); #endif #ifdef cet_cs_name_iso_8859_6 -cet_register_cs(&cet_cs_vec_iso_8859_6); + cet_register_cs(&cet_cs_vec_iso_8859_6); #endif #ifdef cet_cs_name_iso_8859_7 -cet_register_cs(&cet_cs_vec_iso_8859_7); + cet_register_cs(&cet_cs_vec_iso_8859_7); #endif #ifdef cet_cs_name_iso_8859_8 -cet_register_cs(&cet_cs_vec_iso_8859_8); + cet_register_cs(&cet_cs_vec_iso_8859_8); #endif #ifdef cet_cs_name_iso_8859_9 -cet_register_cs(&cet_cs_vec_iso_8859_9); + cet_register_cs(&cet_cs_vec_iso_8859_9); #endif #ifdef cet_cs_name_iso_8859_supp -cet_register_cs(&cet_cs_vec_iso_8859_supp); + cet_register_cs(&cet_cs_vec_iso_8859_supp); #endif #ifdef cet_cs_name_it -cet_register_cs(&cet_cs_vec_it); + cet_register_cs(&cet_cs_vec_it); #endif #ifdef cet_cs_name_jis_c6220_1969_ro -cet_register_cs(&cet_cs_vec_jis_c6220_1969_ro); + cet_register_cs(&cet_cs_vec_jis_c6220_1969_ro); #endif #ifdef cet_cs_name_jis_x0201 -cet_register_cs(&cet_cs_vec_jis_x0201); + cet_register_cs(&cet_cs_vec_jis_x0201); #endif #ifdef cet_cs_name_jus_i_b1_002 -cet_register_cs(&cet_cs_vec_jus_i_b1_002); + cet_register_cs(&cet_cs_vec_jus_i_b1_002); #endif #ifdef cet_cs_name_jus_i_b1_003_mac -cet_register_cs(&cet_cs_vec_jus_i_b1_003_mac); + cet_register_cs(&cet_cs_vec_jus_i_b1_003_mac); #endif #ifdef cet_cs_name_jus_i_b1_003_serb -cet_register_cs(&cet_cs_vec_jus_i_b1_003_serb); + cet_register_cs(&cet_cs_vec_jus_i_b1_003_serb); #endif #ifdef cet_cs_name_keybcs2 -cet_register_cs(&cet_cs_vec_keybcs2); + cet_register_cs(&cet_cs_vec_keybcs2); #endif #ifdef cet_cs_name_koi8_r -cet_register_cs(&cet_cs_vec_koi8_r); + cet_register_cs(&cet_cs_vec_koi8_r); #endif #ifdef cet_cs_name_koi8_ru -cet_register_cs(&cet_cs_vec_koi8_ru); + cet_register_cs(&cet_cs_vec_koi8_ru); #endif #ifdef cet_cs_name_koi8_u -cet_register_cs(&cet_cs_vec_koi8_u); + cet_register_cs(&cet_cs_vec_koi8_u); #endif #ifdef cet_cs_name_koi_7 -cet_register_cs(&cet_cs_vec_koi_7); + cet_register_cs(&cet_cs_vec_koi_7); #endif #ifdef cet_cs_name_koi_8 -cet_register_cs(&cet_cs_vec_koi_8); + cet_register_cs(&cet_cs_vec_koi_8); #endif #ifdef cet_cs_name_koi_8_cs2 -cet_register_cs(&cet_cs_vec_koi_8_cs2); + cet_register_cs(&cet_cs_vec_koi_8_cs2); #endif #ifdef cet_cs_name_ksc5636 -cet_register_cs(&cet_cs_vec_ksc5636); + cet_register_cs(&cet_cs_vec_ksc5636); #endif #ifdef cet_cs_name_latin_greek_1 -cet_register_cs(&cet_cs_vec_latin_greek_1); + cet_register_cs(&cet_cs_vec_latin_greek_1); #endif #ifdef cet_cs_name_mac_is -cet_register_cs(&cet_cs_vec_mac_is); + cet_register_cs(&cet_cs_vec_mac_is); #endif #ifdef cet_cs_name_macintosh -cet_register_cs(&cet_cs_vec_macintosh); + cet_register_cs(&cet_cs_vec_macintosh); #endif #ifdef cet_cs_name_macintosh_ce -cet_register_cs(&cet_cs_vec_macintosh_ce); + cet_register_cs(&cet_cs_vec_macintosh_ce); #endif #ifdef cet_cs_name_msz_7795_3 -cet_register_cs(&cet_cs_vec_msz_7795_3); + cet_register_cs(&cet_cs_vec_msz_7795_3); #endif #ifdef cet_cs_name_nats_dano -cet_register_cs(&cet_cs_vec_nats_dano); + cet_register_cs(&cet_cs_vec_nats_dano); #endif #ifdef cet_cs_name_nats_sefi -cet_register_cs(&cet_cs_vec_nats_sefi); + cet_register_cs(&cet_cs_vec_nats_sefi); #endif #ifdef cet_cs_name_nc_nc00_10 -cet_register_cs(&cet_cs_vec_nc_nc00_10); + cet_register_cs(&cet_cs_vec_nc_nc00_10); #endif #ifdef cet_cs_name_nextstep -cet_register_cs(&cet_cs_vec_nextstep); + cet_register_cs(&cet_cs_vec_nextstep); #endif #ifdef cet_cs_name_nf_z_62_010 -cet_register_cs(&cet_cs_vec_nf_z_62_010); + cet_register_cs(&cet_cs_vec_nf_z_62_010); #endif #ifdef cet_cs_name_nf_z_62_010__1973_ -cet_register_cs(&cet_cs_vec_nf_z_62_010__1973_); + cet_register_cs(&cet_cs_vec_nf_z_62_010__1973_); #endif #ifdef cet_cs_name_ns_4551_1 -cet_register_cs(&cet_cs_vec_ns_4551_1); + cet_register_cs(&cet_cs_vec_ns_4551_1); #endif #ifdef cet_cs_name_ns_4551_2 -cet_register_cs(&cet_cs_vec_ns_4551_2); + cet_register_cs(&cet_cs_vec_ns_4551_2); #endif #ifdef cet_cs_name_pt -cet_register_cs(&cet_cs_vec_pt); + cet_register_cs(&cet_cs_vec_pt); #endif #ifdef cet_cs_name_pt2 -cet_register_cs(&cet_cs_vec_pt2); + cet_register_cs(&cet_cs_vec_pt2); #endif #ifdef cet_cs_name_sami -cet_register_cs(&cet_cs_vec_sami); + cet_register_cs(&cet_cs_vec_sami); #endif #ifdef cet_cs_name_sen_850200_b -cet_register_cs(&cet_cs_vec_sen_850200_b); + cet_register_cs(&cet_cs_vec_sen_850200_b); #endif #ifdef cet_cs_name_sen_850200_c -cet_register_cs(&cet_cs_vec_sen_850200_c); + cet_register_cs(&cet_cs_vec_sen_850200_c); #endif #ifdef cet_cs_name_tcvn -cet_register_cs(&cet_cs_vec_tcvn); + cet_register_cs(&cet_cs_vec_tcvn); #endif #ifdef cet_cs_name_viscii -cet_register_cs(&cet_cs_vec_viscii); + cet_register_cs(&cet_cs_vec_viscii); #endif #ifdef cet_cs_name_vps -cet_register_cs(&cet_cs_vec_vps); -#endif - - if ( cet_cs_vec_ct > 0) - { - cet_cs_vec_t *p; - cet_cs_alias_t *list; - c = 0; - - /* enumerate count of all names and aliases */ - - for (p = cet_cs_vec_root; p != NULL; p = p->next) - { - c++; - if (p->alias != NULL) - { - char **a = (char **)p->alias; - while ((*a) != NULL) - { - a++; - c++; - } - } - } - /* create name to vec table */ - - list = xcalloc(c, sizeof(*list)); - i = 0; - for (p = cet_cs_vec_root; p != NULL; p = p->next) - { - if (p->alias != NULL) - { - char **a = (char **)p->alias; - - list[i].name = xstrdup(p->name); - list[i].vec = p; - i++; - while (*a != NULL) - { - list[i].name = xstrdup(*a); - list[i].vec = p; - i++; - a++; - } - } - } - qsort(list, c, sizeof(*list), cet_cs_alias_qsort_cb); - cet_cs_alias = list; - cet_cs_alias_ct = c; - - /* install fallback for ascii-like (first 128 ch.) character sets */ - for (i = 1250; i <= 1258; i++) { - char name[16]; - cet_cs_vec_t *vec; - - snprintf(name, sizeof(name), "WIN-CP%d", i); - if ((vec = cet_find_cs_by_name(name))) - vec->fallback = &cet_cs_vec_ansi_x3_4_1968; - } - for (i = 1; i <= 15; i++) { - char name[16]; - cet_cs_vec_t *vec; - - snprintf(name, sizeof(name), "ISO-8859-%d", i); - if ((vec = cet_find_cs_by_name(name))) - vec->fallback = &cet_cs_vec_ansi_x3_4_1968; - } - } -#ifdef CET_DEBUG - printf("We have registered %d character sets with %d aliases\n", cet_cs_vec_ct, cet_cs_alias_ct); + cet_register_cs(&cet_cs_vec_vps); +#endif + + if (cet_cs_vec_ct > 0) { + cet_cs_vec_t* p; + cet_cs_alias_t* list; + c = 0; + + /* enumerate count of all names and aliases */ + + for (p = cet_cs_vec_root; p != NULL; p = p->next) { + c++; + if (p->alias != NULL) { + char** a = (char**)p->alias; + while ((*a) != NULL) { + a++; + c++; + } + } + } + /* create name to vec table */ + + list = (cet_cs_alias_t*) xcalloc(c, sizeof(*list)); + i = 0; + for (p = cet_cs_vec_root; p != NULL; p = p->next) { + if (p->alias != NULL) { + char** a = (char**)p->alias; + + list[i].name = xstrdup(p->name); + list[i].vec = p; + i++; + while (*a != NULL) { + list[i].name = xstrdup(*a); + list[i].vec = p; + i++; + a++; + } + } + } + qsort(list, c, sizeof(*list), cet_cs_alias_qsort_cb); + cet_cs_alias = list; + cet_cs_alias_ct = c; + + /* install fallback for ascii-like (first 128 ch.) character sets */ + for (i = 1250; i <= 1258; i++) { + char name[16]; + cet_cs_vec_t* vec; + + snprintf(name, sizeof(name), "WIN-CP%d", i); + if ((vec = cet_find_cs_by_name(name))) { + vec->fallback = &cet_cs_vec_ansi_x3_4_1968; + } + } + for (i = 1; i <= 15; i++) { + char name[16]; + cet_cs_vec_t* vec; + + snprintf(name, sizeof(name), "ISO-8859-%d", i); + if ((vec = cet_find_cs_by_name(name))) { + vec->fallback = &cet_cs_vec_ansi_x3_4_1968; + } + } + } +#ifdef CET_DEBUG + printf("We have registered %d character sets with %d aliases\n", cet_cs_vec_ct, cet_cs_alias_ct); #endif } -cet_cs_vec_t * -cet_find_cs_by_name(const char *name) +cet_cs_vec_t* +cet_find_cs_by_name(const char* name) { - int i, j; - - cet_register(); - - if (cet_cs_alias == NULL) return NULL; - - i = 0; - j = cet_cs_alias_ct - 1; - - while (i <= j) - { - int a, x; - cet_cs_alias_t *n; - - a = (i + j) >> 1; - n = &cet_cs_alias[a]; - x = case_ignore_strcmp(name, n->name); - if (x == 0) return n->vec; - else if (x < 0) j = a - 1; - else i = a + 1; - } - return NULL; + int i, j; + + cet_register(); + + if (cet_cs_alias == NULL) { + return NULL; + } + + i = 0; + j = cet_cs_alias_ct - 1; + + while (i <= j) { + int a, x; + cet_cs_alias_t* n; + + a = (i + j) >> 1; + n = &cet_cs_alias[a]; + x = case_ignore_strcmp(name, n->name); + if (x == 0) { + return n->vec; + } else if (x < 0) { + j = a - 1; + } else { + i = a + 1; + } + } + return NULL; } -void +void cet_deregister(void) { - int i; - int j = cet_cs_alias_ct; - cet_cs_alias_t *p = cet_cs_alias; - - if (p == NULL) return; - - cet_cs_alias_ct = 0; - cet_cs_alias = NULL; - - for (i = 0; i < j; i++) - xfree(p[i].name); - xfree(p); + int i; + int j = cet_cs_alias_ct; + cet_cs_alias_t* p = cet_cs_alias; + + if (p == NULL) { + return; + } + + cet_cs_alias_ct = 0; + cet_cs_alias = NULL; + + for (i = 0; i < j; i++) { + xfree(p[i].name); + } + xfree(p); } /* gpsbabel additions */ int -cet_validate_cs(const char *cs, cet_cs_vec_t **vec, char **cs_name) +cet_validate_cs(const char* cs, cet_cs_vec_t** vec, char** cs_name) { - cet_cs_vec_t *v; - - if ((cs == NULL) || (strlen(cs) == 0)) /* set default us-ascii */ - { - *vec = &cet_cs_vec_ansi_x3_4_1968; - *cs_name = xstrdup(CET_CHARSET_ASCII); - return 1; - } - - v = cet_find_cs_by_name(cs); - if (v != NULL) - { - *cs_name = strupper(xstrdup(v->name)); - *vec = v; - return 1; - } - else - { - *cs_name = NULL; - *vec = NULL; - return 0; - } + cet_cs_vec_t* v; + + if ((cs == NULL) || (strlen(cs) == 0)) { /* set default us-ascii */ + *vec = &cet_cs_vec_ansi_x3_4_1968; + *cs_name = xstrdup(CET_CHARSET_ASCII); + return 1; + } + + v = cet_find_cs_by_name(cs); + if (v != NULL) { + *cs_name = strupper(xstrdup(v->name)); + *vec = v; + return 1; + } else { + *cs_name = NULL; + *vec = NULL; + return 0; + } } void cet_convert_deinit(void) { - if (global_opts.charset_name != NULL) xfree(global_opts.charset_name); - global_opts.charset = NULL; - global_opts.charset_name = NULL; + if (global_opts.charset_name != NULL) { + xfree(global_opts.charset_name); + } + global_opts.charset = NULL; + global_opts.charset_name = NULL; } void -cet_convert_init(const char *cs_name, const int force) +cet_convert_init(const char* cs_name, const int force) { - if ((force != 0) || (global_opts.charset == NULL)) - { - cet_convert_deinit(); - if (0 == cet_validate_cs(cs_name, &global_opts.charset, &global_opts.charset_name)) - fatal("Unsupported character set \"%s\"!\n", cs_name); - } + if ((force != 0) || (global_opts.charset == NULL)) { + cet_convert_deinit(); + if (0 == cet_validate_cs(cs_name, &global_opts.charset, &global_opts.charset_name)) { + fatal("Unsupported character set \"%s\"!\n", cs_name); + } + } } /* -------------------------------------------------------------------- */ static void -cet_flag_waypt(const waypoint *wpt) +cet_flag_waypt(const waypoint* wpt) { - ((waypoint *)(wpt))->wpt_flags.cet_converted = 1; + ((waypoint*)(wpt))->wpt_flags.cet_converted = 1; } static void -cet_flag_route(const route_head *rte) +cet_flag_route(const route_head* rte) { - ((route_head *)(rte))->cet_converted = 1; + ((route_head*)(rte))->cet_converted = 1; } static void cet_flag_all(void) { - waypt_disp_all(cet_flag_waypt); - route_disp_all(cet_flag_route, NULL, cet_flag_waypt); - track_disp_all(cet_flag_route, NULL, cet_flag_waypt); + waypt_disp_all(cet_flag_waypt); + route_disp_all(cet_flag_route, NULL, cet_flag_waypt); + track_disp_all(cet_flag_route, NULL, cet_flag_waypt); } /* -------------------------------------------------------------------- */ /* %%% complete data strings transformation %%% */ /* -------------------------------------------------------------------- */ -static char * (*converter) (const char *) = NULL; +static char* (*converter)(const char*) = NULL; /* two converters */ -static char * -cet_convert_to_utf8(const char *str) +static char* +cet_convert_to_utf8(const char* str) { - return cet_str_any_to_utf8(str, global_opts.charset); + return cet_str_any_to_utf8(str, global_opts.charset); } -static char * -cet_convert_from_utf8(const char *str) +static char* +cet_convert_from_utf8(const char* str) { - return cet_str_utf8_to_any(str, global_opts.charset); + return cet_str_utf8_to_any(str, global_opts.charset); } /* cet_convert_string: internal used within cet_convert_strings process */ -char * -cet_convert_string(char *str) +char* +cet_convert_string(char* str) { - char *res; - - if (str == NULL) return NULL; /* return origin if empty or NULL */ - else if (*str == '\0') return str; - - res = converter(str); - xfree(str); - return res; + char* res; + + if (str == NULL) { + return NULL; /* return origin if empty or NULL */ + } else if (*str == '\0') { + return str; + } + + res = converter(str); + xfree(str); + return res; } /* cet_convert_waypt: internal used within cet_convert_strings process */ static void -cet_convert_waypt(const waypoint *wpt) +cet_convert_waypt(const waypoint* wpt) { - waypoint *w = (waypoint *)wpt; - format_specific_data *fs; - url_link *url_next; - geocache_data *gc_data = (geocache_data *)wpt->gc_data; - - if ((cet_output == 0) && (w->wpt_flags.cet_converted != 0)) return; - - w->wpt_flags.cet_converted = 1; - - w->shortname = cet_convert_string(wpt->shortname); - w->description = cet_convert_string(wpt->description); - w->notes = cet_convert_string(wpt->notes); - w->url = cet_convert_string(wpt->url); - w->url_link_text = cet_convert_string(wpt->url_link_text); - for (url_next = w->url_next; url_next; url_next = url_next->url_next) { - url_next->url = cet_convert_string(url_next->url); - url_next->url_link_text = cet_convert_string(url_next->url_link_text); - } - gc_data->placer = cet_convert_string(gc_data->placer); - gc_data->hint = cet_convert_string(gc_data->hint); - - fs = wpt->fs; - while (fs != NULL) - { - if (fs->convert != NULL) - fs->convert(fs); - fs = fs->next; - } + waypoint* w = (waypoint*)wpt; + format_specific_data* fs; + url_link* url_next; + geocache_data* gc_data = (geocache_data*)wpt->gc_data; + + if ((cet_output == 0) && (w->wpt_flags.cet_converted != 0)) { + return; + } + + w->wpt_flags.cet_converted = 1; + + w->shortname = cet_convert_string(wpt->shortname); + w->description = cet_convert_string(wpt->description); + w->notes = cet_convert_string(wpt->notes); + w->url = cet_convert_string(wpt->url); + w->url_link_text = cet_convert_string(wpt->url_link_text); + for (url_next = w->url_next; url_next; url_next = url_next->url_next) { + url_next->url = cet_convert_string(url_next->url); + url_next->url_link_text = cet_convert_string(url_next->url_link_text); + } + gc_data->placer = cet_convert_string(gc_data->placer); + gc_data->hint = cet_convert_string(gc_data->hint); + + fs = wpt->fs; + while (fs != NULL) { + if (fs->convert != NULL) { + fs->convert(fs); + } + fs = fs->next; + } } /* cet_convert_route_hdr: internal used within cet_convert_strings process */ static void -cet_convert_route_hdr(const route_head *route) +cet_convert_route_hdr(const route_head* route) { - route_head *rte = (route_head *)route; - - if ((cet_output == 0) && (rte->cet_converted != 0)) return; - - rte->cet_converted = 1; - - rte->rte_name = cet_convert_string(route->rte_name); - rte->rte_desc = cet_convert_string(route->rte_desc); - rte->rte_url = cet_convert_string(route->rte_url); + route_head* rte = (route_head*)route; + + if ((cet_output == 0) && (rte->cet_converted != 0)) { + return; + } + + rte->cet_converted = 1; + + rte->rte_name = cet_convert_string(route->rte_name); + rte->rte_desc = cet_convert_string(route->rte_desc); + rte->rte_url = cet_convert_string(route->rte_url); } /* cet_convert_route_tlr: internal used within cet_convert_strings process */ static void -cet_convert_route_tlr(const route_head *route) +cet_convert_route_tlr(const route_head* route) { } @@ -1080,141 +1089,144 @@ cet_convert_route_tlr(const route_head *route) * !!! One of "source" or "target" must be internal cet_cs_vec_utf8 or NULL !!! */ void -cet_convert_strings(const cet_cs_vec_t *source, const cet_cs_vec_t *target, const char *format) +cet_convert_strings(const cet_cs_vec_t* source, const cet_cs_vec_t* target, const char* format) { - char *cs_name_from, *cs_name_to; - - converter = NULL; - - if ((source == NULL) || (source == &cet_cs_vec_utf8)) - { - if ((target == NULL) || (target == &cet_cs_vec_utf8)) { - cet_flag_all(); - return; - } - - cet_output = 1; - - converter = cet_convert_from_utf8; - cs_name_from = (char *)cet_cs_vec_utf8.name; - cs_name_to = (char *)target->name; - } - else { - if ((target != NULL) && (target != &cet_cs_vec_utf8)) - fatal(MYNAME ": Internal error!\n"); - - cet_output = 0; - - converter = cet_convert_to_utf8; - cs_name_to = (char *)cet_cs_vec_utf8.name; - cs_name_from = (char *)source->name; - } - - if (global_opts.debug_level > 0) - printf(MYNAME ": Converting from \"%s\" to \"%s\"", cs_name_from, cs_name_to); - - waypt_disp_all(cet_convert_waypt); - route_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); - track_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); - - cet_output = 0; - - if (global_opts.debug_level > 0) - printf(", done.\n"); + char* cs_name_from, *cs_name_to; + + converter = NULL; + + if ((source == NULL) || (source == &cet_cs_vec_utf8)) { + if ((target == NULL) || (target == &cet_cs_vec_utf8)) { + cet_flag_all(); + return; + } + + cet_output = 1; + + converter = cet_convert_from_utf8; + cs_name_from = (char*)cet_cs_vec_utf8.name; + cs_name_to = (char*)target->name; + } else { + if ((target != NULL) && (target != &cet_cs_vec_utf8)) { + fatal(MYNAME ": Internal error!\n"); + } + + cet_output = 0; + + converter = cet_convert_to_utf8; + cs_name_to = (char*)cet_cs_vec_utf8.name; + cs_name_from = (char*)source->name; + } + + if (global_opts.debug_level > 0) { + printf(MYNAME ": Converting from \"%s\" to \"%s\"", cs_name_from, cs_name_to); + } + + waypt_disp_all(cet_convert_waypt); + route_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); + track_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); + + cet_output = 0; + + if (global_opts.debug_level > 0) { + printf(", done.\n"); + } } /* %%% cet_disp_character_set_names %%% * * - Put all character set names and aliases to "FILE" - */ - + void -cet_disp_character_set_names(FILE *fout) +cet_disp_character_set_names(FILE* fout) { - int i, c, ac; - cet_cs_vec_t *vec; - cet_cs_vec_t **list; - - if (cet_cs_alias_ct == 0) return; - - c = 0; - for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) c++; - - if (cet_cs_vec_ct != c) - fatal(MYNAME ": internal error \"%s\"!\n", "cet_disp_character_set_names"); - - list = (cet_cs_vec_t **)xcalloc(c, sizeof(*list)); - - i = 0; /* fill the list */ - for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) list[i++] = vec; - qsort(list, c, sizeof(*list), cet_cs_vec_qsort_cb); /* sort list by name */ - - ac = 0; - - fprintf(fout, "GPSBabel builtin character sets: (-c option)\n"); - for (i = 0; i < c; i++) - { - char **a; - - vec = list[i]; - fprintf(fout, "\n* %s", vec->name); - - a = (char **)vec->alias; - if (a != NULL) - { - int column = 0; - int alias = 0; - - while (*a != NULL) - { - if (case_ignore_strcmp(*a, vec->name) != 0) - { - ac++; - fprintf(fout, "%s%s%s", - (alias++ > 0) ? ", " : "", - (column++ % 6 == 0) ? "\n\t" : "", - *a); - } - a++; - } - } - } - fprintf(fout, "\n\n"); - fprintf(fout, "We have %d builtin character sets with %d aliases!\n", c, ac); - xfree(list); + int i, c, ac; + cet_cs_vec_t* vec; + cet_cs_vec_t** list; + + if (cet_cs_alias_ct == 0) { + return; + } + + c = 0; + for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) { + c++; + } + + if (cet_cs_vec_ct != c) { + fatal(MYNAME ": internal error \"%s\"!\n", "cet_disp_character_set_names"); + } + + list = (cet_cs_vec_t**)xcalloc(c, sizeof(*list)); + + i = 0; /* fill the list */ + for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) { + list[i++] = vec; + } + qsort(list, c, sizeof(*list), cet_cs_vec_qsort_cb); /* sort list by name */ + + ac = 0; + + fprintf(fout, "GPSBabel builtin character sets: (-c option)\n"); + for (i = 0; i < c; i++) { + char** a; + + vec = list[i]; + fprintf(fout, "\n* %s", vec->name); + + a = (char**)vec->alias; + if (a != NULL) { + int column = 0; + int alias = 0; + + while (*a != NULL) { + if (case_ignore_strcmp(*a, vec->name) != 0) { + ac++; + fprintf(fout, "%s%s%s", + (alias++ > 0) ? ", " : "", + (column++ % 6 == 0) ? "\n\t" : "", + *a); + } + a++; + } + } + } + fprintf(fout, "\n\n"); + fprintf(fout, "We have %d builtin character sets with %d aliases!\n", c, ac); + xfree(list); } /* %%% cet_fprintf / cet_vfprintf %%% * * - print any special hard-coded characters from inside a module - */ -int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, ...) +int cet_gbfprintf(gbfile* stream, const cet_cs_vec_t* src_vec, const char* fmt, ...) { - int res; - char *cout; - va_list args; - - va_start(args, fmt); - xvasprintf(&cout, fmt, args); - va_end(args); - - if (global_opts.charset != src_vec) - { - if (src_vec != &cet_cs_vec_utf8) { - char *ctemp = cet_str_any_to_utf8(cout, src_vec); - xfree(cout); - cout = ctemp; - } - if (global_opts.charset != &cet_cs_vec_utf8) { - char *ctemp = cet_str_utf8_to_any(cout, global_opts.charset); - xfree(cout); - cout = ctemp; - } - } - - res = gbfprintf(stream, "%s", cout); - xfree(cout); - - return res; + int res; + char* cout; + va_list args; + + va_start(args, fmt); + xvasprintf(&cout, fmt, args); + va_end(args); + + if (global_opts.charset != src_vec) { + if (src_vec != &cet_cs_vec_utf8) { + char* ctemp = cet_str_any_to_utf8(cout, src_vec); + xfree(cout); + cout = ctemp; + } + if (global_opts.charset != &cet_cs_vec_utf8) { + char* ctemp = cet_str_utf8_to_any(cout, global_opts.charset); + xfree(cout); + cout = ctemp; + } + } + + res = gbfprintf(stream, "%s", cout); + xfree(cout); + + return res; } /* @@ -1222,104 +1234,107 @@ int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, * words in native endianness. */ -const char *xml_convert_to_char_string_n(const XML_Char *src, int *n) +const char* xml_convert_to_char_string_n(const XML_Char* src, int* n) { -#ifdef XML_UNICODE - char *utf8; - char *utf8b; - int i, j; - - /* - * '*n' is the number of source bytes. - * Walk over that, converting each character and - * discarding it, but tallying 'i' as the number of - * bytes in the destination string. - */ - i = 0; - for (j = 0; j < *n; j++) { - i += cet_ucs4_to_utf8(NULL, 6, src[j]); - } - - /* Update output byte count in caller. */ - *n = i; - - /* Appropriately size (not zero terminated) buffer */ - utf8 = utf8b = xmalloc(i); - - for (j = 0; utf8 < utf8b + i; j++) { - utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); - } - - return utf8b; -#else - return src; -#endif +#ifdef XML_UNICODE + char* utf8; + char* utf8b; + int i, j; + + /* + * '*n' is the number of source bytes. + * Walk over that, converting each character and + * discarding it, but tallying 'i' as the number of + * bytes in the destination string. + */ + i = 0; + for (j = 0; j < *n; j++) { + i += cet_ucs4_to_utf8(NULL, 6, src[j]); + } + + /* Update output byte count in caller. */ + *n = i; + + /* Appropriately size (not zero terminated) buffer */ + utf8 = utf8b = xmalloc(i); + + for (j = 0; utf8 < utf8b + i; j++) { + utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); + } + + return utf8b; +#else + return src; +#endif } /* - * 'str' points to NULL terminated string of XML_Chars which + * 'str' points to NULL terminated string of XML_Chars which * may be UNICODE16 words in native endianness. */ -const char *xml_convert_to_char_string(const XML_Char *src) +const char* xml_convert_to_char_string(const XML_Char* src) { -#ifdef XML_UNICODE - char *utf8; - char *utf8b; - int i, j; - const XML_Char *in = src; - - /* Walk source array until we find source terminator */ - i = 0; - for (j = 0; src[j]; j++) { - i += cet_ucs4_to_utf8(NULL, 6, src[j]); - } - - /* We return a NUL terminated string. */ - utf8 = utf8b = xmalloc(i + 1); - in = src; - - for (j = 0; utf8 < utf8b + i; j++) { - utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); - } - *utf8 = '\0'; - - return utf8b; - +#ifdef XML_UNICODE + char* utf8; + char* utf8b; + int i, j; + const XML_Char* in = src; + + /* Walk source array until we find source terminator */ + i = 0; + for (j = 0; src[j]; j++) { + i += cet_ucs4_to_utf8(NULL, 6, src[j]); + } + + /* We return a NUL terminated string. */ + utf8 = utf8b = xmalloc(i + 1); + in = src; + + for (j = 0; utf8 < utf8b + i; j++) { + utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); + } + *utf8 = '\0'; + + return utf8b; + #else - return src; -#endif + return src; +#endif } -void xml_free_converted_string(const char *str) +void xml_free_converted_string(const char* str) { -#ifdef XML_UNICODE - xfree((void *) str); -#endif +#ifdef XML_UNICODE + xfree((void*) str); +#endif } -const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr) +const char** xml_convert_attrs_to_char_string(const XML_Char** xml_attr) { #ifdef XML_UNICODE // First count size of array int size = 0; int i; - const XML_Char **ptr; - const char **char_attrs; + const XML_Char** ptr; + const char** char_attrs; - if (xml_attr == NULL) + if (xml_attr == NULL) { return NULL; + } - for (ptr = xml_attr; *ptr != NULL; ++ptr) + for (ptr = xml_attr; *ptr != NULL; ++ptr) { ++size; + } // Allocate space - char_attrs = xmalloc((size + 1) * sizeof(char *)); + char_attrs = xmalloc((size + 1) * sizeof(char*)); // Duplicate strings - for (i = 0; i < size; ++i) + for (i = 0; i < size; ++i) { char_attrs[i] = xml_convert_to_char_string(xml_attr[i]); + } char_attrs[size] = NULL; return char_attrs; @@ -1328,12 +1343,12 @@ const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr) #endif } -void xml_free_converted_attrs(const char **attr) +void xml_free_converted_attrs(const char** attr) { -#ifdef XML_UNICODE - while (attr != NULL && *attr != NULL) { - xfree((void *)*attr); - ++attr; - } +#ifdef XML_UNICODE + while (attr != NULL && *attr != NULL) { + xfree((void*)*attr); + ++attr; + } #endif } diff --git a/gpsbabel/cet_util.h b/gpsbabel/cet_util.h index 1fc12062f..abb5d3345 100644 --- a/gpsbabel/cet_util.h +++ b/gpsbabel/cet_util.h @@ -36,29 +36,29 @@ typedef char XML_Char; #include "cet.h" -cet_cs_vec_t *cet_find_cs_by_name(const char *name); +cet_cs_vec_t* cet_find_cs_by_name(const char* name); void cet_register(void); void cet_deregister(void); /* short hand transmissions */ -char *cet_str_utf8_to_cp1252(const char *src); -char *cet_str_cp1252_to_utf8(const char *src); +char* cet_str_utf8_to_cp1252(const char* src); +char* cet_str_cp1252_to_utf8(const char* src); extern cet_cs_vec_t cet_cs_vec_cp1252; -char *cet_str_iso8859_1_to_utf8(const char *src); -char *cet_str_utf8_to_iso8859_1(const char *src); +char* cet_str_iso8859_1_to_utf8(const char* src); +char* cet_str_utf8_to_iso8859_1(const char* src); extern cet_cs_vec_t cet_cs_vec_iso8859_1; -char *cet_str_iso8859_15_to_utf8(const char *src); -char *cet_str_utf8_to_iso8859_15(const char *src); +char* cet_str_iso8859_15_to_utf8(const char* src); +char* cet_str_utf8_to_iso8859_15(const char* src); extern const cet_cs_vec_t cet_cs_vec_iso8859_15; -char *cet_str_utf8_to_us_ascii(const char *src); -char *cet_str_us_ascii_to_utf8(const char *src); +char* cet_str_utf8_to_us_ascii(const char* src); +char* cet_str_us_ascii_to_utf8(const char* src); extern cet_cs_vec_t cet_cs_vec_ansi_x3_4_1968; -short *cet_str_utf8_to_uni(const char *src, int *length); +short* cet_str_utf8_to_uni(const char* src, int* length); extern cet_cs_vec_t cet_cs_vec_utf8; @@ -67,7 +67,7 @@ extern cet_cs_vec_t cet_cs_vec_utf8; /* Taken from expat_external.h (Expat 1.95.7) */ -#ifndef XML_STATUS_OK +#ifndef XML_STATUS_OK # define XML_STATUS_OK 1 #endif #ifndef XML_STATUS_ERROR @@ -96,27 +96,27 @@ extern cet_cs_vec_t cet_cs_vec_utf8; #endif /* not defined XMLCALL */ #if HAVE_LIBEXPAT -int XMLCALL cet_lib_expat_UnknownEncodingHandler(void *data, const XML_Char *encoding, XML_Encoding *info); +int XMLCALL cet_lib_expat_UnknownEncodingHandler(void* data, const XML_Char* encoding, XML_Encoding* info); #endif /* helpers */ -char *cet_str_uni_to_any(const short *src, int length, const cet_cs_vec_t *dest_vec); -char *cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_vec_t *dest_vec); -int cet_valid_char(const char *src, const cet_cs_vec_t *vec); +char* cet_str_uni_to_any(const short* src, int length, const cet_cs_vec_t* dest_vec); +char* cet_str_any_to_any(const char* src, const cet_cs_vec_t* src_vec, const cet_cs_vec_t* dest_vec); +int cet_valid_char(const char* src, const cet_cs_vec_t* vec); -int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, ...); +int cet_gbfprintf(gbfile* stream, const cet_cs_vec_t* src_vec, const char* fmt, ...); /* cet_convert_string: !!! ONLY VALID WITHIN 'cet_convert_strings' process !!! */ -char *cet_convert_string(char *str); +char* cet_convert_string(char* str); /* gpsbabel extensions */ -void cet_convert_init(const char *cs_name, const int force); -void cet_convert_strings(const cet_cs_vec_t *source, const cet_cs_vec_t *target, const char *format); +void cet_convert_init(const char* cs_name, const int force); +void cet_convert_strings(const cet_cs_vec_t* source, const cet_cs_vec_t* target, const char* format); void cet_convert_deinit(void); -void cet_disp_character_set_names(FILE *fout); +void cet_disp_character_set_names(FILE* fout); /* * Conversion from XML_Char string to char string. If XML_Char is the @@ -126,11 +126,11 @@ void cet_disp_character_set_names(FILE *fout); * it. */ -const char *xml_convert_to_char_string_n(const XML_Char *str, int *nbytes); -const char *xml_convert_to_char_string(const XML_Char *str); -void xml_free_converted_string(const char *str); +const char* xml_convert_to_char_string_n(const XML_Char* str, int* nbytes); +const char* xml_convert_to_char_string(const XML_Char* str); +void xml_free_converted_string(const char* str); -const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr); -void xml_free_converted_attrs(const char **attr); +const char** xml_convert_attrs_to_char_string(const XML_Char** xml_attr); +void xml_free_converted_attrs(const char** attr); #endif diff --git a/gpsbabel/cetus.c b/gpsbabel/cetus.c index 9dc56e6d0..a96e36d91 100644 --- a/gpsbabel/cetus.c +++ b/gpsbabel/cetus.c @@ -22,12 +22,12 @@ /* History: - + 2005/08/03: Added track_read by O.K. (Thanx to Adam Schneider for additional information) */ - + #include "defs.h" #if PDBFMTS_ENABLED #include "pdbfile.h" @@ -43,592 +43,624 @@ #define DESCSZ 4096 typedef enum { - WptEdit = 0, /* the position has been edited or it was */ - /* imported from another source */ - WptGPS2D = 1, /* retrieved from a GPS with a 2D fix */ - WptGPS3D = 2, /* retrieved from a GPS with a 3D fix */ - WptDGPS2D = 3, /* retrieved from a GPS with a 2D fix and DGPS signal */ - WptDGPS3D = 4, /* retrieved from a GPS with a 3D fix and DGPS signal */ - WptAverage = 5, /* averaging over 3D positions */ - WptCache = 50, /* this position is a geocache reference */ - WptGarmin = 70 /* this position was imported from a Garmin GPS */ - /* the icon field contains the garmin symbol number */ + WptEdit = 0, /* the position has been edited or it was */ + /* imported from another source */ + WptGPS2D = 1, /* retrieved from a GPS with a 2D fix */ + WptGPS3D = 2, /* retrieved from a GPS with a 3D fix */ + WptDGPS2D = 3, /* retrieved from a GPS with a 2D fix and DGPS signal */ + WptDGPS3D = 4, /* retrieved from a GPS with a 3D fix and DGPS signal */ + WptAverage = 5, /* averaging over 3D positions */ + WptCache = 50, /* this position is a geocache reference */ + WptGarmin = 70 /* this position was imported from a Garmin GPS */ + /* the icon field contains the garmin symbol number */ } wpt_type; struct cetus_wpt_s { - char type; - - char readonly; - - pdb_32 latitude; /* Big endian, degrees*1e7, s=negative */ - pdb_32 longitude; /* same as lat; w=negative */ - pdb_32 elevation; /* Big endian, meters*100. blank=-1e8 */ - - pdb_16 year; /* sample time, UTC */ - unsigned char mon; - unsigned char day; - unsigned char hour; - unsigned char min; - unsigned char sec; - - /* accuracy and precision information for use where applicable */ - unsigned char sat; /* ff if averaged or unknown */ - pdb_16 pdop; /* pdop * 100 */ - pdb_16 hdop; - pdb_16 vdop; - pdb_16 dgpstime; - pdb_32 dgpsstn; - pdb_32 avgtime; - pdb_32 avgite; - - pdb_16 dopmask; - pdb_16 elevmask; - - pdb_16 radius; - pdb_32 distance; - - pdb_16 vyear; /* date visited */ - unsigned char vmon; - unsigned char vday; - unsigned char vhour; - unsigned char vmin; - unsigned char vsec; - - char flagged; - - pdb_32 icon; - pdb_16 category; + char type; + + char readonly; + + pdb_32 latitude; /* Big endian, degrees*1e7, s=negative */ + pdb_32 longitude; /* same as lat; w=negative */ + pdb_32 elevation; /* Big endian, meters*100. blank=-1e8 */ + + pdb_16 year; /* sample time, UTC */ + unsigned char mon; + unsigned char day; + unsigned char hour; + unsigned char min; + unsigned char sec; + + /* accuracy and precision information for use where applicable */ + unsigned char sat; /* ff if averaged or unknown */ + pdb_16 pdop; /* pdop * 100 */ + pdb_16 hdop; + pdb_16 vdop; + pdb_16 dgpstime; + pdb_32 dgpsstn; + pdb_32 avgtime; + pdb_32 avgite; + + pdb_16 dopmask; + pdb_16 elevmask; + + pdb_16 radius; + pdb_32 distance; + + pdb_16 vyear; /* date visited */ + unsigned char vmon; + unsigned char vday; + unsigned char vhour; + unsigned char vmin; + unsigned char vsec; + + char flagged; + + pdb_32 icon; + pdb_16 category; }; -typedef struct cetus_track_head_s -{ - char id[2]; - char version; - unsigned char interval; - unsigned short gps; - char year; - char month; - char day; - char hour; - char min; - char sec; - char dsec; - char tz; - char desc; +typedef struct cetus_track_head_s { + char id[2]; + char version; + unsigned char interval; + unsigned short gps; + char year; + char month; + char day; + char hour; + char min; + char sec; + char dsec; + char tz; + char desc; } cetus_track_head_t; #define TRACK_HEAD_SIZE sizeof(struct cetus_track_head_s) -typedef struct cetus_track_point_s -{ - signed char hour; - signed char min; - signed char sec; - signed char dsec; - signed char sat; - signed char hdop; - pdb_32 latitude; - pdb_32 longitude; - short speed; - short course; - pdb_32 elevation; +typedef struct cetus_track_point_s { + signed char hour; + signed char min; + signed char sec; + signed char dsec; + signed char sat; + signed char hdop; + pdb_32 latitude; + pdb_32 longitude; + short speed; + short course; + pdb_32 elevation; } cetus_track_point_t; #define TRACK_POINT_SIZE sizeof(struct cetus_track_point_s) -static pdbfile *file_in, *file_out; -static const char *out_fname; +static pdbfile* file_in, *file_out; +static const char* out_fname; static short_handle mkshort_wr_handle; static int ct; -static char *dbname = NULL; -static char *appendicon = NULL; +static char* dbname = NULL; +static char* appendicon = NULL; static arglist_t cetus_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, - ARG_NOMINMAX }, - {"appendicon", &appendicon, "Append icon_descr to description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + "appendicon", &appendicon, "Append icon_descr to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static waypoint * -read_track_point(cetus_track_point_t *data, const time_t basetime) +static waypoint* +read_track_point(cetus_track_point_t* data, const time_t basetime) { - int i, ilat, ilon; - waypoint *wpt; - - ilat = be_read32(&data->latitude); - ilon = be_read32(&data->longitude); - - if (data->hour == -1 || data->min == -1 || data->sec == -1 || - ilat == 2000000000 || ilon == 2000000000) return NULL; /* At least one of basic data is not available */ - - wpt = waypt_new(); - - wpt->latitude = (double)ilat / 10000000.0; - wpt->longitude = (double)ilon / 10000000.0; - - i = be_read32(&data->elevation); - wpt->altitude = (i == -100000000) ? unknown_alt : (double) i / 100.0; - - if (data->sat != -1) wpt->sat = data->sat; - if (data->hdop != -1) wpt->hdop = (float) data->hdop / 10; - - i = be_read16(&data->speed); - if (i != 10000) WAYPT_SET(wpt, speed, KNOTS_TO_MPS((float) i / 10)); /* meters/second */ - i = be_read16(&data->course); - if (i != 4000) WAYPT_SET(wpt, course, (float) i / 10); - - switch(data->hour >> 5) /* extract fix */ - { - case 1: wpt->fix = fix_none; break; - case 2: wpt->fix = fix_2d; break; - case 3: wpt->fix = fix_3d; break; - case 4: wpt->fix = fix_dgps; break; - default: break; /* no GPS */ - } - - wpt->creation_time = basetime + - ((data->hour & 0x1F) * 3600) + (data->min * 60) + data->sec; - if (data->dsec) - wpt->microseconds = (int)data->dsec * 10000; - - return wpt; + int i, ilat, ilon; + waypoint* wpt; + + ilat = be_read32(&data->latitude); + ilon = be_read32(&data->longitude); + + if (data->hour == -1 || data->min == -1 || data->sec == -1 || + ilat == 2000000000 || ilon == 2000000000) { + return NULL; /* At least one of basic data is not available */ + } + + wpt = waypt_new(); + + wpt->latitude = (double)ilat / 10000000.0; + wpt->longitude = (double)ilon / 10000000.0; + + i = be_read32(&data->elevation); + wpt->altitude = (i == -100000000) ? unknown_alt : (double) i / 100.0; + + if (data->sat != -1) { + wpt->sat = data->sat; + } + if (data->hdop != -1) { + wpt->hdop = (float) data->hdop / 10; + } + + i = be_read16(&data->speed); + if (i != 10000) { + WAYPT_SET(wpt, speed, KNOTS_TO_MPS((float) i / 10)); /* meters/second */ + } + i = be_read16(&data->course); + if (i != 4000) { + WAYPT_SET(wpt, course, (float) i / 10); + } + + switch (data->hour >> 5) { /* extract fix */ + case 1: + wpt->fix = fix_none; + break; + case 2: + wpt->fix = fix_2d; + break; + case 3: + wpt->fix = fix_3d; + break; + case 4: + wpt->fix = fix_dgps; + break; + default: + break; /* no GPS */ + } + + wpt->creation_time = basetime + + ((data->hour & 0x1F) * 3600) + (data->min * 60) + data->sec; + if (data->dsec) { + wpt->microseconds = (int)data->dsec * 10000; + } + + return wpt; } - + static void -read_tracks(const pdbfile *pdb) +read_tracks(const pdbfile* pdb) { - pdbrec_t *pdb_rec; - int reclen, records, total, points, dropped; - char descr[(2 * TRACK_POINT_SIZE) + 1]; - char temp_descr[TRACK_POINT_SIZE + 1]; - cetus_track_head_t *head; - waypoint *wpt; - route_head *track; - time_t basetime; - - track = route_head_alloc(); - track_add_head(track); - - total = 0; - points = 0; - dropped = 0; - basetime = 0; - - for (pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - int i, magic; - char *c = (char *)pdb_rec->data; - - magic = be_read32(c); - if (magic != MYTRACK) - fatal(MYNAME ": Invaid track data or unsupported version!\n"); - - reclen = be_read32(c+4); - records = reclen / TRACK_POINT_SIZE; - - c += 8; - - for (i = 0; i < records; i++, c += TRACK_POINT_SIZE) - { - switch(total++) - { - struct tm tm; - - case 0: /* track header */ - head = (cetus_track_head_t *)c; - if (head->id[0] != 'C' || head->id[1] != 'G') - fatal(MYNAME ": Invalid track header!\n"); - - memset(&tm, 0, sizeof(tm)); - tm.tm_mday = head->day; - tm.tm_mon = head->month - 1; - tm.tm_year = head->year + 100; - basetime = mkgmtime(&tm); - break; - - case 1: /* first part of description */ - strncpy(descr, c, TRACK_POINT_SIZE); - break; - - case 2: /* continued description */ - strncpy(temp_descr, c, TRACK_POINT_SIZE); - strcat(descr, temp_descr); /* here is no need to check target size */ - if (strlen(descr) > 0) - track->rte_desc = xstrdup(descr); - break; - - default: - wpt = read_track_point((cetus_track_point_t *)c, basetime); - if (wpt != NULL) - { - track_add_wpt(track, wpt); - points++; - } - else - dropped++; - } - - } - } - - if (global_opts.verbose_status > 0) - { - printf(MYNAME ": Loaded %d track point(s) from source.\n", points); - if (dropped > 0) - printf(MYNAME ": ! %d dropped because of missing data (no time, no coordinates) !\n", dropped); - } + pdbrec_t* pdb_rec; + int reclen, records, total, points, dropped; + char descr[(2 * TRACK_POINT_SIZE) + 1]; + char temp_descr[TRACK_POINT_SIZE + 1]; + cetus_track_head_t* head; + waypoint* wpt; + route_head* track; + time_t basetime; + + track = route_head_alloc(); + track_add_head(track); + + total = 0; + points = 0; + dropped = 0; + basetime = 0; + + for (pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + int i, magic; + char* c = (char*)pdb_rec->data; + + magic = be_read32(c); + if (magic != MYTRACK) { + fatal(MYNAME ": Invaid track data or unsupported version!\n"); + } + + reclen = be_read32(c+4); + records = reclen / TRACK_POINT_SIZE; + + c += 8; + + for (i = 0; i < records; i++, c += TRACK_POINT_SIZE) { + switch (total++) { + struct tm tm; + + case 0: /* track header */ + head = (cetus_track_head_t*)c; + if (head->id[0] != 'C' || head->id[1] != 'G') { + fatal(MYNAME ": Invalid track header!\n"); + } + + memset(&tm, 0, sizeof(tm)); + tm.tm_mday = head->day; + tm.tm_mon = head->month - 1; + tm.tm_year = head->year + 100; + basetime = mkgmtime(&tm); + break; + + case 1: /* first part of description */ + strncpy(descr, c, TRACK_POINT_SIZE); + break; + + case 2: /* continued description */ + strncpy(temp_descr, c, TRACK_POINT_SIZE); + strcat(descr, temp_descr); /* here is no need to check target size */ + if (strlen(descr) > 0) { + track->rte_desc = xstrdup(descr); + } + break; + + default: + wpt = read_track_point((cetus_track_point_t*)c, basetime); + if (wpt != NULL) { + track_add_wpt(track, wpt); + points++; + } else { + dropped++; + } + } + + } + } + + if (global_opts.verbose_status > 0) { + printf(MYNAME ": Loaded %d track point(s) from source.\n", points); + if (dropped > 0) { + printf(MYNAME ": ! %d dropped because of missing data (no time, no coordinates) !\n", dropped); + } + } } static void -read_waypts(const pdbfile *pdb) +read_waypts(const pdbfile* pdb) { - struct cetus_wpt_s *rec; - pdbrec_t *pdb_rec; - char *vdata; - - for(pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - waypoint *wpt_tmp; - int i; - - wpt_tmp = waypt_new(); - - rec = (struct cetus_wpt_s *) pdb_rec->data; - if ( be_read32(&rec->elevation) == -100000000 ) { - wpt_tmp->altitude = unknown_alt; - } - else { - wpt_tmp->altitude = be_read32(&rec->elevation) / 100.0; - } - - wpt_tmp->latitude = be_read32(&rec->latitude) / 10000000.0; - wpt_tmp->longitude = be_read32(&rec->longitude) / 10000000.0; - - if (rec->sat != 0xff) - wpt_tmp->sat = rec->sat; - - i = be_read16(&rec->pdop); - if (i != 0xffff) wpt_tmp->pdop = i / 100.0; - i = be_read16(&rec->hdop); - if (i != 0xffff) wpt_tmp->hdop = i / 100.0; - i = be_read16(&rec->vdop); - if (i != 0xffff) wpt_tmp->vdop = i / 100.0; - - switch (rec->type) { - case WptGPS2D: wpt_tmp->fix = fix_2d; break; - case WptGPS3D: wpt_tmp->fix = fix_3d; break; - case WptDGPS2D: wpt_tmp->fix = fix_dgps; break; - case WptDGPS3D: wpt_tmp->fix = fix_dgps; break; - } - - if (be_read16(&rec->year) != 0xff) { - struct tm tm; - - memset (&tm, 0, sizeof(tm)); - tm.tm_min = rec->min; - tm.tm_hour = rec->hour; - tm.tm_mday = rec->day; - tm.tm_mon = rec->mon - 1; - tm.tm_year = be_read16(&rec->year) - 1900; - - wpt_tmp->creation_time = mkgmtime(&tm); - - } - - vdata = (char *) pdb_rec->data + sizeof(*rec); - - wpt_tmp->shortname = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->description = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->notes = xstrdup(vdata); - - waypt_add(wpt_tmp); - - } + struct cetus_wpt_s* rec; + pdbrec_t* pdb_rec; + char* vdata; + + for (pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint* wpt_tmp; + int i; + + wpt_tmp = waypt_new(); + + rec = (struct cetus_wpt_s*) pdb_rec->data; + if (be_read32(&rec->elevation) == -100000000) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = be_read32(&rec->elevation) / 100.0; + } + + wpt_tmp->latitude = be_read32(&rec->latitude) / 10000000.0; + wpt_tmp->longitude = be_read32(&rec->longitude) / 10000000.0; + + if (rec->sat != 0xff) { + wpt_tmp->sat = rec->sat; + } + + i = be_read16(&rec->pdop); + if (i != 0xffff) { + wpt_tmp->pdop = i / 100.0; + } + i = be_read16(&rec->hdop); + if (i != 0xffff) { + wpt_tmp->hdop = i / 100.0; + } + i = be_read16(&rec->vdop); + if (i != 0xffff) { + wpt_tmp->vdop = i / 100.0; + } + + switch (rec->type) { + case WptGPS2D: + wpt_tmp->fix = fix_2d; + break; + case WptGPS3D: + wpt_tmp->fix = fix_3d; + break; + case WptDGPS2D: + wpt_tmp->fix = fix_dgps; + break; + case WptDGPS3D: + wpt_tmp->fix = fix_dgps; + break; + } + + if (be_read16(&rec->year) != 0xff) { + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + tm.tm_min = rec->min; + tm.tm_hour = rec->hour; + tm.tm_mday = rec->day; + tm.tm_mon = rec->mon - 1; + tm.tm_year = be_read16(&rec->year) - 1900; + + wpt_tmp->creation_time = mkgmtime(&tm); + + } + + vdata = (char*) pdb_rec->data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + waypt_add(wpt_tmp); + + } } /* --------------------------------------------------------------------------- */ static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_in); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void data_read(void) { - if (file_in->creator != MYCREATOR) fatal(MYNAME ": Not a Cetus file.\n"); - - switch(file_in->type) - { - case MYTYPE_TRK: - read_tracks(file_in); - break; - - case MYTYPE_WPT: - read_waypts(file_in); - break; - } + if (file_in->creator != MYCREATOR) { + fatal(MYNAME ": Not a Cetus file.\n"); + } + + switch (file_in->type) { + case MYTYPE_TRK: + read_tracks(file_in); + break; + + case MYTYPE_WPT: + read_waypts(file_in); + break; + } } static void -cetus_writewpt(const waypoint *wpt) +cetus_writewpt(const waypoint* wpt) { - struct cetus_wpt_s *rec; - struct tm *tm; - char *vdata; - char *desc_long; - char *desc_short; - char *desc_geo; - char *desc; - - rec = (struct cetus_wpt_s*) xcalloc(sizeof(*rec)+18 + NOTESZ + DESCSZ,1); - - if (wpt->creation_time && (NULL != (tm = gmtime(&wpt->creation_time)))){ - rec->min = tm->tm_min; - rec->hour = tm->tm_hour; - rec->sec = tm->tm_sec; - rec->day = tm->tm_mday; - rec->mon = tm->tm_mon + 1; - be_write16( &rec->year, tm->tm_year + 1900); - } else { - rec->min = 0xff; - rec->hour = 0xff; - rec->sec = 0xff; - rec->day = 0xff; - rec->mon = 0xff; - be_write16(&rec->year, 0xff); - } - be_write32(&rec->longitude, (unsigned int) (int) (wpt->longitude * 10000000.0)); - be_write32(&rec->latitude, (unsigned int) (wpt->latitude * 10000000.0)); - if ( wpt->altitude == unknown_alt ) { - be_write32(&rec->elevation, -100000000); - } - else { - be_write32(&rec->elevation, (unsigned int) (wpt->altitude * 100.0)); - } - - be_write16( &rec->pdop, wpt->pdop ? wpt->pdop * 100 : 0xffff ); - be_write16( &rec->hdop, wpt->hdop ? wpt->hdop * 100 : 0xffff ); - be_write16( &rec->vdop, wpt->vdop ? wpt->vdop * 100 : 0xffff ); - be_write16( &rec->dgpstime, 0xffff ); - be_write32( &rec->distance, 0xffffffff ); - - rec->vmin = 0xff; - rec->vhour = 0xff; - rec->vsec = 0xff; - rec->vday = 0xff; - rec->vmon = 0xff; - be_write16(&rec->vyear, 0xff); - - rec->sat = wpt->sat ? wpt->sat : 0xff; - - vdata = (char *)rec + sizeof(*rec); - if ( wpt->shortname ) { - char *sn = xstrdup(wpt->shortname); - strncpy( vdata, sn, 16 ); - vdata[15] = '\0'; - xfree(sn); - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - if (wpt->gc_data->diff) { - xasprintf(&desc_geo, "%s%s by %s\n%.4s/%.4s %3.1f/%3.1f\n", - wpt->gc_data->is_available==status_true ? - "" : " (Disabled)", - wpt->gc_data->is_archived==status_true ? - " (Archived)" : "", - wpt->gc_data->placer, - gs_get_cachetype(wpt->gc_data->type), - gs_get_container(wpt->gc_data->container), - wpt->gc_data->diff/10.0, - wpt->gc_data->terr/10.0); - } else { - desc_geo = xstrdup(""); - } - - if (wpt->gc_data->desc_short.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_short); - desc_short = xstrdup(wpt->gc_data->diff == 0 ? "\n\n" : ""); - desc_short = xstrappend(desc_short, xstrdup(stripped_html)); - xfree(stripped_html); - } else { - desc_short = xstrdup(""); - } - - if (wpt->gc_data->desc_long.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_long); - desc_long = xstrdup("\n\n"); - desc_long = xstrappend(desc_long, xstrdup(stripped_html)); - xfree(stripped_html); - } else { - desc_long = xstrdup(""); - } - - desc = wpt->description ? xstrdup(wpt->description) : - xstrdup(""); - - snprintf(vdata, DESCSZ, "%s%s%s%s", - desc, - desc_geo, - desc_short, - desc_long); - - xfree(desc); - xfree(desc_geo); - xfree(desc_short); - xfree(desc_long); - - if (appendicon && wpt->icon_descr) { - int left = DESCSZ - strlen( vdata ); - int ilen = strlen( wpt->icon_descr ); - if (ilen && left > (ilen+3)) { - strcat( vdata, " (" ); - strcat( vdata, wpt->icon_descr ); - strcat( vdata, ")" ); - } - } - vdata += strlen( vdata ) + 1; - - if (wpt->gc_data->hint) { - char *hint = xstrdup(wpt->gc_data->hint); - rec->type = WptCache; - strncpy( vdata, hint, NOTESZ + 1 ) ; - xfree(hint); - vdata[NOTESZ] = '\0'; - } else { - rec->type = WptEdit; - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - pdb_write_rec(file_out, 0, 2, ct++, rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct cetus_wpt_s* rec; + struct tm* tm; + char* vdata; + char* desc_long; + char* desc_short; + char* desc_geo; + char* desc; + + rec = (struct cetus_wpt_s*) xcalloc(sizeof(*rec)+18 + NOTESZ + DESCSZ,1); + + if (wpt->creation_time && (NULL != (tm = gmtime(&wpt->creation_time)))) { + rec->min = tm->tm_min; + rec->hour = tm->tm_hour; + rec->sec = tm->tm_sec; + rec->day = tm->tm_mday; + rec->mon = tm->tm_mon + 1; + be_write16(&rec->year, tm->tm_year + 1900); + } else { + rec->min = 0xff; + rec->hour = 0xff; + rec->sec = 0xff; + rec->day = 0xff; + rec->mon = 0xff; + be_write16(&rec->year, 0xff); + } + be_write32(&rec->longitude, (unsigned int)(int)(wpt->longitude * 10000000.0)); + be_write32(&rec->latitude, (unsigned int)(wpt->latitude * 10000000.0)); + if (wpt->altitude == unknown_alt) { + be_write32(&rec->elevation, -100000000); + } else { + be_write32(&rec->elevation, (unsigned int)(wpt->altitude * 100.0)); + } + + be_write16(&rec->pdop, wpt->pdop ? wpt->pdop * 100 : 0xffff); + be_write16(&rec->hdop, wpt->hdop ? wpt->hdop * 100 : 0xffff); + be_write16(&rec->vdop, wpt->vdop ? wpt->vdop * 100 : 0xffff); + be_write16(&rec->dgpstime, 0xffff); + be_write32(&rec->distance, 0xffffffff); + + rec->vmin = 0xff; + rec->vhour = 0xff; + rec->vsec = 0xff; + rec->vday = 0xff; + rec->vmon = 0xff; + be_write16(&rec->vyear, 0xff); + + rec->sat = wpt->sat ? wpt->sat : 0xff; + + vdata = (char*)rec + sizeof(*rec); + if (wpt->shortname) { + char* sn = xstrdup(wpt->shortname); + strncpy(vdata, sn, 16); + vdata[15] = '\0'; + xfree(sn); + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + if (wpt->gc_data->diff) { + xasprintf(&desc_geo, "%s%s by %s\n%.4s/%.4s %3.1f/%3.1f\n", + wpt->gc_data->is_available==status_true ? + "" : " (Disabled)", + wpt->gc_data->is_archived==status_true ? + " (Archived)" : "", + wpt->gc_data->placer, + gs_get_cachetype(wpt->gc_data->type), + gs_get_container(wpt->gc_data->container), + wpt->gc_data->diff/10.0, + wpt->gc_data->terr/10.0); + } else { + desc_geo = xstrdup(""); + } + + if (wpt->gc_data->desc_short.utfstring) { + char* stripped_html = strip_html(&wpt->gc_data->desc_short); + desc_short = xstrdup(wpt->gc_data->diff == 0 ? "\n\n" : ""); + desc_short = xstrappend(desc_short, xstrdup(stripped_html)); + xfree(stripped_html); + } else { + desc_short = xstrdup(""); + } + + if (wpt->gc_data->desc_long.utfstring) { + char* stripped_html = strip_html(&wpt->gc_data->desc_long); + desc_long = xstrdup("\n\n"); + desc_long = xstrappend(desc_long, xstrdup(stripped_html)); + xfree(stripped_html); + } else { + desc_long = xstrdup(""); + } + + desc = wpt->description ? xstrdup(wpt->description) : + xstrdup(""); + + snprintf(vdata, DESCSZ, "%s%s%s%s", + desc, + desc_geo, + desc_short, + desc_long); + + xfree(desc); + xfree(desc_geo); + xfree(desc_short); + xfree(desc_long); + + if (appendicon && wpt->icon_descr) { + int left = DESCSZ - strlen(vdata); + int ilen = strlen(wpt->icon_descr); + if (ilen && left > (ilen+3)) { + strcat(vdata, " ("); + strcat(vdata, wpt->icon_descr); + strcat(vdata, ")"); + } + } + vdata += strlen(vdata) + 1; + + if (wpt->gc_data->hint) { + char* hint = xstrdup(wpt->gc_data->hint); + rec->type = WptCache; + strncpy(vdata, hint, NOTESZ + 1) ; + xfree(hint); + vdata[NOTESZ] = '\0'; + } else { + rec->type = WptEdit; + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, rec, (char*)vdata - (char*)rec); + + xfree(rec); } -struct hdr{ - char *wpt_name; - waypoint *wpt; +struct hdr { + char* wpt_name; + waypoint* wpt; }; static -int -compare(const void *a, const void *b) +int +compare(const void* a, const void* b) { - const struct hdr *wa = (const struct hdr*) a; - const struct hdr *wb = (const struct hdr*) b; + const struct hdr* wa = (const struct hdr*) a; + const struct hdr* wb = (const struct hdr*) b; - return strcmp(wa->wpt->shortname, wb->wpt->shortname); + return strcmp(wa->wpt->shortname, wb->wpt->shortname); } static void data_write(void) { - int i, ct = waypt_count(); - struct hdr *htable, *bh; - queue *elem, *tmp; - extern queue waypt_head; - waypoint *waypointp; - mkshort_wr_handle = mkshort_new_handle(); - setshort_length(mkshort_wr_handle, 15); - setshort_whitespace_ok(mkshort_wr_handle, 0); - - if ( dbname ) { - strncpy( file_out->name, dbname, PDB_DBNAMELEN ); - } - else { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - } - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE_WPT; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - - /* - * All this is to sort by waypoint names before going to Cetus. - * Turns out plain old strcmp will do the trick... - */ - - htable = xmalloc(ct * sizeof(*htable)); - bh = htable; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - bh->wpt = waypointp; - if (global_opts.synthesize_shortnames && waypointp->description) { - if (waypointp->shortname) - xfree(waypointp->shortname); - waypointp->shortname = mkshort_from_wpt(mkshort_wr_handle, waypointp); - } - bh->wpt_name = waypointp->shortname; - bh ++; - } - qsort(htable, ct, sizeof(*bh), compare); - - for (i=0;iname, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE_WPT; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + /* + * All this is to sort by waypoint names before going to Cetus. + * Turns out plain old strcmp will do the trick... + */ + + htable = (struct hdr*) xmalloc(ct * sizeof(*htable)); + bh = htable; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint*) elem; + bh->wpt = waypointp; + if (global_opts.synthesize_shortnames && waypointp->description) { + if (waypointp->shortname) { + xfree(waypointp->shortname); + } + waypointp->shortname = mkshort_from_wpt(mkshort_wr_handle, waypointp); + } + bh->wpt_name = waypointp->shortname; + bh ++; + } + qsort(htable, ct, sizeof(*bh), compare); + + for (i=0; i - static XML_Parser psr; +static XML_Parser psr; #endif #include @@ -30,7 +30,7 @@ #include "uuid.h" -static gbfile *fd, *ofd; +static gbfile* fd, *ofd; #define MYNAME "coastexp" #define MY_CBUF 4096 @@ -39,100 +39,102 @@ static gbfile *fd, *ofd; #define MY_XBUF 128 -static char *element; // Current element being parsed -static char *cdatastr; // Current XML character data being built up (until a ) +static char* element; // Current element being parsed +static char* cdatastr; // Current XML character data being built up (until a ) /* CE-specific mark structure - used for both route marks and standalone marks */ struct CE_MARK { - queue Q; - char *id; // CE's mark ID (of the form "{}") - char *created; // CE's creation time (of the form "
TZ") - waypoint *wp; // GPSBabel waypoint - int used; // Is this mark used in a route or not? + queue Q; + char* id; // CE's mark ID (of the form "{}") + char* created; // CE's creation time (of the form "
TZ") + waypoint* wp; // GPSBabel waypoint + int used; // Is this mark used in a route or not? }; typedef struct CE_MARK ce_mark; /* CE-specific route structure */ struct CE_ROUTE { - queue Q; - char *id; // CE's route ID (of the form "{}") - route_head *r; // GPSBabel route header - queue ce_mark_head; // list of CE marks in this route + queue Q; + char* id; // CE's route ID (of the form "{}") + route_head* r; // GPSBabel route header + queue ce_mark_head; // list of CE marks in this route }; typedef struct CE_ROUTE ce_route; static queue ce_route_head; // List of routes currently found -static ce_route *currentRoute = NULL; // Current route being processed +static ce_route* currentRoute = NULL; // Current route being processed static queue ce_mark_head; // List of stand-alone marks currently found -static ce_mark *currentMark = NULL; // Current mark being processed -static char *time_buffer = NULL; // Time buffer for processing times -static char *uuid_buffer = NULL; // UUID buffer for processing uuid's -static char *xml_buffer = NULL; // XML buffer for processing XML strings +static ce_mark* currentMark = NULL; // Current mark being processed +static char* time_buffer = NULL; // Time buffer for processing times +static char* uuid_buffer = NULL; // UUID buffer for processing uuid's +static char* xml_buffer = NULL; // XML buffer for processing XML strings static int inRoute = 0; // Are we processing a route? static int inMark = 0; // Are we processing a mark? /* Add a route to the list of routes */ static void -ce_add_route(ce_route *route) +ce_add_route(ce_route* route) { - ENQUEUE_TAIL(&ce_route_head, &route->Q); + ENQUEUE_TAIL(&ce_route_head, &route->Q); } /* Add a mark to the list of stand-alone marks */ static void -ce_add_mark(ce_mark *mark) +ce_add_mark(ce_mark* mark) { - ENQUEUE_TAIL(&ce_mark_head, &mark->Q); + ENQUEUE_TAIL(&ce_mark_head, &mark->Q); } /* Add a mark to the specified route */ static void -ce_add_mark_to_route(ce_route *route, ce_mark *mark) +ce_add_mark_to_route(ce_route* route, ce_mark* mark) { - ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q); + ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q); } /* Free a mark */ static void -ce_free_mark(ce_mark *mark) +ce_free_mark(ce_mark* mark) { - dequeue(&mark->Q); - if (mark->id) - xfree(mark->id); - if (mark->created) - xfree(mark->created); - xfree(mark); + dequeue(&mark->Q); + if (mark->id) { + xfree(mark->id); + } + if (mark->created) { + xfree(mark->created); + } + xfree(mark); } /* Free a route */ static void -ce_free_route(ce_route *route) +ce_free_route(ce_route* route) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - ce_free_mark(mark); - } - xfree(route->id); - xfree(route); - // Don't free the waypoint since this is done elsewhere + queue* elem, *tmp; + QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) { + ce_mark* mark = (ce_mark*) elem; + ce_free_mark(mark); + } + xfree(route->id); + xfree(route); + // Don't free the waypoint since this is done elsewhere } /* Allocate a mark */ -static ce_mark * -ce_alloc_mark(const waypoint *wpt, const char *id) +static ce_mark* +ce_alloc_mark(const waypoint* wpt, const char* id) { - ce_mark *res = xcalloc(sizeof(ce_mark), 1); - res->id = (char *) id; - res->wp = (waypoint *) wpt; - return res; + ce_mark* res = (ce_mark*) xcalloc(sizeof(ce_mark), 1); + res->id = (char*) id; + res->wp = (waypoint*) wpt; + return res; } #if !HAVE_LIBEXPAT void -ce_rd_init(const char *fname) +ce_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded CoastalExplorer support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded CoastalExplorer support because expat was not installed.\n"); } void @@ -143,210 +145,215 @@ ce_read(void) /* Start processing an XML item */ static void -ce_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) -{ - const char *el = xml_convert_to_char_string(xml_el); - const char **ap; - const char **attr; - - attr = xml_convert_attrs_to_char_string(xml_attr); - strcpy(element, el); - if (0 == strcmp(el, "Route")) { - inRoute = 1; - for (ap = attr; *ap; ap+=2) { - if (0 == strcmp(ap[0], "id")) { - // Create a CE route object and add it to the list of routes - currentRoute = (ce_route *) xcalloc(sizeof (ce_route), 1); - currentRoute->id=xstrdup(ap[1]); - currentRoute->r = route_head_alloc(); - QUEUE_INIT(¤tRoute->ce_mark_head); - ce_add_route(currentRoute); - } - } - } else if (0 == strcmp(el, "Mark")) { - inMark = 1; - currentMark = ce_alloc_mark(NULL, NULL); - ce_add_mark(currentMark); - for (ap = attr; *ap; ap+=2) { - if (0 == strcmp(ap[0], "id")) { - // Create a CE mark object and add it to the list of stand-alone marks - currentMark->id = xstrdup(ap[1]); - } - else if (0 == strcmp(ap[0], "created")) { - currentMark->created = xstrdup(ap[1]); - } - } - } - xml_free_converted_string(el); - xml_free_converted_attrs(attr); +ce_start(void* data, const XML_Char* xml_el, const XML_Char** xml_attr) +{ + const char* el = xml_convert_to_char_string(xml_el); + const char** ap; + const char** attr; + + attr = xml_convert_attrs_to_char_string(xml_attr); + strcpy(element, el); + if (0 == strcmp(el, "Route")) { + inRoute = 1; + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "id")) { + // Create a CE route object and add it to the list of routes + currentRoute = (ce_route*) xcalloc(sizeof(ce_route), 1); + currentRoute->id=xstrdup(ap[1]); + currentRoute->r = route_head_alloc(); + QUEUE_INIT(¤tRoute->ce_mark_head); + ce_add_route(currentRoute); + } + } + } else if (0 == strcmp(el, "Mark")) { + inMark = 1; + currentMark = ce_alloc_mark(NULL, NULL); + ce_add_mark(currentMark); + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "id")) { + // Create a CE mark object and add it to the list of stand-alone marks + currentMark->id = xstrdup(ap[1]); + } else if (0 == strcmp(ap[0], "created")) { + currentMark->created = xstrdup(ap[1]); + } + } + } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); } /* Finish processing an XML item */ static void -ce_end(void *data, const XML_Char *xml_el) +ce_end(void* data, const XML_Char* xml_el) { - const char *el = xml_convert_to_char_string(xml_el); - if (0 == strcmp(el, "Route")) { - inRoute = 0; /* ??? */ - } - else if (0 == strcmp(el, "Mark")) - inMark = 0; - xml_free_converted_string(el); + const char* el = xml_convert_to_char_string(xml_el); + if (0 == strcmp(el, "Route")) { + inRoute = 0; /* ??? */ + } else if (0 == strcmp(el, "Mark")) { + inMark = 0; + } + xml_free_converted_string(el); } /* Process some XML character data for the current item */ static void -ce_cdata(void *dta, const XML_Char *xml_s, int len) -{ - const char *origs = xml_convert_to_char_string_n(xml_s, &len); - const char *s = origs; - if (*s != '\n') { - char *edatastr; - // We buffer up characters in 'cdatastr' until a single is received - if ((strlen(cdatastr) + len) > MY_CBUF) { - printf("Buffer overflow - line too long!"); - exit(-1); - } - edatastr = cdatastr+strlen(cdatastr); - memcpy(edatastr, s, len); - edatastr[len] = '\0'; - } else { - // Now process what we have in 'cdatastr' - s = cdatastr; - while (*s != '\0' && (*s == '\b' || *s == '\t')) - s++; - if (strlen(s) <= 0) - return; - if (0 == strcmp(element, "Marks")) { - if (inRoute) { - // We are processing the marks in a route so create a CE mark object - // and add it to the current route - ce_mark *mark = (ce_mark *) ce_alloc_mark(NULL, xstrdup(s)); - ce_add_mark_to_route(currentRoute, mark); - } - } else if (0 == strcmp(element, "Position")) { - if (inMark) { - // We are processing a standalone mark so read the lat/long position - // and create a waypoint to add to the current mark - char *position = xstrdup(s); - char *lat = position; - char *latNorS = position; - char *lng; - char *longEorW; - while (*latNorS != ' ') - latNorS++; - *latNorS++ = '\0'; - lng = latNorS; - lng++; lng++; - longEorW = lng; - while (*longEorW != ' ') - longEorW++; - *longEorW++ = '\0'; - if (!currentMark->wp) - currentMark->wp = waypt_new(); - currentMark->wp->latitude = atof(lat); - if (*latNorS == 'S') - currentMark->wp->latitude = -currentMark->wp->latitude; - currentMark->wp->longitude = atof(lng); - if (*longEorW == 'W') - currentMark->wp->longitude = -currentMark->wp->longitude; - xfree(position); - } - } else if (0 == strcmp(element, "Name")) { - // Names we care about may be either for routes or marks - if (inMark) - { - if (!currentMark->wp) - currentMark->wp = waypt_new(); - currentMark->wp->shortname = xstrdup(s); - - // Also set the creation time - if (currentMark->created) - { - struct tm t; - char yearString[5], monthString[3], dayString[3], hourString[3], minString[3], secString[3]; - memset(&t, 0, sizeof(struct tm)); - strncpy(yearString, currentMark->created, 4); - yearString[4] = '\0'; - t.tm_year = atoi(yearString) - 1900; - strncpy(monthString, currentMark->created+4, 2); - monthString[2] = '\0'; - t.tm_mon = atoi(monthString) - 1; - strncpy(dayString, currentMark->created+6, 2); - dayString[2] = '\0'; - t.tm_mday = atoi(dayString); - strncpy(hourString, currentMark->created+9, 2); - hourString[2] = '\0'; - t.tm_hour = atoi(hourString); - strncpy(minString, currentMark->created+11, 2); - minString[2] = '\0'; - t.tm_min = atoi(minString); - strncpy(secString, currentMark->created+13, 2); - secString[2] = '\0'; - t.tm_sec = atoi(secString); - currentMark->wp->creation_time = mkgmtime(&t); - } - } - else if (inRoute) { - currentRoute->r->rte_name = xstrdup(s); - } - } else if (0 == strcmp(element, "Description")) { - // Descriptions we care about may be either for routes or marks - char *desc = xstrdup(s); - if (inMark) - { - if (!currentMark->wp) - currentMark->wp = waypt_new(); - currentMark->wp->description = desc; - } - else if (inRoute) - currentRoute->r->rte_desc = desc; - } - - // Start building a new string since we are done with this one - cdatastr[0] = '\0'; - } - - xml_free_converted_string(origs); +ce_cdata(void* dta, const XML_Char* xml_s, int len) +{ + const char* origs = xml_convert_to_char_string_n(xml_s, &len); + const char* s = origs; + if (*s != '\n') { + char* edatastr; + // We buffer up characters in 'cdatastr' until a single is received + if ((strlen(cdatastr) + len) > MY_CBUF) { + printf("Buffer overflow - line too long!"); + exit(-1); + } + edatastr = cdatastr+strlen(cdatastr); + memcpy(edatastr, s, len); + edatastr[len] = '\0'; + } else { + // Now process what we have in 'cdatastr' + s = cdatastr; + while (*s != '\0' && (*s == '\b' || *s == '\t')) { + s++; + } + if (strlen(s) <= 0) { + return; + } + if (0 == strcmp(element, "Marks")) { + if (inRoute) { + // We are processing the marks in a route so create a CE mark object + // and add it to the current route + ce_mark* mark = (ce_mark*) ce_alloc_mark(NULL, xstrdup(s)); + ce_add_mark_to_route(currentRoute, mark); + } + } else if (0 == strcmp(element, "Position")) { + if (inMark) { + // We are processing a standalone mark so read the lat/long position + // and create a waypoint to add to the current mark + char* position = xstrdup(s); + char* lat = position; + char* latNorS = position; + char* lng; + char* longEorW; + while (*latNorS != ' ') { + latNorS++; + } + *latNorS++ = '\0'; + lng = latNorS; + lng++; + lng++; + longEorW = lng; + while (*longEorW != ' ') { + longEorW++; + } + *longEorW++ = '\0'; + if (!currentMark->wp) { + currentMark->wp = waypt_new(); + } + currentMark->wp->latitude = atof(lat); + if (*latNorS == 'S') { + currentMark->wp->latitude = -currentMark->wp->latitude; + } + currentMark->wp->longitude = atof(lng); + if (*longEorW == 'W') { + currentMark->wp->longitude = -currentMark->wp->longitude; + } + xfree(position); + } + } else if (0 == strcmp(element, "Name")) { + // Names we care about may be either for routes or marks + if (inMark) { + if (!currentMark->wp) { + currentMark->wp = waypt_new(); + } + currentMark->wp->shortname = xstrdup(s); + + // Also set the creation time + if (currentMark->created) { + struct tm t; + char yearString[5], monthString[3], dayString[3], hourString[3], minString[3], secString[3]; + memset(&t, 0, sizeof(struct tm)); + strncpy(yearString, currentMark->created, 4); + yearString[4] = '\0'; + t.tm_year = atoi(yearString) - 1900; + strncpy(monthString, currentMark->created+4, 2); + monthString[2] = '\0'; + t.tm_mon = atoi(monthString) - 1; + strncpy(dayString, currentMark->created+6, 2); + dayString[2] = '\0'; + t.tm_mday = atoi(dayString); + strncpy(hourString, currentMark->created+9, 2); + hourString[2] = '\0'; + t.tm_hour = atoi(hourString); + strncpy(minString, currentMark->created+11, 2); + minString[2] = '\0'; + t.tm_min = atoi(minString); + strncpy(secString, currentMark->created+13, 2); + secString[2] = '\0'; + t.tm_sec = atoi(secString); + currentMark->wp->creation_time = mkgmtime(&t); + } + } else if (inRoute) { + currentRoute->r->rte_name = xstrdup(s); + } + } else if (0 == strcmp(element, "Description")) { + // Descriptions we care about may be either for routes or marks + char* desc = xstrdup(s); + if (inMark) { + if (!currentMark->wp) { + currentMark->wp = waypt_new(); + } + currentMark->wp->description = desc; + } else if (inRoute) { + currentRoute->r->rte_desc = desc; + } + } + + // Start building a new string since we are done with this one + cdatastr[0] = '\0'; + } + + xml_free_converted_string(origs); } /* Set up reading the CE input file */ void -ce_rd_init(const char *fname) +ce_rd_init(const char* fname) { - fd = gbfopen(fname, "r", MYNAME); - QUEUE_INIT(&ce_route_head); - QUEUE_INIT(&ce_mark_head); + fd = gbfopen(fname, "r", MYNAME); + QUEUE_INIT(&ce_route_head); + QUEUE_INIT(&ce_mark_head); - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ":Cannot create XML parser\n"); - } + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - XML_SetElementHandler(psr, ce_start, ce_end); - cdatastr = xcalloc(MY_CBUF,1); - element = xcalloc(MY_CBUF,1); - XML_SetCharacterDataHandler(psr, ce_cdata); + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, ce_start, ce_end); + cdatastr = (char*) xcalloc(MY_CBUF,1); + element = (char*) xcalloc(MY_CBUF,1); + XML_SetCharacterDataHandler(psr, ce_cdata); } /* Parse the input file */ void ce_read(void) { - int len; - char buf[MY_CBUF + 1]; + int len; + char buf[MY_CBUF + 1]; - while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { - buf[len] = '\0'; - if (!XML_Parse(psr, buf, len, gbfeof(fd))) { - fatal(MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - } + while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { + buf[len] = '\0'; + if (!XML_Parse(psr, buf, len, gbfeof(fd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } - XML_ParserFree(psr); + XML_ParserFree(psr); } #endif @@ -355,362 +362,369 @@ ce_read(void) void ce_fix_route_mark_waypoints(void) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { - ce_route *route = (ce_route *) elem; - queue *elem2, *tmp2; - QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { - ce_mark *mark = (ce_mark *) elem2; - queue *elem3, *tmp3; - QUEUE_FOR_EACH(&ce_mark_head, elem3, tmp3) { - ce_mark *mark2 = (ce_mark *) elem3; - if (0 == strcmp(mark->id, mark2->id)) { - mark->wp = waypt_dupe(mark2->wp); - mark2->used = 1; - break; - } - } - } - } + queue* elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route* route = (ce_route*) elem; + queue* elem2, *tmp2; + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark* mark = (ce_mark*) elem2; + queue* elem3, *tmp3; + QUEUE_FOR_EACH(&ce_mark_head, elem3, tmp3) { + ce_mark* mark2 = (ce_mark*) elem3; + if (0 == strcmp(mark->id, mark2->id)) { + mark->wp = waypt_dupe(mark2->wp); + mark2->used = 1; + break; + } + } + } + } } /* Check route name and if NULL assign a name */ void ce_check_route_names(void) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { - ce_route *route = (ce_route *) elem; - if (route->r->rte_name == NULL) { - *cdatastr = '\0'; - strcat(cdatastr, ((ce_mark *) QUEUE_FIRST(&route->ce_mark_head))->wp->shortname); - strcat(cdatastr, "->"); - strcat(cdatastr, ((ce_mark *) QUEUE_LAST(&route->ce_mark_head))->wp->shortname); - route->r->rte_name = xstrdup(cdatastr); - } - } + queue* elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route* route = (ce_route*) elem; + if (route->r->rte_name == NULL) { + *cdatastr = '\0'; + strcat(cdatastr, ((ce_mark*) QUEUE_FIRST(&route->ce_mark_head))->wp->shortname); + strcat(cdatastr, "->"); + strcat(cdatastr, ((ce_mark*) QUEUE_LAST(&route->ce_mark_head))->wp->shortname); + route->r->rte_name = xstrdup(cdatastr); + } + } } /* Remove marks used in routes */ void ce_remove_used_marks(void) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - if (mark->used) - { - if (mark->wp) - waypt_free(mark->wp); - ce_free_mark(mark); - } - } + queue* elem, *tmp; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark* mark = (ce_mark*) elem; + if (mark->used) { + if (mark->wp) { + waypt_free(mark->wp); + } + ce_free_mark(mark); + } + } } /* Print out results */ void ce_print_results(void) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { - queue *elem2, *tmp2; - ce_route *route = (ce_route *) elem; - printf("Route name=%s id=%s\n", route->r->rte_name, route->id); - QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { - ce_mark *mark = (ce_mark *) elem2; - if (mark->wp == NULL) - printf(" null\n"); - else - printf(" %s (%f, %f)\n", mark->wp->shortname, mark->wp->latitude, mark->wp->longitude); - } - } - - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - printf("Mark name=%s id=%s ", mark->wp->shortname, mark->id); - if (mark->wp == NULL) - printf("(null)\n"); - else - printf("(%f, %f)\n", mark->wp->latitude, mark->wp->longitude); - } + queue* elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + queue* elem2, *tmp2; + ce_route* route = (ce_route*) elem; + printf("Route name=%s id=%s\n", route->r->rte_name, route->id); + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark* mark = (ce_mark*) elem2; + if (mark->wp == NULL) { + printf(" null\n"); + } else { + printf(" %s (%f, %f)\n", mark->wp->shortname, mark->wp->latitude, mark->wp->longitude); + } + } + } + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark* mark = (ce_mark*) elem; + printf("Mark name=%s id=%s ", mark->wp->shortname, mark->id); + if (mark->wp == NULL) { + printf("(null)\n"); + } else { + printf("(%f, %f)\n", mark->wp->latitude, mark->wp->longitude); + } + } } /* Finish reading the input file */ void ce_rd_deinit(void) { - /* If doing routes, we create GPSBabel route structures and waypoint structures for - any standalone waypoints. - If doing waypoints, we create only waypoint structures for both route waypoints and - standalone waypoints. - */ - queue *elem, *tmp; - - ce_fix_route_mark_waypoints(); - ce_check_route_names(); - ce_remove_used_marks(); - - // Log results - if (global_opts.debug_level > 1) - ce_print_results(); - - // Add routes to GPSBabel - QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { - ce_route *route = (ce_route *) elem; - queue *elem2, *tmp2; - route_add_head(route->r); - QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { - ce_mark *mark = (ce_mark *) elem2; - if (mark->wp) - route_add_wpt(route->r, mark->wp); - else - printf("Undefined mark: %s\n", mark->id); - } - ce_free_route(route); - } - - // Add (unused) marks to GPSBabel - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - waypt_add(mark->wp); - ce_free_mark(mark); - } - - gbfclose(fd); - xfree(element); - xfree(cdatastr); + /* If doing routes, we create GPSBabel route structures and waypoint structures for + any standalone waypoints. + If doing waypoints, we create only waypoint structures for both route waypoints and + standalone waypoints. + */ + queue* elem, *tmp; + + ce_fix_route_mark_waypoints(); + ce_check_route_names(); + ce_remove_used_marks(); + + // Log results + if (global_opts.debug_level > 1) { + ce_print_results(); + } + + // Add routes to GPSBabel + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route* route = (ce_route*) elem; + queue* elem2, *tmp2; + route_add_head(route->r); + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark* mark = (ce_mark*) elem2; + if (mark->wp) { + route_add_wpt(route->r, mark->wp); + } else { + printf("Undefined mark: %s\n", mark->id); + } + } + ce_free_route(route); + } + + // Add (unused) marks to GPSBabel + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark* mark = (ce_mark*) elem; + waypt_add(mark->wp); + ce_free_mark(mark); + } + + gbfclose(fd); + xfree(element); + xfree(cdatastr); } /* Setup for writing */ void -ce_wr_init(const char *fname) +ce_wr_init(const char* fname) { - QUEUE_INIT(&ce_mark_head); + QUEUE_INIT(&ce_mark_head); - // Alloocate all buffers used for writing - time_buffer = xcalloc(MY_TBUF,1); - uuid_buffer = xcalloc(MY_UBUF,1); - xml_buffer = xcalloc(MY_XBUF, 1); + // Alloocate all buffers used for writing + time_buffer = (char*) xcalloc(MY_TBUF,1); + uuid_buffer = (char*) xcalloc(MY_UBUF,1); + xml_buffer = (char*) xcalloc(MY_XBUF, 1); - ofd = gbfopen(fname, "w", MYNAME); - srand(gpsbabel_now); + ofd = gbfopen(fname, "w", MYNAME); + srand(gpsbabel_now); } void ce_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); - // Free the buffers used for writing - xfree(time_buffer); - xfree(uuid_buffer); - xfree(xml_buffer); + // Free the buffers used for writing + xfree(time_buffer); + xfree(uuid_buffer); + xfree(xml_buffer); } /* Generate a CE-style creation time based on supplied time */ -static char * +static char* ce_gen_creation_time(time_t tm) { - xml_fill_in_time(time_buffer, tm, 0, XML_SHORT_TIME); - return time_buffer; + xml_fill_in_time(time_buffer, tm, 0, XML_SHORT_TIME); + return time_buffer; } /* Generate a CE-style creation time based on current time */ -static char * +static char* ce_gen_current_time(void) { - return ce_gen_creation_time(current_time()); + return ce_gen_creation_time(current_time()); } /* Generate a UUID (has same format as Microsoft registry GUIDs */ -static char * +static char* ce_gen_uuid(void) { - uuid_t uu; + uuid_t uu; - memset(&uu, 0, sizeof(uu)); - gb_uuid_generate(uu); - sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], - uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); - return uuid_buffer; + memset(&uu, 0, sizeof(uu)); + gb_uuid_generate(uu); + sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], + uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); + return uuid_buffer; } /* Generate route header XML */ static void -ce_route_hdr(const route_head *rte) +ce_route_hdr(const route_head* rte) { - sprintf(xml_buffer, "{%s}", ce_gen_uuid()); - write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer); - write_xml_entity_begin0(ofd, "\t\t", "Marks"); + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer); + write_xml_entity_begin0(ofd, "\t\t", "Marks"); } /* Generate route body XML */ static void -ce_route_disp(const waypoint *waypointp) +ce_route_disp(const waypoint* waypointp) { - char *uuid = ce_gen_uuid(); - char *id = xcalloc(strlen(uuid)+3, 1); - - sprintf(id, "{%s}", uuid); - currentMark = ce_alloc_mark(waypointp, id); - ENQUEUE_TAIL(&ce_mark_head, ¤tMark->Q); + char* uuid = ce_gen_uuid(); + char* id = (char*) xcalloc(strlen(uuid)+3, 1); - gbfprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard! + sprintf(id, "{%s}", uuid); + currentMark = ce_alloc_mark(waypointp, id); + ENQUEUE_TAIL(&ce_mark_head, ¤tMark->Q); + + gbfprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard! } /* Generate route trailer XML */ static void -ce_route_tlr(const route_head *rte) +ce_route_tlr(const route_head* rte) { - write_xml_entity_end(ofd, "\t\t", "Marks"); - write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name); - write_xml_entity_end(ofd, "\t", "Route"); + write_xml_entity_end(ofd, "\t\t", "Marks"); + write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name); + write_xml_entity_end(ofd, "\t", "Route"); } /* Generate waypoint body XML */ static void -ce_waypt_pr(const waypoint *wp) -{ - double latitude = wp->latitude; - char NorS = 'N'; - char EorW = 'E'; - double longitude = wp->longitude; - - if (latitude < 0) { - latitude = -latitude; - NorS = 'S'; - } - if (longitude < 0) { - longitude = -longitude; - EorW = 'W'; - } - sprintf(xml_buffer, "%3.6f %c %3.6f %c", latitude, NorS, longitude, EorW); - write_xml_entity(ofd, "\t\t", "Position", xml_buffer); - write_optional_xml_entity(ofd, "\t\t", "Name", wp->shortname); - if (wp->description && wp->shortname && - strcmp(wp->description, wp->shortname)) - write_optional_xml_entity(ofd, "\t\t", "Description", wp->description); -} - -static char * -ce_find_uuid(const waypoint *wpt) -{ - queue *elem, *tmp; - - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - if (mark->wp == wpt) { - return mark->id; - } - } - return NULL; -} - -static waypoint * -ce_find_wpt(const waypoint *wpt) -{ - queue *elem, *tmp; - - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - if ((mark->wp->shortname == wpt->shortname) && - (mark->wp->latitude == wpt->latitude) && - (mark->wp->longitude == wpt->longitude)) - return mark->wp; - } - return NULL; +ce_waypt_pr(const waypoint* wp) +{ + double latitude = wp->latitude; + char NorS = 'N'; + char EorW = 'E'; + double longitude = wp->longitude; + + if (latitude < 0) { + latitude = -latitude; + NorS = 'S'; + } + if (longitude < 0) { + longitude = -longitude; + EorW = 'W'; + } + sprintf(xml_buffer, "%3.6f %c %3.6f %c", latitude, NorS, longitude, EorW); + write_xml_entity(ofd, "\t\t", "Position", xml_buffer); + write_optional_xml_entity(ofd, "\t\t", "Name", wp->shortname); + if (wp->description && wp->shortname && + strcmp(wp->description, wp->shortname)) { + write_optional_xml_entity(ofd, "\t\t", "Description", wp->description); + } +} + +static char* +ce_find_uuid(const waypoint* wpt) +{ + queue* elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark* mark = (ce_mark*) elem; + if (mark->wp == wpt) { + return mark->id; + } + } + return NULL; +} + +static waypoint* +ce_find_wpt(const waypoint* wpt) +{ + queue* elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark* mark = (ce_mark*) elem; + if ((mark->wp->shortname == wpt->shortname) && + (mark->wp->latitude == wpt->latitude) && + (mark->wp->longitude == wpt->longitude)) { + return mark->wp; + } + } + return NULL; } /* Generate a mark XML; look for created id's */ static void -ce_mark_pr(const waypoint *wp) -{ - char *id; - - if (inRoute) { - id = ce_find_uuid(wp); - if (id == NULL) { - sprintf(xml_buffer, "{%s}", ce_gen_uuid()); - id = xml_buffer; - } - } - /* Have we seen and written the (nearly) same waypoint ? */ - else if (ce_find_wpt(wp) != NULL) return; - else { - ce_mark *mark = ce_alloc_mark(wp, NULL); - ENQUEUE_TAIL(&ce_mark_head, &mark->Q); - sprintf(xml_buffer, "{%s}", ce_gen_uuid()); - id = xml_buffer; - } - write_xml_entity_begin2(ofd, "\t", "Mark", - "created", ce_gen_creation_time(wp->creation_time), - "id", id); - ce_waypt_pr(wp); - write_xml_entity_end(ofd, "\t", "Mark"); +ce_mark_pr(const waypoint* wp) +{ + char* id; + + if (inRoute) { + id = ce_find_uuid(wp); + if (id == NULL) { + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + id = xml_buffer; + } + } + /* Have we seen and written the (nearly) same waypoint ? */ + else if (ce_find_wpt(wp) != NULL) { + return; + } else { + ce_mark* mark = ce_alloc_mark(wp, NULL); + ENQUEUE_TAIL(&ce_mark_head, &mark->Q); + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + id = xml_buffer; + } + write_xml_entity_begin2(ofd, "\t", "Mark", + "created", ce_gen_creation_time(wp->creation_time), + "id", id); + ce_waypt_pr(wp); + write_xml_entity_end(ofd, "\t", "Mark"); } /* Generate all route marks */ static void ce_marks_pr(void) { - queue *elem, *tmp; + queue* elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - ce_mark_pr(mark->wp); - } + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark* mark = (ce_mark*) elem; + ce_mark_pr(mark->wp); + } } /* Release all generated marks */ static void ce_marks_flush_all(void) { - queue *elem, *tmp; + queue* elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - ce_free_mark(mark); - } + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark* mark = (ce_mark*) elem; + ce_free_mark(mark); + } } /* Write all routes and marks */ void ce_write(void) { - /* If doing routes, we write out the routes and all the standalone waypoints. - If doing waypoints, we write out the route waypoints (without the routes) and - the standalone waypoints. - */ - time_t now = 0; - now = current_time(); - - write_xml_header(ofd); - write_xml_entity_begin1(ofd, "", "NavObjectCollection", "created", - ce_gen_current_time()); - write_xml_entity(ofd, "\t", "Name", "Navigation Objects"); - - inRoute = 1; - route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp); - ce_marks_pr(); - inRoute = 0; - - waypt_disp_all(ce_mark_pr); - ce_marks_flush_all(); - - write_xml_entity_end(ofd, "", "NavObjectCollection"); + /* If doing routes, we write out the routes and all the standalone waypoints. + If doing waypoints, we write out the route waypoints (without the routes) and + the standalone waypoints. + */ + time_t now = 0; + now = current_time(); + + write_xml_header(ofd); + write_xml_entity_begin1(ofd, "", "NavObjectCollection", "created", + ce_gen_current_time()); + write_xml_entity(ofd, "\t", "Name", "Navigation Objects"); + + inRoute = 1; + route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp); + ce_marks_pr(); + inRoute = 0; + + waypt_disp_all(ce_mark_pr); + ce_marks_flush_all(); + + write_xml_entity_end(ofd, "", "NavObjectCollection"); } ff_vecs_t coastexp_vecs = { - ff_type_file, - { ff_cap_read|ff_cap_write, ff_cap_none, ff_cap_read|ff_cap_write }, - ce_rd_init, - ce_wr_init, - ce_rd_deinit, - ce_wr_deinit, - ce_read, - ce_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { (ff_cap)(ff_cap_read|ff_cap_write), ff_cap_none, (ff_cap)(ff_cap_read|ff_cap_write) }, + ce_rd_init, + ce_wr_init, + ce_rd_deinit, + ce_wr_deinit, + ce_read, + ce_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/compegps.c b/gpsbabel/compegps.c index eb5fa0f59..196303038 100644 --- a/gpsbabel/compegps.c +++ b/gpsbabel/compegps.c @@ -28,12 +28,12 @@ 08/13/2006: switch to gbfile api */ -/* - +/* + the meaning of leading characters in CompeGPS data lines (enhanced PCX): - header lines: - + header lines: + "G": WGS 84 - Datum of the map "N": Anybody - Name of the user "L": -02:00:00 - Difference to UTC @@ -44,16 +44,16 @@ "C": 0 0 255 2 -1.000000 - ??? "V": 0.0 0.0 0 0 0 0 0.0 - ??? "E": 0|1|00-NUL-00 00:00:00|00:00:00|0 - ??? - + data lines: - + "W": if(route) routepoint; else waypoint - "T": trackpoint + "T": trackpoint "t": if(track) additionally track info if(!track) additionally trackpoint info "a": link to ... "w": waypoint additional info - + */ #include "defs.h" @@ -71,7 +71,7 @@ #define SHORT_NAME_LENGTH 16 -static gbfile *fin, *fout; +static gbfile* fin, *fout; static int target_index, curr_index; static int track_info_flag; static short_handle sh; @@ -79,614 +79,637 @@ static int snlen; static int radius; static int input_datum; -static route_head *curr_track; -static route_head *curr_route; +static route_head* curr_track; +static route_head* curr_route; /* placeholders for options */ -static char *option_icon; -static char *option_index; -static char *option_radius; -static char *option_snlen; +static char* option_icon; +static char* option_index; +static char* option_radius; +static char* option_snlen; static arglist_t compegps_args[] = { - {"deficon", &option_icon, "Default icon name", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"index", &option_index, "Index of route/track to write (if more than one in source)", - NULL, ARGTYPE_INT, "1", NULL}, - {"radius", &option_radius, "Give points (waypoints/route points) a default radius (proximity)", - NULL, ARGTYPE_FLOAT, "0", NULL}, - {"snlen", &option_snlen, "Length of generated shortnames (default 16)", - "16", ARGTYPE_INT, "1", NULL}, - ARG_TERMINATOR + { + "deficon", &option_icon, "Default icon name", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "index", &option_index, "Index of route/track to write (if more than one in source)", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "radius", &option_radius, "Give points (waypoints/route points) a default radius (proximity)", + NULL, ARGTYPE_FLOAT, "0", NULL + }, + { + "snlen", &option_snlen, "Length of generated shortnames (default 16)", + "16", ARGTYPE_INT, "1", NULL + }, + ARG_TERMINATOR }; static -void fix_datum(double *lat, double *lon) +void fix_datum(double* lat, double* lon) { - double amt; - - /* - * Avoid FP jitter in the common case. - */ - if (input_datum != DATUM_WGS84) { - GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, lat, lon, - &amt, input_datum); - } + double amt; + + /* + * Avoid FP jitter in the common case. + */ + if (input_datum != DATUM_WGS84) { + GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, lat, lon, + &amt, input_datum); + } } static void -compegps_parse_date(const char *c, struct tm* tm) +compegps_parse_date(const char* c, struct tm* tm) { - char month[4]; - int year; - tm->tm_mday = atoi(c); - strncpy(month, c+3, 3); - month[3] = 0; - tm->tm_mon = month_lookup(month); - year = atoi(c + 7); - if (year < 70) - year += 100; - if (year > 1900) - year -= 1900; - tm->tm_year = year; - // if (tm->tm_year < 70) tm->tm_year += 100; + char month[4]; + int year; + tm->tm_mday = atoi(c); + strncpy(month, c+3, 3); + month[3] = 0; + tm->tm_mon = month_lookup(month); + year = atoi(c + 7); + if (year < 70) { + year += 100; + } + if (year > 1900) { + year -= 1900; + } + tm->tm_year = year; + // if (tm->tm_year < 70) tm->tm_year += 100; } static void -compegps_parse_time(const char *c, struct tm* tm) +compegps_parse_time(const char* c, struct tm* tm) { - tm->tm_hour = atoi(c); - tm->tm_min = atoi(c+3); - tm->tm_sec = atoi(c+6); + tm->tm_hour = atoi(c); + tm->tm_min = atoi(c+3); + tm->tm_sec = atoi(c+6); } /* specialized readers */ static waypoint* -parse_wpt(char *buff) +parse_wpt(char* buff) { - int col = -1; - char *c, *cx; - waypoint *wpt = waypt_new(); - struct tm tm; - int has_time = 0; - memset(&tm, 0, sizeof(tm)); - - c = strstr(buff, "A "); - if (c == buff) col++; - - c = csv_lineparse(buff, " ", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + int col = -1; + char* c, *cx; + waypoint* wpt = waypt_new(); + struct tm tm; + int has_time = 0; + memset(&tm, 0, sizeof(tm)); + + c = strstr(buff, "A "); + if (c == buff) { + col++; + } + + c = csv_lineparse(buff, " ", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_wpt: col(%d)=%s\n", col, c); + printf(MYNAME "_read_wpt: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 0: - - cx = c + strlen(c) - 1; /* trim trailing underscores */ - while ((cx >= c) && (*cx == '_')) *cx-- = '\0'; - if (*c != '\0') - wpt->shortname = xstrdup(c); - break; - case 2: - human_to_dec(c, &wpt->latitude, NULL, 1); - break; - case 3: - human_to_dec(c, NULL, &wpt->longitude, 2); - break; - // Older compegps used a dumb constant. - // Report are that 2010-era writes a sensible - // value here. - /* always "27-MAR-62 00:00:00" */ - case 4: - if (strcmp(c, "27-MAR-62")) { - has_time = 1; - compegps_parse_date(c, &tm); - } - break; - case 5: - if (has_time) { - compegps_parse_time(c, &tm); - wpt->creation_time = mkgmtime(&tm); - } - case 6: - wpt->altitude = atof(c); - break; - case 7: - wpt->description = xstrdup(c); - break; - default: - if (col > 7) - { - wpt->description = xstrappend(wpt->description, " "); - wpt->description = xstrappend(wpt->description, c); - } - } - } - c = csv_lineparse(NULL, " ", "", col++); - } - fix_datum(&wpt->latitude, &wpt->longitude); - return wpt; + switch (col) { + case 0: + + cx = c + strlen(c) - 1; /* trim trailing underscores */ + while ((cx >= c) && (*cx == '_')) { + *cx-- = '\0'; + } + if (*c != '\0') { + wpt->shortname = xstrdup(c); + } + break; + case 2: + human_to_dec(c, &wpt->latitude, NULL, 1); + break; + case 3: + human_to_dec(c, NULL, &wpt->longitude, 2); + break; + // Older compegps used a dumb constant. + // Report are that 2010-era writes a sensible + // value here. + /* always "27-MAR-62 00:00:00" */ + case 4: + if (strcmp(c, "27-MAR-62")) { + has_time = 1; + compegps_parse_date(c, &tm); + } + break; + case 5: + if (has_time) { + compegps_parse_time(c, &tm); + wpt->creation_time = mkgmtime(&tm); + } + case 6: + wpt->altitude = atof(c); + break; + case 7: + wpt->description = xstrdup(c); + break; + default: + if (col > 7) { + wpt->description = xstrappend(wpt->description, " "); + wpt->description = xstrappend(wpt->description, c); + } + } + } + c = csv_lineparse(NULL, " ", "", col++); + } + fix_datum(&wpt->latitude, &wpt->longitude); + return wpt; } static void -parse_wpt_info(const char *buff, waypoint *wpt) /* "w" */ +parse_wpt_info(const char* buff, waypoint* wpt) /* "w" */ { - char *c; - int col = -1; - double fx; - - c = csv_lineparse(buff, ",", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + char* c; + int col = -1; + double fx; + + c = csv_lineparse(buff, ",", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_wpt_info: col(%d)=%s\n", col, c); + printf(MYNAME "_read_wpt_info: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 0: - wpt->icon_descr = xstrdup(c); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - break; - case 1: break; /* Text postion */ - case 2: break; /* Lens zoom level */ - case 3: break; /* Text colour */ - case 4: break; /* Background colour */ - case 5: break; /* Transparent text  (0=transparent, 1=no transparent) */ - case 6: break; /* ??? */ - case 7: break; /* ??? */ - case 8: /* radius */ - fx = atof(c); - if (fx > 0) WAYPT_SET(wpt, proximity, fx); - break; - } - } - c = csv_lineparse(NULL, ",", "", col++); - } + switch (col) { + case 0: + wpt->icon_descr = xstrdup(c); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 1: + break; /* Text postion */ + case 2: + break; /* Lens zoom level */ + case 3: + break; /* Text colour */ + case 4: + break; /* Background colour */ + case 5: + break; /* Transparent text  (0=transparent, 1=no transparent) */ + case 6: + break; /* ??? */ + case 7: + break; /* ??? */ + case 8: /* radius */ + fx = atof(c); + if (fx > 0) { + WAYPT_SET(wpt, proximity, fx); + } + break; + } + } + c = csv_lineparse(NULL, ",", "", col++); + } } -static waypoint * -parse_trkpt(char *buff) +static waypoint* +parse_trkpt(char* buff) { - int col = -1; - char *c; - struct tm tm; - waypoint *wpt = waypt_new(); - - c = strstr(buff, "A "); - if (c == buff) col++; - - memset(&tm, 0, sizeof(tm)); - c = csv_lineparse(buff, " ", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + int col = -1; + char* c; + struct tm tm; + waypoint* wpt = waypt_new(); + + c = strstr(buff, "A "); + if (c == buff) { + col++; + } + + memset(&tm, 0, sizeof(tm)); + c = csv_lineparse(buff, " ", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_trkpt: col(%d)=%s\n", col, c); + printf(MYNAME "_read_trkpt: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 2: - human_to_dec(c, &wpt->latitude, NULL, 1); - break; - case 3: - human_to_dec(c, NULL, &wpt->longitude, 2); - break; - case 4: - compegps_parse_date(c, &tm); - break; - case 5: - compegps_parse_time(c, &tm); - wpt->creation_time = mkgmtime(&tm); - break; - case 7: - wpt->altitude = atof(c); - break; - } - } - c = csv_lineparse(NULL, " ", "", col++); - } - fix_datum(&wpt->latitude, &wpt->longitude); - return wpt; + switch (col) { + case 2: + human_to_dec(c, &wpt->latitude, NULL, 1); + break; + case 3: + human_to_dec(c, NULL, &wpt->longitude, 2); + break; + case 4: + compegps_parse_date(c, &tm); + break; + case 5: + compegps_parse_time(c, &tm); + wpt->creation_time = mkgmtime(&tm); + break; + case 7: + wpt->altitude = atof(c); + break; + } + } + c = csv_lineparse(NULL, " ", "", col++); + } + fix_datum(&wpt->latitude, &wpt->longitude); + return wpt; } static void -parse_track_info(const char *buff, route_head *track) /* "t" */ +parse_track_info(const char* buff, route_head* track) /* "t" */ { - char *c; - int col = -1; - - c = csv_lineparse(buff, "|", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + char* c; + int col = -1; + + c = csv_lineparse(buff, "|", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_track_info: col(%d)=%s\n", col, c); + printf(MYNAME "_read_track_info: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 0: - break; /* unknown field */ - case 1: - track->rte_name = xstrdup(c); - break; - case 2: - break; /* unknown field */ - case 3: - break; /* unknown field */ - } - } - c = csv_lineparse(NULL, "|", "", col++); - } + switch (col) { + case 0: + break; /* unknown field */ + case 1: + track->rte_name = xstrdup(c); + break; + case 2: + break; /* unknown field */ + case 3: + break; /* unknown field */ + } + } + c = csv_lineparse(NULL, "|", "", col++); + } } static void -parse_rte_info(const char *buff, route_head *route) /* "R" */ +parse_rte_info(const char* buff, route_head* route) /* "R" */ { - char *c; - int col = -1; - - c = csv_lineparse(buff, ",", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + char* c; + int col = -1; + + c = csv_lineparse(buff, ",", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_rte_info: col(%d)=%s\n", col, c); + printf(MYNAME "_read_rte_info: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 0: break; /* unknown field (colour?) */ - case 1: - route->rte_name = xstrdup(c); - break; - case 2: break; /* unknown field */ - - } - } - c = csv_lineparse(NULL, ",", "", col++); - } + switch (col) { + case 0: + break; /* unknown field (colour?) */ + case 1: + route->rte_name = xstrdup(c); + break; + case 2: + break; /* unknown field */ + + } + } + c = csv_lineparse(NULL, ",", "", col++); + } } /* main functions */ static void -compegps_rd_init(const char *fname) +compegps_rd_init(const char* fname) { - fin = gbfopen(fname, "rb", MYNAME); - input_datum = DATUM_WGS84; + fin = gbfopen(fname, "rb", MYNAME); + input_datum = DATUM_WGS84; } static void compegps_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void compegps_data_read(void) { - char *buff; - int line = 0; - int input_datum; - waypoint *wpt = NULL; - route_head *route = NULL; - route_head *track = NULL; - - while ((buff = gbfgetstr(fin))) - { - char *cin = buff; - char *ctail; - - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - cin = lrtrim(buff); - if (strlen(cin) == 0) continue; - - ctail = strchr(cin, ' '); - if (ctail == NULL) continue; - ctail = lrtrim(ctail); - - switch(*cin) - { - case 'G': - input_datum = GPS_Lookup_Datum_Index(ctail); - if (input_datum < 0) { - fatal( MYNAME ": Unsupported datum \"%s\"!", ctail); - } - break; - case 'U': - switch(*ctail) - { - case '1': /* lat/lon, that's we want to see */ - break; - case '0': /* UTM not supported yet */ - fatal(MYNAME "Sorry, UTM is not supported yet!\n"); - default: - fatal(MYNAME "Invalid system of coordinates (%s)!\n", cin); - } - break; - case 'R': - route = route_head_alloc(); - route_add_head(route); - parse_rte_info(ctail, route); - break; - case 'M': - break; - case 'W': - wpt = parse_wpt(ctail); - if (wpt != NULL) - { - if (route != NULL) - route_add_wpt(route, wpt); - else - waypt_add(wpt); - } - break; - case 'w': - is_fatal((wpt == NULL), MYNAME ": No waypoint data before \"%s\"!", cin); - parse_wpt_info(ctail, wpt); - break; - case 'T': - wpt = parse_trkpt(ctail); - if (wpt != NULL) - { - if (track == NULL) - { - track = route_head_alloc(); - track_add_head(track); - } - track_add_wpt(track, wpt); - } - break; - case 't': - if (track != NULL) - parse_track_info(ctail, track); - break; - } - } + char* buff; + int line = 0; + int input_datum; + waypoint* wpt = NULL; + route_head* route = NULL; + route_head* track = NULL; + + while ((buff = gbfgetstr(fin))) { + char* cin = buff; + char* ctail; + + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + cin = lrtrim(buff); + if (strlen(cin) == 0) { + continue; + } + + ctail = strchr(cin, ' '); + if (ctail == NULL) { + continue; + } + ctail = lrtrim(ctail); + + switch (*cin) { + case 'G': + input_datum = GPS_Lookup_Datum_Index(ctail); + if (input_datum < 0) { + fatal(MYNAME ": Unsupported datum \"%s\"!", ctail); + } + break; + case 'U': + switch (*ctail) { + case '1': /* lat/lon, that's we want to see */ + break; + case '0': /* UTM not supported yet */ + fatal(MYNAME "Sorry, UTM is not supported yet!\n"); + default: + fatal(MYNAME "Invalid system of coordinates (%s)!\n", cin); + } + break; + case 'R': + route = route_head_alloc(); + route_add_head(route); + parse_rte_info(ctail, route); + break; + case 'M': + break; + case 'W': + wpt = parse_wpt(ctail); + if (wpt != NULL) { + if (route != NULL) { + route_add_wpt(route, wpt); + } else { + waypt_add(wpt); + } + } + break; + case 'w': + is_fatal((wpt == NULL), MYNAME ": No waypoint data before \"%s\"!", cin); + parse_wpt_info(ctail, wpt); + break; + case 'T': + wpt = parse_trkpt(ctail); + if (wpt != NULL) { + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + } + track_add_wpt(track, wpt); + } + break; + case 't': + if (track != NULL) { + parse_track_info(ctail, track); + } + break; + } + } } /* ----------------------------------------------------------- */ static void -write_waypt_cb(const waypoint *wpt) +write_waypt_cb(const waypoint* wpt) { - char *name; - - if (curr_index != target_index ) return; - - name = (snlen > 0) ? mkshort_from_wpt(sh, wpt) : csv_stringclean(wpt->shortname, " "); - - gbfprintf(fout, "W %s A ", name); - gbfprintf(fout, "%.10f%c%c ", - fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S'); - gbfprintf(fout, "%.10f%c%c ", - fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); - gbfprintf(fout, "27-MAR-62 00:00:00 %.6f", - (wpt->altitude != unknown_alt) ? wpt->altitude : 0.0); - if (wpt->description != NULL) - gbfprintf(fout, " %s", wpt->description); - gbfprintf(fout, "\n"); - - if ((wpt->icon_descr != NULL) || (wpt->wpt_flags.proximity) || \ - (option_icon != NULL)) - { - char *icon = option_icon; - - if (wpt->icon_descr != NULL) icon = (char *) wpt->icon_descr; - - gbfprintf(fout, "w %s,0,0.0,16777215,255,1,7,,%.1f\n", - (icon != NULL) ? icon : "Waypoint", - WAYPT_GET(wpt, proximity, 0)); - } - xfree(name); + char* name; + + if (curr_index != target_index) { + return; + } + + name = (snlen > 0) ? mkshort_from_wpt(sh, wpt) : csv_stringclean(wpt->shortname, " "); + + gbfprintf(fout, "W %s A ", name); + gbfprintf(fout, "%.10f%c%c ", + fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S'); + gbfprintf(fout, "%.10f%c%c ", + fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); + gbfprintf(fout, "27-MAR-62 00:00:00 %.6f", + (wpt->altitude != unknown_alt) ? wpt->altitude : 0.0); + if (wpt->description != NULL) { + gbfprintf(fout, " %s", wpt->description); + } + gbfprintf(fout, "\n"); + + if ((wpt->icon_descr != NULL) || (wpt->wpt_flags.proximity) || \ + (option_icon != NULL)) { + char* icon = option_icon; + + if (wpt->icon_descr != NULL) { + icon = (char*) wpt->icon_descr; + } + + gbfprintf(fout, "w %s,0,0.0,16777215,255,1,7,,%.1f\n", + (icon != NULL) ? icon : "Waypoint", + WAYPT_GET(wpt, proximity, 0)); + } + xfree(name); } -static void -write_route_hdr_cb(const route_head *rte) +static void +write_route_hdr_cb(const route_head* rte) { - char *name; - curr_route = (route_head *) rte; - curr_index++; - if (curr_index != target_index) return; - - name = rte->rte_name; - if (name != NULL) - name = csv_stringclean(name, ","); - else - name = xstrdup(" "); - gbfprintf(fout, "R 16711680,%s,1,-1\n", name); - xfree(name); + char* name; + curr_route = (route_head*) rte; + curr_index++; + if (curr_index != target_index) { + return; + } + + name = rte->rte_name; + if (name != NULL) { + name = csv_stringclean(name, ","); + } else { + name = xstrdup(" "); + } + gbfprintf(fout, "R 16711680,%s,1,-1\n", name); + xfree(name); } -static void +static void write_route(void) { - curr_index = 0; - route_disp_all(write_route_hdr_cb, NULL, write_waypt_cb); + curr_index = 0; + route_disp_all(write_route_hdr_cb, NULL, write_waypt_cb); } static void -write_track_hdr_cb(const route_head *trk) +write_track_hdr_cb(const route_head* trk) { - track_info_flag = 0; - curr_track = (route_head *) trk; - - curr_index++; - if (curr_index != target_index) return; - - track_info_flag = 1; + track_info_flag = 0; + curr_track = (route_head*) trk; + + curr_index++; + if (curr_index != target_index) { + return; + } + + track_info_flag = 1; } static void -write_trkpt_cb(const waypoint *wpt) +write_trkpt_cb(const waypoint* wpt) { - char buff[128]; - struct tm tm; - - if ((curr_index != target_index) || (wpt == NULL)) return; - - buff[0] = '\0'; - - if (wpt->creation_time != 0) - { - tm = *gmtime(&wpt->creation_time); - strftime(buff, sizeof(buff), "%d-%b-%y %H:%M:%S", &tm); - strupper(buff); - } - else strncpy(buff, "01-JAN-70 00:00:00", sizeof(buff)); - - gbfprintf(fout, "T A %.10f%c%c %.10f%c%c ", - fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S', - fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); - gbfprintf(fout, "%s s %.1f %.1f %.1f %.1f %d ", - buff, - wpt->altitude, - 0.0, - 0.0, - 0.0, - 0); - gbfprintf(fout, "%.1f %.1f %.1f %.1f %.1f\n", - -1000.0, - -1.0, - -1.0, - -1.0, - -1.0); - if (track_info_flag != 0) - { - track_info_flag = 0; - if (curr_track->rte_name != NULL) - { - char *name; - - name = csv_stringclean(curr_track->rte_name, "|"); - gbfprintf(fout, "t 4294967295|%s|-1|-1\n", name); - xfree(name); - } - } + char buff[128]; + struct tm tm; + + if ((curr_index != target_index) || (wpt == NULL)) { + return; + } + + buff[0] = '\0'; + + if (wpt->creation_time != 0) { + tm = *gmtime(&wpt->creation_time); + strftime(buff, sizeof(buff), "%d-%b-%y %H:%M:%S", &tm); + strupper(buff); + } else { + strncpy(buff, "01-JAN-70 00:00:00", sizeof(buff)); + } + + gbfprintf(fout, "T A %.10f%c%c %.10f%c%c ", + fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S', + fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); + gbfprintf(fout, "%s s %.1f %.1f %.1f %.1f %d ", + buff, + wpt->altitude, + 0.0, + 0.0, + 0.0, + 0); + gbfprintf(fout, "%.1f %.1f %.1f %.1f %.1f\n", + -1000.0, + -1.0, + -1.0, + -1.0, + -1.0); + if (track_info_flag != 0) { + track_info_flag = 0; + if (curr_track->rte_name != NULL) { + char* name; + + name = csv_stringclean(curr_track->rte_name, "|"); + gbfprintf(fout, "t 4294967295|%s|-1|-1\n", name); + xfree(name); + } + } } static void write_track(void) { - curr_index = 0; - + curr_index = 0; + // gbfprintf(fout, "L +02:00:00\n"); - track_disp_all(write_track_hdr_cb, NULL, write_trkpt_cb); - gbfprintf(fout, "F 1234\n"); + track_disp_all(write_track_hdr_cb, NULL, write_trkpt_cb); + gbfprintf(fout, "F 1234\n"); } static void write_waypoints(void) { - waypt_disp_all(write_waypt_cb); + waypt_disp_all(write_waypt_cb); } /* --------------------------------------------------------------------------- */ static void -compegps_wr_init(const char *fname) +compegps_wr_init(const char* fname) { - fout = gbfopen(fname, "w", MYNAME); - sh = mkshort_new_handle(); + fout = gbfopen(fname, "w", MYNAME); + sh = mkshort_new_handle(); } static void compegps_wr_deinit(void) { - mkshort_del_handle(&sh); - gbfclose(fout); + mkshort_del_handle(&sh); + gbfclose(fout); } static void compegps_data_write(void) { - /* because of different file extensions we can only write one GPS data type at time */ - - gbfprintf(fout, "G WGS 84\n"); - gbfprintf(fout, "U 1\n"); - - /* process options */ - - target_index = 1; - if (option_index != NULL) - target_index = atoi(option_index); - - snlen = 0; - if (global_opts.synthesize_shortnames != 0) - { - if (option_snlen != NULL) - snlen = atoi(option_snlen); - else - snlen = SHORT_NAME_LENGTH; - - is_fatal((snlen < 1), MYNAME "Invalid length for generated shortnames!"); - - setshort_whitespace_ok(sh, 0); - setshort_length(sh, snlen); - } - - radius = -1; - if (option_radius != 0) - { - radius = atof(option_radius); - is_fatal((radius <= 0.0), MYNAME "Invalid value for radius!"); - } - - if (option_icon != NULL) - { - if (*option_icon == '\0') - option_icon = NULL; - else if (case_ignore_strcmp(option_icon, "deficon") == 0) - option_icon = NULL; - } - - switch(global_opts.objective) - { - case wptdata: - curr_index = target_index = 0; - write_waypoints(); - break; - case trkdata: - write_track(); - break; - case rtedata: - write_route(); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - } + /* because of different file extensions we can only write one GPS data type at time */ + + gbfprintf(fout, "G WGS 84\n"); + gbfprintf(fout, "U 1\n"); + + /* process options */ + + target_index = 1; + if (option_index != NULL) { + target_index = atoi(option_index); + } + + snlen = 0; + if (global_opts.synthesize_shortnames != 0) { + if (option_snlen != NULL) { + snlen = atoi(option_snlen); + } else { + snlen = SHORT_NAME_LENGTH; + } + + is_fatal((snlen < 1), MYNAME "Invalid length for generated shortnames!"); + + setshort_whitespace_ok(sh, 0); + setshort_length(sh, snlen); + } + + radius = -1; + if (option_radius != 0) { + radius = atof(option_radius); + is_fatal((radius <= 0.0), MYNAME "Invalid value for radius!"); + } + + if (option_icon != NULL) { + if (*option_icon == '\0') { + option_icon = NULL; + } else if (case_ignore_strcmp(option_icon, "deficon") == 0) { + option_icon = NULL; + } + } + + switch (global_opts.objective) { + case wptdata: + case unknown_gpsdata: + curr_index = target_index = 0; + write_waypoints(); + break; + case trkdata: + write_track(); + break; + case rtedata: + write_route(); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } } /* --------------------------------------------------------------------------- */ ff_vecs_t compegps_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - compegps_rd_init, - compegps_wr_init, - compegps_rd_deinit, - compegps_wr_deinit, - compegps_data_read, - compegps_data_write, - NULL, - compegps_args, - CET_CHARSET_MS_ANSI, 1 + ff_type_file, + FF_CAP_RW_ALL, + compegps_rd_init, + compegps_wr_init, + compegps_rd_deinit, + compegps_wr_deinit, + compegps_data_read, + compegps_data_write, + NULL, + compegps_args, + CET_CHARSET_MS_ANSI, 1 }; #endif /* CSVFMTS_ENABLED */ diff --git a/gpsbabel/config.h.in b/gpsbabel/config.h.in index 393348a85..18a7c51c0 100644 --- a/gpsbabel/config.h.in +++ b/gpsbabel/config.h.in @@ -30,6 +30,9 @@ /* Define to 1 if you have the `sleep' function. */ #undef HAVE_SLEEP +/* Define to 1 if you have the `glob' function. */ +#undef HAVE_GLOB + /* Define to 1 if you have the `uname' function. */ #undef HAVE_UNAME @@ -75,3 +78,5 @@ /* 1 to inhibit our use of zlib. */ #undef ZLIB_INHIBITED + +#undef HAVE_WDK diff --git a/gpsbabel/configure b/gpsbabel/configure index 7f477376d..fdd746166 100755 --- a/gpsbabel/configure +++ b/gpsbabel/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for GPSBabel 1.4.2. +# Generated by GNU Autoconf 2.61 for GPSBabel 1.4.3. # # Report bugs to . # @@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='GPSBabel' PACKAGE_TARNAME='gpsbabel' -PACKAGE_VERSION='1.4.2' -PACKAGE_STRING='GPSBabel 1.4.2' +PACKAGE_VERSION='1.4.3' +PACKAGE_STRING='GPSBabel 1.4.3' PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS' # Factoring default headers for most tests. @@ -1212,7 +1212,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures GPSBabel 1.4.2 to adapt to many kinds of systems. +\`configure' configures GPSBabel 1.4.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1278,7 +1278,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of GPSBabel 1.4.2:";; + short | recursive ) echo "Configuration of GPSBabel 1.4.3:";; esac cat <<\_ACEOF @@ -1375,7 +1375,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -GPSBabel configure 1.4.2 +GPSBabel configure 1.4.3 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1389,7 +1389,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by GPSBabel $as_me 1.4.2, which was +It was created by GPSBabel $as_me 1.4.3, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -1745,13 +1745,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu DOCVERSION=`echo $PACKAGE_VERSION` # 1.4.1 is a tiny tweak to 1.4.0. Use that doc. -DOCVERSION=1.4.2 +DOCVERSION=1.4.3 # Increase GBBUILD for a new release -GBBUILD=22 +GBBUILD=24 # YYYYMMDD, please, if beta, i.e. "-beta20060413" -# PACKAGE_RELEASE="-beta20100518" +# PACKAGE_RELEASE="-beta20120114" # DOCVERSION=development cat >>confdefs.h <<_ACEOF @@ -4179,7 +4179,67 @@ echo "${ECHO_T}USB skipped" >&6; } OSJEEPS=jeeps/gpsusbstub.o else OSJEEPS=jeeps/gpsusbwin.o - USB_LIBS="-lsetupapi -lhid" + USB_LIBS="-lsetupapi" + { echo "$as_me:$LINENO: checking for Windows DDK" >&5 +echo $ECHO_N "checking for Windows DDK... $ECHO_C" >&6; } + old_LIBS="$LIBS" + LIBS="$LIBS -lhid" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + #include +int +main () +{ +HANDLE HidDeviceObject; + HIDD_ATTRIBUTES Attributes; + HidD_GetAttributes(HidDeviceObject, &Attributes); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WDK 1 +_ACEOF + + USB_LIBS=${USB_LIBS}" -lhid" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$old_LIBS" fi ;; *-*-darwin*) @@ -4378,7 +4438,8 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } - cat >>confdefs.h <<\_ACEOF + +cat >>confdefs.h <<\_ACEOF #define HAVE_LINUX_HID 1 _ACEOF @@ -4457,34 +4518,16 @@ else # libexpat installed via fink EXPAT_LIB=/sw/lib/libexpat.a LIBS="$LIBS -L/sw/lib" - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBEXPAT 1 -_ACEOF - - fi if test -f /opt/local/lib/libexpat.a ; then # libexpat installed via macports EXPAT_LIB=/opt/local/lib/libexpat.a LIBS="$LIBS -L/opt/local/lib" - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBEXPAT 1 -_ACEOF - - fi if test -f /usr/local/lib/libexpat.a ; then # libexpat installed from source EXPAT_LIB=/usr/local/lib/libexpat.a LIBS="$LIBS -L/usr/local/lib" - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBEXPAT 1 -_ACEOF - - fi ;; *-gentoo-freebsd*) @@ -4493,26 +4536,26 @@ _ACEOF *-*-freebsd*) if test -f /usr/local/lib/libexpat.a ; then EXPAT_LIB=/usr/local/lib/libexpat.a - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBEXPAT 1 -_ACEOF - - fi ;; - *) - EXPAT_LIB=-lexpat - ;; esac fi -{ echo "$as_me:$LINENO: result: $EXPAT_LIB" >&5 + +if ! test "x${EXPAT_LIB}" = x; then + { echo "$as_me:$LINENO: result: $EXPAT_LIB" >&5 echo "${ECHO_T}$EXPAT_LIB" >&6; } -{ echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5 +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + +else + { echo "$as_me:$LINENO: result: try to autodetect" >&5 +echo "${ECHO_T}try to autodetect" >&6; } + { echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5 echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6; } if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -4579,7 +4622,9 @@ cat >>confdefs.h <<\_ACEOF #define HAVE_LIBEXPAT 1 _ACEOF + EXPAT_LIB=-lexpat +fi fi @@ -4640,7 +4685,8 @@ fi -for ac_func in nanosleep sleep uname + +for ac_func in nanosleep sleep uname glob do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -5338,7 +5384,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by GPSBabel $as_me 1.4.2, which was +This file was extended by GPSBabel $as_me 1.4.3, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5387,7 +5433,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -GPSBabel config.status 1.4.2 +GPSBabel config.status 1.4.3 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/gpsbabel/configure.in b/gpsbabel/configure.in index 102f4de18..484d3ac46 100644 --- a/gpsbabel/configure.in +++ b/gpsbabel/configure.in @@ -3,17 +3,17 @@ AC_PREREQ(2.59) -AC_INIT(GPSBabel, 1.4.2, BUG-REPORT-ADDRESS) +AC_INIT(GPSBabel, 1.4.3, BUG-REPORT-ADDRESS) DOCVERSION=`echo $PACKAGE_VERSION` # 1.4.1 is a tiny tweak to 1.4.0. Use that doc. -DOCVERSION=1.4.2 +DOCVERSION=1.4.3 # Increase GBBUILD for a new release -GBBUILD=22 +GBBUILD=24 # YYYYMMDD, please, if beta, i.e. "-beta20060413" -# PACKAGE_RELEASE="-beta20100518" +# PACKAGE_RELEASE="-beta20120114" # DOCVERSION=development AC_DEFINE_UNQUOTED(PACKAGE_RELEASE, "$PACKAGE_RELEASE", [Define to the release name of this package.]) AC_SUBST(PACKAGE_RELEASE) @@ -162,7 +162,21 @@ case "$target" in OSJEEPS=jeeps/gpsusbstub.o else OSJEEPS=jeeps/gpsusbwin.o - USB_LIBS="-lsetupapi -lhid" + USB_LIBS="-lsetupapi" + AC_MSG_CHECKING(for Windows DDK) + old_LIBS="$LIBS" + LIBS="$LIBS -lhid" + AC_TRY_LINK([#include ] + [#include ], + [HANDLE HidDeviceObject; + HIDD_ATTRIBUTES Attributes; + HidD_GetAttributes(HidDeviceObject, &Attributes);], + [AC_MSG_RESULT(yes)] + [AC_DEFINE(HAVE_WDK, 1, [Defined if you have Windows DDK])] + [USB_LIBS=${USB_LIBS}" -lhid"], + [AC_MSG_RESULT(no)] + ) + LIBS="$old_LIBS" fi ;; *-*-darwin*) @@ -232,7 +246,7 @@ case "$target" in ioctl(0, HIDIOCSREPORT, &rinfo); }], AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_LINUX_HID, 1), + AC_DEFINE(HAVE_LINUX_HID, 1, [Defined if you have Linux HID]), AC_MSG_RESULT(no)) ;; esac @@ -289,22 +303,16 @@ AC_ARG_WITH(libexpat, # libexpat installed via fink EXPAT_LIB=/sw/lib/libexpat.a LIBS="$LIBS -L/sw/lib" - AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) - AC_SUBST(EXPAT_LIB) fi if test -f /opt/local/lib/libexpat.a ; then # libexpat installed via macports EXPAT_LIB=/opt/local/lib/libexpat.a LIBS="$LIBS -L/opt/local/lib" - AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) - AC_SUBST(EXPAT_LIB) fi if test -f /usr/local/lib/libexpat.a ; then # libexpat installed from source EXPAT_LIB=/usr/local/lib/libexpat.a LIBS="$LIBS -L/usr/local/lib" - AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) - AC_SUBST(EXPAT_LIB) fi ;; *-gentoo-freebsd*) @@ -313,22 +321,23 @@ AC_ARG_WITH(libexpat, *-*-freebsd*) if test -f /usr/local/lib/libexpat.a ; then EXPAT_LIB=/usr/local/lib/libexpat.a - AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) - AC_SUBST(EXPAT_LIB) fi ;; - *) - EXPAT_LIB=-lexpat - ;; esac ] ) -AC_MSG_RESULT($EXPAT_LIB) -AC_CHECK_LIB([expat], [XML_ParserCreate], +if ! test "x${EXPAT_LIB}" = x; then + AC_MSG_RESULT($EXPAT_LIB) AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) - AC_SUBST(EXPAT_LIB) -) +else + AC_MSG_RESULT(try to autodetect) + AC_CHECK_LIB([expat], [XML_ParserCreate], + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + EXPAT_LIB=-lexpat + ) +fi +AC_SUBST(EXPAT_LIB) AC_MSG_CHECKING(for efence) AC_ARG_ENABLE(efence, @@ -372,7 +381,7 @@ AC_SUBST(DOCDIR) # AC_FUNC_STRTOD # AC_FUNC_VPRINTF # AC_CHECK_FUNCS([atexit floor localtime_r memmove memset pow select sqrt strchr strcspn strdup strerror strncasecmp strrchr strspn strstr strtol strtoul]) -AC_CHECK_FUNCS([nanosleep sleep uname]) +AC_CHECK_FUNCS([nanosleep sleep uname glob]) # # Checks for how the system handles va_list diff --git a/gpsbabel/copilot.c b/gpsbabel/copilot.c index 9405b9723..93c589e0c 100644 --- a/gpsbabel/copilot.c +++ b/gpsbabel/copilot.c @@ -33,80 +33,80 @@ struct record0 { - pdb_double latitude; /* PDB double format, */ - pdb_double longitude; /* similarly, neg = east */ - pdb_double magvar; /* magnetic variation in degrees, neg = east */ - gbuint32 elevation; /* feet */ + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + gbuint32 elevation; /* feet */ }; struct record1 { - pdb_double latitude; /* PDB double format, */ - pdb_double longitude; /* similarly, neg = east */ - pdb_double magvar; /* magnetic variation in degrees, neg = east */ - pdb_double elevation; /* feet */ + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + pdb_double elevation; /* feet */ }; struct record3 { - pdb_double latitude; /* PDB double format, */ - pdb_double longitude; /* similarly, neg = east */ - pdb_double magvar; /* magnetic variation in degrees, neg = east */ - pdb_double elevation; /* feet */ - char flags; /* flags */ + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + pdb_double elevation; /* feet */ + char flags; /* flags */ }; struct record4 { - pdb_double latitude; /* PDB double format, */ - pdb_double longitude; /* similarly, neg = east */ - pdb_float magvar; /* magnetic variation in degrees, neg = east */ - pdb_float elevation; /* feet */ + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_float magvar; /* magnetic variation in degrees, neg = east */ + pdb_float elevation; /* feet */ }; -static pdbfile *file_in, *file_out; -static const char *out_fname; +static pdbfile* file_in, *file_out; +static const char* out_fname; static int ct; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); + pdb_close(file_out); } static waypoint* -read_version0(void *data) +read_version0(void* data) { - char *vdata; - waypoint *wpt_tmp; + char* vdata; + waypoint* wpt_tmp; struct record0* rec = (struct record0*)data; wpt_tmp = waypt_new(); wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = FEET_TO_METERS(be_read32(&rec->elevation)); - vdata = (char *) data + sizeof(*rec); + vdata = (char*) data + sizeof(*rec); wpt_tmp->shortname = xstrdup(vdata); vdata = vdata + strlen(vdata) + 1; @@ -120,22 +120,22 @@ read_version0(void *data) } static waypoint* -read_version1(void *data) +read_version1(void* data) { - char *vdata; - waypoint *wpt_tmp; + char* vdata; + waypoint* wpt_tmp; struct record1* rec = (struct record1*)data; wpt_tmp = waypt_new(); wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = - FEET_TO_METERS(pdb_read_double(&rec->elevation)); + FEET_TO_METERS(pdb_read_double(&rec->elevation)); - vdata = (char *) data + sizeof(*rec); + vdata = (char*) data + sizeof(*rec); wpt_tmp->shortname = xstrdup(vdata); vdata = vdata + strlen(vdata) + 1; @@ -149,22 +149,22 @@ read_version1(void *data) } static waypoint* -read_version3(void *data) +read_version3(void* data) { - char *vdata; - waypoint *wpt_tmp; + char* vdata; + waypoint* wpt_tmp; struct record3* rec = (struct record3*)data; wpt_tmp = waypt_new(); wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = - FEET_TO_METERS(pdb_read_double(&rec->elevation)); + FEET_TO_METERS(pdb_read_double(&rec->elevation)); - vdata = (char *) data + sizeof(*rec); + vdata = (char*) data + sizeof(*rec); wpt_tmp->shortname = xstrdup(vdata); vdata = vdata + strlen(vdata) + 1; @@ -178,22 +178,22 @@ read_version3(void *data) } static waypoint* -read_version4(void *data) +read_version4(void* data) { - char *vdata; - waypoint *wpt_tmp; + char* vdata; + waypoint* wpt_tmp; struct record4* rec = (struct record4*)data; wpt_tmp = waypt_new(); wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = - FEET_TO_METERS(pdb_read_float(&rec->elevation)); + FEET_TO_METERS(pdb_read_float(&rec->elevation)); - vdata = (char *) data + sizeof(*rec); + vdata = (char*) data + sizeof(*rec); wpt_tmp->shortname = xstrdup(vdata); vdata = vdata + strlen(vdata) + 1; @@ -209,115 +209,111 @@ read_version4(void *data) static void data_read(void) { - pdbrec_t *pdb_rec; - - if ((file_in->creator != GXPU_CREATOR && file_in->creator != AP_P_CREATOR) || - (file_in->type != wayp_TYPE && file_in->type != swpu_TYPE && - file_in->type != wayu_TYPE)) { - fatal(MYNAME ": Not a CoPilot file.\n"); - } - if (file_in->version > 4) { - fatal(MYNAME ": %d is not a known version.\n", file_in->version); - } - - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { - waypoint *wpt_tmp; - - switch (file_in->version) - { - case 0: - wpt_tmp = read_version0(pdb_rec->data); - break; - case 1: - case 2: - wpt_tmp = read_version1(pdb_rec->data); - break; - case 3: - wpt_tmp = read_version3(pdb_rec->data); - break; - case 4: - wpt_tmp = read_version4(pdb_rec->data); - break; - default: - fatal(MYNAME ": Unknown version %d.\n", file_in->version); - } - waypt_add(wpt_tmp); - } + pdbrec_t* pdb_rec; + + if ((file_in->creator != GXPU_CREATOR && file_in->creator != AP_P_CREATOR) || + (file_in->type != wayp_TYPE && file_in->type != swpu_TYPE && + file_in->type != wayu_TYPE)) { + fatal(MYNAME ": Not a CoPilot file.\n"); + } + if (file_in->version > 4) { + fatal(MYNAME ": %d is not a known version.\n", file_in->version); + } + + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint* wpt_tmp; + + switch (file_in->version) { + case 0: + wpt_tmp = read_version0(pdb_rec->data); + break; + case 1: + case 2: + wpt_tmp = read_version1(pdb_rec->data); + break; + case 3: + wpt_tmp = read_version3(pdb_rec->data); + break; + case 4: + wpt_tmp = read_version4(pdb_rec->data); + break; + default: + fatal(MYNAME ": Unknown version %d.\n", file_in->version); + } + waypt_add(wpt_tmp); + } } static void -copilot_writewpt(const waypoint *wpt) +copilot_writewpt(const waypoint* wpt) { - struct record4 *rec; - char *vdata; - - rec = xcalloc(sizeof(*rec)+1141,1); - - pdb_write_double(&rec->latitude, RAD(wpt->latitude)); - pdb_write_double(&rec->longitude, RAD(-wpt->longitude)); - pdb_write_float(&rec->magvar, 0); - pdb_write_float(&rec->elevation, - METERS_TO_FEET(wpt->altitude)); - - vdata = (char *)rec + sizeof(*rec); - if ( wpt->shortname ) { - strncpy( vdata, wpt->shortname, 10 ); - vdata[9] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - if ( wpt->description ) { - strncpy( vdata, wpt->description, 100 ); - vdata[99] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - if ( wpt->notes ) { - strncpy( vdata, wpt->notes, 1000 ); - vdata[999] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - pdb_write_rec(file_out, 0, 2, ct++, rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct record4* rec; + char* vdata; + + rec = (struct record4*) xcalloc(sizeof(*rec)+1141,1); + + pdb_write_double(&rec->latitude, RAD(wpt->latitude)); + pdb_write_double(&rec->longitude, RAD(-wpt->longitude)); + pdb_write_float(&rec->magvar, 0); + pdb_write_float(&rec->elevation, + METERS_TO_FEET(wpt->altitude)); + + vdata = (char*)rec + sizeof(*rec); + if (wpt->shortname) { + strncpy(vdata, wpt->shortname, 10); + vdata[9] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + if (wpt->description) { + strncpy(vdata, wpt->description, 100); + vdata[99] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + if (wpt->notes) { + strncpy(vdata, wpt->notes, 1000); + vdata[999] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, rec, (char*)vdata - (char*)rec); + + xfree(rec); } static void data_write(void) { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = wayp_TYPE; - file_out->creator = GXPU_CREATOR; - file_out->version = 4; - - waypt_disp_all(copilot_writewpt); + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = wayp_TYPE; + file_out->creator = GXPU_CREATOR; + file_out->version = 4; + + waypt_disp_all(copilot_writewpt); } ff_vecs_t copilot_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/coto.c b/gpsbabel/coto.c index eff0692e7..a08d7b74d 100644 --- a/gpsbabel/coto.c +++ b/gpsbabel/coto.c @@ -2,7 +2,7 @@ Read and write cotoGPS files. Copyright (C) 2005 Tobias Minich, - + Based on the Cetus I/O Filter, Copyright (C) 2002 Robert Lipe, robertlipe@usa.net @@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA - + */ @@ -42,39 +42,39 @@ #define CATEGORY_NAME_LENGTH 16 typedef enum { - cotofixNone = 0, /* No Fix or Warning */ - cotofixReserved = 1, /* Shouldn't occur*/ - cotofix2D = 2, /* retrieved from a GPS with a 2D fix */ - cotofix3D = 3, /* retrieved from a GPS with a 3D fix */ - cotofixDGPS = 4, /* retrieved from a GPS with a DGPS signal */ + cotofixNone = 0, /* No Fix or Warning */ + cotofixReserved = 1, /* Shouldn't occur*/ + cotofix2D = 2, /* retrieved from a GPS with a 2D fix */ + cotofix3D = 3, /* retrieved from a GPS with a 3D fix */ + cotofixDGPS = 4, /* retrieved from a GPS with a DGPS signal */ } fix_quality; struct record_track { - pdb_double latitude; /* radians, s=negative */ - pdb_double longitude; /* same as lat; e=negative */ - pdb_double distance; /* Distance to thel last point; discarded since it's calculated by gpsbabel on write */ - pdb_double arc; /* Course, unknown dimension */ - pdb_double x,y; /* Internal virtual coordinates used for drawing the track on the Palm */ + pdb_double latitude; /* radians, s=negative */ + pdb_double longitude; /* same as lat; e=negative */ + pdb_double distance; /* Distance to thel last point; discarded since it's calculated by gpsbabel on write */ + pdb_double arc; /* Course, unknown dimension */ + pdb_double x,y; /* Internal virtual coordinates used for drawing the track on the Palm */ - gbuint16 alt; /* Altitude */ + gbuint16 alt; /* Altitude */ - /* accuracy and precision information for use where applicable */ - gbuint16 hdop; /* _dop * 10 */ - gbuint16 vdop; - gbuint16 pdop; - gbuint8 sat_tracked; - gbuint8 fix_quality; + /* accuracy and precision information for use where applicable */ + gbuint16 hdop; /* _dop * 10 */ + gbuint16 vdop; + gbuint16 pdop; + gbuint8 sat_tracked; + gbuint8 fix_quality; - gbuint16 speed; /* *10 */ - gbuint32 time; /* Palm Time */ + gbuint16 speed; /* *10 */ + gbuint32 time; /* Palm Time */ }; struct record_wpt { - char lon[8]; - char lat[8]; - char name[MAX_MARKER_NAME_LENGTH]; - char notes[1]; + char lon[8]; + char lat[8]; + char name[MAX_MARKER_NAME_LENGTH]; + char notes[1]; }; @@ -83,347 +83,351 @@ struct record_wpt { typedef char appinfo_category[16]; typedef struct appinfo { - gbuint8 U0; - gbuint8 renamedCategories; - appinfo_category categories[CATEGORY_NAME_LENGTH]; - gbuint8 ids[16]; - gbuint8 maxid; + gbuint8 U0; + gbuint8 renamedCategories; + appinfo_category categories[CATEGORY_NAME_LENGTH]; + gbuint8 ids[16]; + gbuint8 maxid; } appinfo_t; #define APPINFO_SIZE sizeof(appinfo_t) -static pdbfile *file_in, *file_out; -static const char *out_fname; -static const char *in_fname; /* We might need that for naming tracks */ +static pdbfile* file_in, *file_out; +static const char* out_fname; +static const char* in_fname; /* We might need that for naming tracks */ static short_handle mkshort_wr_handle; static int ct; -static char *zerocat = NULL; -static char *internals = NULL; +static char* zerocat = NULL; +static char* internals = NULL; static arglist_t coto_args[] = { - {"zerocat", &zerocat, "Name of the 'unassigned' category", NULL, - ARGTYPE_STRING, ARG_NOMINMAX }, - {"internals", &internals, "Export some internal stuff to notes", NULL, - ARGTYPE_STRING | ARGTYPE_HIDDEN, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "zerocat", &zerocat, "Name of the 'unassigned' category", NULL, + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "internals", &internals, "Export some internal stuff to notes", NULL, + ARGTYPE_STRING | ARGTYPE_HIDDEN, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); - in_fname = fname; + file_in = pdb_open(fname, MYNAME); + in_fname = fname; } static void rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); + pdb_close(file_out); } /* helpers */ -static char * -coto_get_icon_descr(int category, const appinfo_t *app) +static char* +coto_get_icon_descr(int category, const appinfo_t* app) { - char buff[CATEGORY_NAME_LENGTH + 1] = "Not Assigned"; - if ((category >= 0) && (category < 16)) - { - if ((category > 0) && (app->categories[category][0] == '\0')) - category = 0; - - strncpy(buff, app->categories[category], sizeof(buff) - 1); - if (buff[0] == '\0') - return NULL; - } - return xstrdup(buff); + char buff[CATEGORY_NAME_LENGTH + 1] = "Not Assigned"; + if ((category >= 0) && (category < 16)) { + if ((category > 0) && (app->categories[category][0] == '\0')) { + category = 0; + } + + strncpy(buff, app->categories[category], sizeof(buff) - 1); + if (buff[0] == '\0') { + return NULL; + } + } + return xstrdup(buff); } static void coto_track_read(void) { - struct record_track *rec; - pdbrec_t *pdb_rec; - route_head *trk_head; - char *track_name; - - if (strncmp(file_in->name, "cotoGPS TrackDB", PDB_DBNAMELEN) != 0) - // Use database name if not default - track_name = xstrndup(file_in->name, PDB_DBNAMELEN); - else { - // Use filename for new track title - const char *fnametmp = strrchr(in_fname, '/'); - if (fnametmp == NULL) - fnametmp = strrchr(in_fname, '\\'); - if (fnametmp) - fnametmp++; - else - fnametmp = in_fname; - if (strrchr(fnametmp, '.') != NULL) - track_name = xstrndup(fnametmp, strrchr(fnametmp,'.') - fnametmp); - else - track_name = xstrdup(fnametmp); - } - - trk_head = route_head_alloc(); - track_add_head(trk_head); - - trk_head->rte_name = track_name; - - for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - waypoint *wpt_tmp; - - wpt_tmp = waypt_new(); - - rec = (struct record_track *) pdb_rec->data; - - wpt_tmp->longitude = DEG(-pdb_read_double(&rec->longitude)); - wpt_tmp->latitude = DEG(pdb_read_double(&rec->latitude)); - - // It's not the course, so leave it out for now - // WAYPT_SET(wpt_tmp, course, pdb_read_double(&rec->arc)); - wpt_tmp->altitude = be_read16(&rec->alt); - - if (internals) - { - // Parse the option as xcsv delimiter - const char *inter = xcsv_get_char_from_constant_table(internals); - char temp[256]; - snprintf(temp, sizeof(temp), "%.20f%s%.20f%s%.20f%s%.20f", pdb_read_double(&rec->distance), inter, - pdb_read_double(&rec->arc), inter, pdb_read_double(&rec->x), inter, pdb_read_double(&rec->y)); - wpt_tmp->notes = xstrdup(temp); - } - - wpt_tmp->pdop = be_read16(&rec->pdop)/10.0; - wpt_tmp->hdop = be_read16(&rec->hdop)/10.0; - wpt_tmp->vdop = be_read16(&rec->vdop)/10.0; - wpt_tmp->sat = rec->sat_tracked; - switch (rec->fix_quality) - { - case cotofixNone: - wpt_tmp->fix = fix_none; - break; - case cotofixReserved: - wpt_tmp->fix = fix_unknown; - break; - case cotofix2D: - wpt_tmp->fix = fix_2d; - break; - case cotofix3D: - wpt_tmp->fix = fix_3d; - break; - case cotofixDGPS: - wpt_tmp->fix = fix_dgps; - break; - } - WAYPT_SET(wpt_tmp, speed, be_read16(&rec->speed)/10.0); - rec->time = be_read32(&rec->time); - if (rec->time != 0) - { - rec->time -= 2082844800U; - wpt_tmp->creation_time = rec->time; - } - track_add_wpt(trk_head, wpt_tmp); - } + struct record_track* rec; + pdbrec_t* pdb_rec; + route_head* trk_head; + char* track_name; + + if (strncmp(file_in->name, "cotoGPS TrackDB", PDB_DBNAMELEN) != 0) + // Use database name if not default + { + track_name = xstrndup(file_in->name, PDB_DBNAMELEN); + } else { + // Use filename for new track title + const char* fnametmp = strrchr(in_fname, '/'); + if (fnametmp == NULL) { + fnametmp = strrchr(in_fname, '\\'); + } + if (fnametmp) { + fnametmp++; + } else { + fnametmp = in_fname; + } + if (strrchr(fnametmp, '.') != NULL) { + track_name = xstrndup(fnametmp, strrchr(fnametmp,'.') - fnametmp); + } else { + track_name = xstrdup(fnametmp); + } + } + + trk_head = route_head_alloc(); + track_add_head(trk_head); + + trk_head->rte_name = track_name; + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint* wpt_tmp; + + wpt_tmp = waypt_new(); + + rec = (struct record_track*) pdb_rec->data; + + wpt_tmp->longitude = DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = DEG(pdb_read_double(&rec->latitude)); + + // It's not the course, so leave it out for now + // WAYPT_SET(wpt_tmp, course, pdb_read_double(&rec->arc)); + wpt_tmp->altitude = be_read16(&rec->alt); + + if (internals) { + // Parse the option as xcsv delimiter + const char* inter = xcsv_get_char_from_constant_table(internals); + char temp[256]; + snprintf(temp, sizeof(temp), "%.20f%s%.20f%s%.20f%s%.20f", pdb_read_double(&rec->distance), inter, + pdb_read_double(&rec->arc), inter, pdb_read_double(&rec->x), inter, pdb_read_double(&rec->y)); + wpt_tmp->notes = xstrdup(temp); + } + + wpt_tmp->pdop = be_read16(&rec->pdop)/10.0; + wpt_tmp->hdop = be_read16(&rec->hdop)/10.0; + wpt_tmp->vdop = be_read16(&rec->vdop)/10.0; + wpt_tmp->sat = rec->sat_tracked; + switch (rec->fix_quality) { + case cotofixNone: + wpt_tmp->fix = fix_none; + break; + case cotofixReserved: + wpt_tmp->fix = fix_unknown; + break; + case cotofix2D: + wpt_tmp->fix = fix_2d; + break; + case cotofix3D: + wpt_tmp->fix = fix_3d; + break; + case cotofixDGPS: + wpt_tmp->fix = fix_dgps; + break; + } + WAYPT_SET(wpt_tmp, speed, be_read16(&rec->speed)/10.0); + rec->time = be_read32(&rec->time); + if (rec->time != 0) { + rec->time -= 2082844800U; + wpt_tmp->creation_time = rec->time; + } + track_add_wpt(trk_head, wpt_tmp); + } } static void coto_wpt_read(void) { - struct record_wpt *rec; - pdbrec_t *pdb_rec; - appinfo_t *app; - app = (struct appinfo *) file_in->appinfo; - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - waypoint *wpt_tmp; - char *c; - - wpt_tmp = waypt_new(); - - rec = (struct record_wpt *) pdb_rec->data; - - wpt_tmp->longitude = DEG(-pdb_read_double(&rec->lon)); - wpt_tmp->latitude = DEG(pdb_read_double(&rec->lat)); - - wpt_tmp->shortname = xstrndup(rec->name, sizeof(rec->name)); - - wpt_tmp->icon_descr = coto_get_icon_descr(pdb_rec->category, app); - if (wpt_tmp->icon_descr) - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - - if ((c = strstr(rec->notes, "\nNotes:\n"))) { /* remove our contruct */ - wpt_tmp->notes = xstrdup(c + 8); - if (c != rec->notes) { - wpt_tmp->description = xstrndup(rec->notes, c - rec->notes); - } - } else { - wpt_tmp->notes = xstrdup(rec->notes); - } - - waypt_add(wpt_tmp); - } + struct record_wpt* rec; + pdbrec_t* pdb_rec; + appinfo_t* app; + app = (struct appinfo*) file_in->appinfo; + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint* wpt_tmp; + char* c; + + wpt_tmp = waypt_new(); + + rec = (struct record_wpt*) pdb_rec->data; + + wpt_tmp->longitude = DEG(-pdb_read_double(&rec->lon)); + wpt_tmp->latitude = DEG(pdb_read_double(&rec->lat)); + + wpt_tmp->shortname = xstrndup(rec->name, sizeof(rec->name)); + + wpt_tmp->icon_descr = coto_get_icon_descr(pdb_rec->category, app); + if (wpt_tmp->icon_descr) { + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + } + + if ((c = strstr(rec->notes, "\nNotes:\n"))) { /* remove our contruct */ + wpt_tmp->notes = xstrdup(c + 8); + if (c != rec->notes) { + wpt_tmp->description = xstrndup(rec->notes, c - rec->notes); + } + } else { + wpt_tmp->notes = xstrdup(rec->notes); + } + + waypt_add(wpt_tmp); + } } static void data_read(void) { - if ((file_in->creator != MYCREATOR) || ((file_in->type != MYTYPETRACK) && (file_in->type != MYTYPEWPT))) { - warning("Creator %x Type %x Version %d\n", (int) file_in->creator, (int) file_in->type, (int) file_in->version); - fatal(MYNAME ": Not a cotoGPS file.\n"); - } - - is_fatal((file_in->version > 0), - MYNAME ": This file is from an unsupported newer version of cotoGPS. It may be supported in a newer version of GPSBabel.\n"); - - switch(file_in->type) - { - case MYTYPETRACK: - coto_track_read(); - break; - case MYTYPEWPT: - coto_wpt_read(); - break; - } + if ((file_in->creator != MYCREATOR) || ((file_in->type != MYTYPETRACK) && (file_in->type != MYTYPEWPT))) { + warning("Creator %x Type %x Version %d\n", (int) file_in->creator, (int) file_in->type, (int) file_in->version); + fatal(MYNAME ": Not a cotoGPS file.\n"); + } + + is_fatal((file_in->version > 0), + MYNAME ": This file is from an unsupported newer version of cotoGPS. It may be supported in a newer version of GPSBabel.\n"); + + switch (file_in->type) { + case MYTYPETRACK: + coto_track_read(); + break; + case MYTYPEWPT: + coto_wpt_read(); + break; + } } static void coto_prepare_wpt_write(void) { - struct appinfo *ai; - - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->type = MYTYPEWPT; - file_out->creator = MYCREATOR; - file_out->version = 0; - - strncpy(file_out->name, "cotoGPS MarkerDB", PDB_DBNAMELEN); - - file_out->appinfo_len = APPINFO_SIZE; - file_out->appinfo = calloc(APPINFO_SIZE,1); - - ai = (struct appinfo *) file_out->appinfo; - be_write16(&ai->renamedCategories, 31); // Don't ask me why... - if (zerocat) - strncpy(ai->categories[0], zerocat, 16); - else - strncpy(ai->categories[0], "Not Assigned", 16); // FIXME: Replace by default English Palm 'Not Assigned' category - + struct appinfo* ai; + + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->type = MYTYPEWPT; + file_out->creator = MYCREATOR; + file_out->version = 0; + + strncpy(file_out->name, "cotoGPS MarkerDB", PDB_DBNAMELEN); + + file_out->appinfo_len = APPINFO_SIZE; + file_out->appinfo = calloc(APPINFO_SIZE,1); + + ai = (struct appinfo*) file_out->appinfo; + be_write16(&ai->renamedCategories, 31); // Don't ask me why... + if (zerocat) { + strncpy(ai->categories[0], zerocat, 16); + } else { + strncpy(ai->categories[0], "Not Assigned", 16); // FIXME: Replace by default English Palm 'Not Assigned' category + } + } static void -coto_wpt_write(const waypoint *wpt) +coto_wpt_write(const waypoint* wpt) { - struct record_wpt *rec; - struct appinfo *ai = (struct appinfo *) file_out->appinfo; - char *notes = NULL; - char *shortname = NULL; - int size; - gbuint8 cat = 0; - int i; - - mkshort_wr_handle = mkshort_new_handle(); - setshort_length(mkshort_wr_handle, MAX_MARKER_NAME_LENGTH); - setshort_whitespace_ok(mkshort_wr_handle, 1); - - if ((global_opts.synthesize_shortnames && wpt->description) || (wpt->shortname == NULL)) - shortname = mkshort_from_wpt(mkshort_wr_handle, wpt); - else - shortname = xstrdup(wpt->shortname); - - if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname)))) - { - if ((wpt->notes) && (strcmp(wpt->description, wpt->notes) != 0)) - { - notes = xcalloc(strlen(wpt->description) + strlen(wpt->notes) + 9, 1); - sprintf(notes, "%s\nNotes:\n%s", wpt->description, wpt->notes); - } else { - notes = xstrdup(wpt->description); - } - } - else if (wpt->notes != NULL) - { - notes = xstrdup(wpt->notes); - } - - size = sizeof(*rec); - if (notes != NULL) - size += strlen(notes); - rec = xcalloc(size, 1); - - pdb_write_double(&rec->lon, RAD(-wpt->longitude)); - pdb_write_double(&rec->lat, RAD(wpt->latitude)); - strncpy(rec->name, shortname, MAX_MARKER_NAME_LENGTH); - - if (notes) - { - strcpy(rec->notes, notes); - xfree(notes); - } - - if (wpt->icon_descr) - { - for(i = 1; i < 16; i++) - if (!strncmp(wpt->icon_descr, ai->categories[i], 16)) {cat=i; break;} - if (!cat) { - // We have a new one - if (ai->maxid<15) { - i = ++ai->maxid; - snprintf(ai->categories[i], 16, "%s", wpt->icon_descr); - cat = ai->ids[i] = i; - } else { - // We're full! - warning(MYNAME ": Categories full. Category '%s' written as %s.\n", wpt->icon_descr, zerocat?zerocat:"Not Assigned"); - } - } - } - - pdb_write_rec(file_out, 0, cat, ct++, (const gbuint8 *)rec, size); - - xfree(shortname); - xfree(rec); - - mkshort_del_handle(&mkshort_wr_handle); + struct record_wpt* rec; + struct appinfo* ai = (struct appinfo*) file_out->appinfo; + char* notes = NULL; + char* shortname = NULL; + int size; + gbuint8 cat = 0; + int i; + + mkshort_wr_handle = mkshort_new_handle(); + setshort_length(mkshort_wr_handle, MAX_MARKER_NAME_LENGTH); + setshort_whitespace_ok(mkshort_wr_handle, 1); + + if ((global_opts.synthesize_shortnames && wpt->description) || (wpt->shortname == NULL)) { + shortname = mkshort_from_wpt(mkshort_wr_handle, wpt); + } else { + shortname = xstrdup(wpt->shortname); + } + + if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname)))) { + if ((wpt->notes) && (strcmp(wpt->description, wpt->notes) != 0)) { + notes = (char*) xcalloc(strlen(wpt->description) + strlen(wpt->notes) + 9, 1); + sprintf(notes, "%s\nNotes:\n%s", wpt->description, wpt->notes); + } else { + notes = xstrdup(wpt->description); + } + } else if (wpt->notes != NULL) { + notes = xstrdup(wpt->notes); + } + + size = sizeof(*rec); + if (notes != NULL) { + size += strlen(notes); + } + rec = (struct record_wpt*) xcalloc(size, 1); + + pdb_write_double(&rec->lon, RAD(-wpt->longitude)); + pdb_write_double(&rec->lat, RAD(wpt->latitude)); + strncpy(rec->name, shortname, MAX_MARKER_NAME_LENGTH); + + if (notes) { + strcpy(rec->notes, notes); + xfree(notes); + } + + if (wpt->icon_descr) { + for (i = 1; i < 16; i++) + if (!strncmp(wpt->icon_descr, ai->categories[i], 16)) { + cat=i; + break; + } + if (!cat) { + // We have a new one + if (ai->maxid<15) { + i = ++ai->maxid; + snprintf(ai->categories[i], 16, "%s", wpt->icon_descr); + cat = ai->ids[i] = i; + } else { + // We're full! + warning(MYNAME ": Categories full. Category '%s' written as %s.\n", wpt->icon_descr, zerocat?zerocat:"Not Assigned"); + } + } + } + + pdb_write_rec(file_out, 0, cat, ct++, (const gbuint8*)rec, size); + + xfree(shortname); + xfree(rec); + + mkshort_del_handle(&mkshort_wr_handle); } static void data_write(void) { - coto_prepare_wpt_write(); - waypt_disp_all(coto_wpt_write); + coto_prepare_wpt_write(); + waypt_disp_all(coto_wpt_write); } ff_vecs_t coto_vecs = { - ff_type_file, - {ff_cap_read|ff_cap_write, ff_cap_read, ff_cap_none}, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - coto_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + {(ff_cap)(ff_cap_read|ff_cap_write), ff_cap_read, ff_cap_none}, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + coto_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/cst.c b/gpsbabel/cst.c index e58421b12..ffe89401a 100644 --- a/gpsbabel/cst.c +++ b/gpsbabel/cst.c @@ -30,7 +30,7 @@ #define MYNAME "cst" #undef CST_DEBUG - + #define CST_UNKNOWN 0 #define CST_HEADER 1 #define CST_ROUTE 2 @@ -38,114 +38,116 @@ #define CST_REFERENCE 4 #define CST_VERSION 5 -static gbfile *fin; +static gbfile* fin; -static route_head *temp_route; +static route_head* temp_route; /* placeholders for options */ static arglist_t cst_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /* helpers */ static void -cst_add_wpt(const route_head *track, waypoint *wpt) +cst_add_wpt(const route_head* track, waypoint* wpt) { - if ((wpt == NULL) || (track == NULL)) return; - - if (wpt->shortname != NULL) - { - waypt_add(waypt_dupe(wpt)); - if (wpt->url != NULL) - { - xfree(wpt->url); - wpt->url = NULL; - } - - if (temp_route == NULL) - { - temp_route = route_head_alloc(); - route_add_head(temp_route); - } - route_add_wpt(temp_route, waypt_dupe(wpt)); - } - track_add_wpt((route_head *)track, (waypoint *)wpt); + if ((wpt == NULL) || (track == NULL)) { + return; + } + + if (wpt->shortname != NULL) { + waypt_add(waypt_dupe(wpt)); + if (wpt->url != NULL) { + xfree(wpt->url); + wpt->url = NULL; + } + + if (temp_route == NULL) { + temp_route = route_head_alloc(); + route_add_head(temp_route); + } + route_add_wpt(temp_route, waypt_dupe(wpt)); + } + track_add_wpt((route_head*)track, (waypoint*)wpt); } -static char * -cst_make_url(char *str) +static char* +cst_make_url(char* str) { - int len = strlen(str); - char *res; - - if (len < 3) return NULL; - - if (strstr(str, "://") > str) - return xstrdup(str); - else if (strstr(str, ":\\") == str+1) /* DOS 0.01++ file format */ - { - res = xstrdup("file://*:"); - res[7] = *str++; - res[8] = *str++; - res = xstrappend(res, str); - { - char *c; - int i; - - c = res; /* replace all backslashes with a slash */ - while ((c = strchr(c, '\\'))) *c++ = '/'; - - c = res; /* enumerate number of spaces within filename */ - i = 0; - while ((c = strchr(c, ' '))) - { - c++; - i++; - } - - if (i > 0) /* .. and replace them with "%20" */ - { - char *src, *dest, *last; - - last = src = res; - res = dest = xcalloc(strlen(src) + (2*i) + 1, 1); - while ((c = strchr(src, ' '))) - { - if (c != src) strncpy(dest, src, c - src); - strcat(dest, "%20"); - c++; - src = c; - dest = res + strlen(res); - } - while (*src != '\0') - *dest++ = *src++; - xfree(last); - } - } - return res; - - } - else - return NULL; - + int len = strlen(str); + char* res; + + if (len < 3) { + return NULL; + } + + if (strstr(str, "://") > str) { + return xstrdup(str); + } else if (strstr(str, ":\\") == str+1) { /* DOS 0.01++ file format */ + res = xstrdup("file://*:"); + res[7] = *str++; + res[8] = *str++; + res = xstrappend(res, str); + { + char* c; + int i; + + c = res; /* replace all backslashes with a slash */ + while ((c = strchr(c, '\\'))) { + *c++ = '/'; + } + + c = res; /* enumerate number of spaces within filename */ + i = 0; + while ((c = strchr(c, ' '))) { + c++; + i++; + } + + if (i > 0) { /* .. and replace them with "%20" */ + char* src, *dest, *last; + + last = src = res; + res = dest = (char*) xcalloc(strlen(src) + (2*i) + 1, 1); + while ((c = strchr(src, ' '))) { + if (c != src) { + strncpy(dest, src, c - src); + } + strcat(dest, "%20"); + c++; + src = c; + dest = res + strlen(res); + } + while (*src != '\0') { + *dest++ = *src++; + } + xfree(last); + } + } + return res; + + } else { + return NULL; + } + } /* --------------------------------------------------------------------------- */ static void -cst_rd_init(const char *fname) +cst_rd_init(const char* fname) { - fin = gbfopen(fname, "rb", MYNAME); - temp_route = NULL; + fin = gbfopen(fname, "rb", MYNAME); + temp_route = NULL; } static void cst_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } /* --------------------------------------------------------------------------- */ @@ -153,191 +155,198 @@ cst_rd_deinit(void) static void cst_data_read(void) { - char *buff; - int line = 0; - int data_lines = -1; - int line_of_count = -1; - int valid = 0; - int section = CST_UNKNOWN; - int cst_version; - int cst_points = -1; - route_head *track = NULL; - waypoint *wpt = NULL; - - while ((buff = gbfgetstr(fin))) - { - char *cin = buff; - - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - cin = lrtrim(buff); - if (strlen(cin) == 0) continue; - - if (strncmp(cin, "; ", 2) == 0) continue; - if (*cin == '#') - { - section = CST_UNKNOWN; - if (strcmp(cin+1, "ROUTE") == 0) section = CST_ROUTE; - else if (strcmp(cin+1, "VERSION") == 0) section = CST_VERSION; - else if (strcmp(cin+1, "NOTES") == 0) section = CST_NOTES; - else if (strcmp(cin+1, "REFERENCE") == 0) section = CST_REFERENCE; - else if (strcmp(cin+1, "CARTE SUR TABLE DATA FILE") == 0) - { - section = CST_HEADER; - valid = 1; - } - else - warning(MYNAME ": Unknown section \"%s\".\n", cin+1); - - continue; - } - - if (valid == 0) continue; - - switch(section) - { - case CST_ROUTE: - if (*cin == ';') - { - int data = 0; - - if (*(cin+1) != '\xA4') continue; - - if (strncmp(cin + 2, "bitmap", 6) == 0) - { - cin = lrtrim(cin + 8); - if (*cin != '\0') - wpt->url = cst_make_url(cin); - } - - while ((buff = gbfgetstr(fin))) - { - line++; - cin = lrtrim(buff); - - if (strcmp(cin + 2, "note") == 0) - { - buff = gbfgetstr(fin); - if (buff == NULL) buff = ""; - line++; - cin = lrtrim(buff); - if (*cin != '\0') - wpt->notes = xstrdup(cin); - } - else if (strcmp(cin + 2, "end") == 0) - { - data = 1; - break; - } - } - if (data == 0) - fatal(MYNAME ": Unexpected end of file!\n"); - } - else - { - int interp, i; - char name[256]; - char *pow; - - if (data_lines < 0) - { - if ((2 != sscanf(cin, "%d %128s", &i, name)) || - (case_ignore_strcmp(name, "Points") != 0)) - fatal(MYNAME "-line %d: Number of points expected!\n", line); - line_of_count = line; - data_lines = 0; - cst_points = i; - continue; - } - - cst_add_wpt(track, wpt); - wpt = NULL; - - - wpt = waypt_new(); - - if (5 != sscanf(cin, "%lf %lf %lf %d %s", - &wpt->longitude, - &wpt->latitude, - &wpt->altitude, - &interp, name)) - { - fatal(MYNAME ": Could not interprete line %d!\n", line); - } - - data_lines++; - - if (strcmp(name, "1") == 0) - { - track = route_head_alloc(); - track_add_head(track); - } - else if (strncmp(name, "NAME:", 5) == 0) - wpt->shortname = xstrdup(((char *)&name) + 5); - - pow = strrchr(cin, '^'); - if (pow != NULL) - { - struct tm tm; - - pow = lrtrim(++pow); - strptime(pow, "%Y %m %d %H:%M:%S", &tm); - - wpt->creation_time = mkgmtime(&tm); - } - wpt->latitude /= 100000.0; - wpt->longitude /= 100000.0; - } - break; - - - case CST_VERSION: - cst_version = atoi(cin); - if (cst_version != 40) - warning(MYNAME ": Not tested with file version %d.\n", cst_version); - break; - - case CST_REFERENCE: - if ((strncmp(cin, "DATUM ", 6) == 0) && (strstr(cin, "WGS 84") == NULL)) - fatal(MYNAME ": Unsupported datum (%s)!\n", cin); - break; - - case CST_HEADER: - case CST_NOTES: - break; - } - } - cst_add_wpt(track, wpt); - wpt = NULL; - - if ((cst_points >= 0) && (data_lines != cst_points)) - warning(MYNAME ": Loaded %d point(s), but line %d says %d!\n", data_lines, line_of_count, cst_points); + char* buff; + int line = 0; + int data_lines = -1; + int line_of_count = -1; + int valid = 0; + int section = CST_UNKNOWN; + int cst_version; + int cst_points = -1; + route_head* track = NULL; + waypoint* wpt = NULL; + + while ((buff = gbfgetstr(fin))) { + char* cin = buff; + + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + cin = lrtrim(buff); + if (strlen(cin) == 0) { + continue; + } + + if (strncmp(cin, "; ", 2) == 0) { + continue; + } + if (*cin == '#') { + section = CST_UNKNOWN; + if (strcmp(cin+1, "ROUTE") == 0) { + section = CST_ROUTE; + } else if (strcmp(cin+1, "VERSION") == 0) { + section = CST_VERSION; + } else if (strcmp(cin+1, "NOTES") == 0) { + section = CST_NOTES; + } else if (strcmp(cin+1, "REFERENCE") == 0) { + section = CST_REFERENCE; + } else if (strcmp(cin+1, "CARTE SUR TABLE DATA FILE") == 0) { + section = CST_HEADER; + valid = 1; + } else { + warning(MYNAME ": Unknown section \"%s\".\n", cin+1); + } + + continue; + } + + if (valid == 0) { + continue; + } + + switch (section) { + case CST_ROUTE: + if (*cin == ';') { + int data = 0; + + if (*(cin+1) != '\xA4') { + continue; + } + + if (strncmp(cin + 2, "bitmap", 6) == 0) { + cin = lrtrim(cin + 8); + if (*cin != '\0') { + wpt->url = cst_make_url(cin); + } + } + + while ((buff = gbfgetstr(fin))) { + line++; + cin = lrtrim(buff); + + if (strcmp(cin + 2, "note") == 0) { + buff = gbfgetstr(fin); + if (buff == NULL) { + buff = ""; + } + line++; + cin = lrtrim(buff); + if (*cin != '\0') { + wpt->notes = xstrdup(cin); + } + } else if (strcmp(cin + 2, "end") == 0) { + data = 1; + break; + } + } + if (data == 0) { + fatal(MYNAME ": Unexpected end of file!\n"); + } + } else { + int interp, i; + char name[256]; + char* pow; + + if (data_lines < 0) { + if ((2 != sscanf(cin, "%d %128s", &i, name)) || + (case_ignore_strcmp(name, "Points") != 0)) { + fatal(MYNAME "-line %d: Number of points expected!\n", line); + } + line_of_count = line; + data_lines = 0; + cst_points = i; + continue; + } + + cst_add_wpt(track, wpt); + wpt = NULL; + + + wpt = waypt_new(); + + if (5 != sscanf(cin, "%lf %lf %lf %d %s", + &wpt->longitude, + &wpt->latitude, + &wpt->altitude, + &interp, name)) { + fatal(MYNAME ": Could not interprete line %d!\n", line); + } + + data_lines++; + + if (strcmp(name, "1") == 0) { + track = route_head_alloc(); + track_add_head(track); + } else if (strncmp(name, "NAME:", 5) == 0) { + wpt->shortname = xstrdup(((char*)&name) + 5); + } + + pow = strrchr(cin, '^'); + if (pow != NULL) { + struct tm tm; + + pow = lrtrim(++pow); + strptime(pow, "%Y %m %d %H:%M:%S", &tm); + + wpt->creation_time = mkgmtime(&tm); + } + wpt->latitude /= 100000.0; + wpt->longitude /= 100000.0; + } + break; + + + case CST_VERSION: + cst_version = atoi(cin); + if (cst_version != 40) { + warning(MYNAME ": Not tested with file version %d.\n", cst_version); + } + break; + + case CST_REFERENCE: + if ((strncmp(cin, "DATUM ", 6) == 0) && (strstr(cin, "WGS 84") == NULL)) { + fatal(MYNAME ": Unsupported datum (%s)!\n", cin); + } + break; + + case CST_HEADER: + case CST_NOTES: + break; + } + } + cst_add_wpt(track, wpt); + wpt = NULL; + + if ((cst_points >= 0) && (data_lines != cst_points)) { + warning(MYNAME ": Loaded %d point(s), but line %d says %d!\n", data_lines, line_of_count, cst_points); + } } #if 0 static void -cst_wr_init(const char *fname) +cst_wr_init(const char* fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } static void cst_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } -static void -cst_route_hdr(const route_head *rte) +static void +cst_route_hdr(const route_head* rte) { } -static void -cst_route_tlr(const route_head *rte) +static void +cst_route_tlr(const route_head* rte) { } static void -cst_write_wpt(const waypoint *wpt) +cst_write_wpt(const waypoint* wpt) { } @@ -348,15 +357,15 @@ cst_data_write(void) #endif ff_vecs_t cst_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_read, ff_cap_read }, - cst_rd_init, - NULL, /* cst_wr_init, */ - cst_rd_deinit, - NULL, /* cst_wr_deinit, */ - cst_data_read, - NULL, /* cst_data_write, */ - NULL, - cst_args, - CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_read }, + cst_rd_init, + NULL, /* cst_wr_init, */ + cst_rd_deinit, + NULL, /* cst_wr_deinit, */ + cst_data_read, + NULL, /* cst_data_write, */ + NULL, + cst_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/csv_util.c b/gpsbabel/csv_util.c index 626066b67..a7618034e 100644 --- a/gpsbabel/csv_util.c +++ b/gpsbabel/csv_util.c @@ -52,93 +52,93 @@ * that has GNU gperf on it. */ typedef enum { - XT_unused = 0, - XT_ALT_FEET, - XT_ALT_METERS, - XT_ANYNAME, - XT_CADENCE, - XT_CITY, - XT_CONSTANT, - XT_COUNTRY, - XT_DESCRIPTION, - XT_EXCEL_TIME, - XT_FACILITY, - XT_FILENAME, - XT_FORMAT, - XT_GEOCACHE_CONTAINER, - XT_GEOCACHE_DIFF, - XT_GEOCACHE_HINT, - XT_GEOCACHE_LAST_FOUND, - XT_GEOCACHE_PLACER, - XT_GEOCACHE_TERR, - XT_GEOCACHE_TYPE, - XT_GEOCACHE_ISAVAILABLE, - XT_GEOCACHE_ISARCHIVED, - XT_GMT_TIME, - XT_GPS_FIX, - XT_GPS_HDOP, - XT_GPS_PDOP, - XT_GPS_SAT, - XT_GPS_VDOP, - XT_HEART_RATE, - XT_HMSG_TIME, - XT_HMSL_TIME, - XT_ICON_DESCR, - XT_IGNORE, - XT_INDEX, - XT_ISO_TIME, - XT_ISO_TIME_MS, - XT_LATLON_HUMAN_READABLE, - XT_LAT_DECIMAL, - XT_LAT_DECIMALDIR, - XT_LAT_DIR, - XT_LAT_DIRDECIMAL, - XT_LAT_HUMAN_READABLE, - XT_LAT_INT32DEG, - XT_LAT_DDMMDIR, - XT_LAT_NMEA, - XT_LOCAL_TIME, - XT_LON_DECIMAL, - XT_LON_DECIMALDIR, - XT_LON_DIR, - XT_LON_DIRDECIMAL, - XT_LON_HUMAN_READABLE, - XT_LON_INT32DEG, - XT_LON_DDMMDIR, - XT_LON_NMEA, - XT_MAP_EN_BNG, - XT_NOTES, - XT_NET_TIME, - XT_PATH_COURSE, - XT_PATH_DISTANCE_KM, - XT_PATH_DISTANCE_MILES, - XT_PATH_SPEED, - XT_PATH_SPEED_KNOTS, - XT_PATH_SPEED_KPH, - XT_PATH_SPEED_MPH, - XT_PHONE_NR, - XT_POSTAL_CODE, - XT_ROUTE_NAME, - XT_SHORTNAME, - XT_STATE, - XT_STREET_ADDR, - XT_TIMET_TIME, - XT_TRACK_NAME, - XT_TRACK_NEW, - XT_URL, - XT_UTM, - XT_UTM_ZONE, - XT_UTM_ZONEC, - XT_UTM_ZONEF, - XT_UTM_EASTING, - XT_UTM_NORTHING, - XT_URL_LINK_TEXT, - XT_YYYYMMDD_TIME + XT_unused = 0, + XT_ALT_FEET, + XT_ALT_METERS, + XT_ANYNAME, + XT_CADENCE, + XT_CITY, + XT_CONSTANT, + XT_COUNTRY, + XT_DESCRIPTION, + XT_EXCEL_TIME, + XT_FACILITY, + XT_FILENAME, + XT_FORMAT, + XT_GEOCACHE_CONTAINER, + XT_GEOCACHE_DIFF, + XT_GEOCACHE_HINT, + XT_GEOCACHE_LAST_FOUND, + XT_GEOCACHE_PLACER, + XT_GEOCACHE_TERR, + XT_GEOCACHE_TYPE, + XT_GEOCACHE_ISAVAILABLE, + XT_GEOCACHE_ISARCHIVED, + XT_GMT_TIME, + XT_GPS_FIX, + XT_GPS_HDOP, + XT_GPS_PDOP, + XT_GPS_SAT, + XT_GPS_VDOP, + XT_HEART_RATE, + XT_HMSG_TIME, + XT_HMSL_TIME, + XT_ICON_DESCR, + XT_IGNORE, + XT_INDEX, + XT_ISO_TIME, + XT_ISO_TIME_MS, + XT_LATLON_HUMAN_READABLE, + XT_LAT_DECIMAL, + XT_LAT_DECIMALDIR, + XT_LAT_DIR, + XT_LAT_DIRDECIMAL, + XT_LAT_HUMAN_READABLE, + XT_LAT_INT32DEG, + XT_LAT_DDMMDIR, + XT_LAT_NMEA, + XT_LOCAL_TIME, + XT_LON_DECIMAL, + XT_LON_DECIMALDIR, + XT_LON_DIR, + XT_LON_DIRDECIMAL, + XT_LON_HUMAN_READABLE, + XT_LON_INT32DEG, + XT_LON_DDMMDIR, + XT_LON_NMEA, + XT_MAP_EN_BNG, + XT_NOTES, + XT_NET_TIME, + XT_PATH_COURSE, + XT_PATH_DISTANCE_KM, + XT_PATH_DISTANCE_MILES, + XT_PATH_SPEED, + XT_PATH_SPEED_KNOTS, + XT_PATH_SPEED_KPH, + XT_PATH_SPEED_MPH, + XT_PHONE_NR, + XT_POSTAL_CODE, + XT_ROUTE_NAME, + XT_SHORTNAME, + XT_STATE, + XT_STREET_ADDR, + XT_TIMET_TIME, + XT_TRACK_NAME, + XT_TRACK_NEW, + XT_URL, + XT_UTM, + XT_UTM_ZONE, + XT_UTM_ZONEC, + XT_UTM_ZONEF, + XT_UTM_EASTING, + XT_UTM_NORTHING, + XT_URL_LINK_TEXT, + XT_YYYYMMDD_TIME } xcsv_token; // Static definition of in_word_set to meet C99 rules as used by Clang. -static struct xt_mapping * -in_word_set (register const char *str, register unsigned int len); +static struct xt_mapping* +in_word_set(register const char* str, register unsigned int len); #include "xcsv_tokens.gperf" @@ -147,8 +147,8 @@ in_word_set (register const char *str, register unsigned int len); /****************************************************************************/ xcsv_file_t xcsv_file; -extern char *xcsv_urlbase; -extern char *prefer_shortnames; +extern char* xcsv_urlbase; +extern char* prefer_shortnames; #if CSVFMTS_ENABLED static double pathdist = 0; @@ -156,7 +156,7 @@ static double oldlon = 999; static double oldlat = 999; static int waypt_out_count; -static route_head *csv_track, *csv_route; +static route_head* csv_track, *csv_route; static double utm_northing, utm_easting, utm_zone = 0; static char utm_zonec; #endif // CSVFMTS_ENABLED @@ -168,42 +168,42 @@ static char utm_zonec; /* usage: p = csv_stringclean(stringtoclean, "&,\"") */ /* (strip out ampersands, commas, and quotes. */ /*********************************************************************/ -char * +char* #ifdef DEBUG_MEM -CSV_STRINGCLEAN(const char *string, const char *chararray, DEBUG_PARAMS) +CSV_STRINGCLEAN(const char* string, const char* chararray, DEBUG_PARAMS) #else -csv_stringclean(const char *string, const char *chararray) -#endif +csv_stringclean(const char* string, const char* chararray) +#endif { - char * p1; - char * p2; - const char * cp; - char * tmp = xxstrdup(string,file,line); + char* p1; + char* p2; + const char* cp; + char* tmp = xxstrdup(string,file,line); - if ((! string) || (! chararray)) { - return (tmp); - } + if ((! string) || (! chararray)) { + return (tmp); + } - /* p2 - end of the original string */ - p2 = tmp + strlen(tmp); - - cp = chararray; - - while (*cp) { - p1 = tmp; - while (*p1) { - if (*cp == *p1) { - /* we don't want this character! */ - memmove(p1, p1 + 1, (p2 - p1)); - p1[p2 - p1] = '\0'; - p2--; - } - else - p1++; - } - cp++; + /* p2 - end of the original string */ + p2 = tmp + strlen(tmp); + + cp = chararray; + + while (*cp) { + p1 = tmp; + while (*p1) { + if (*cp == *p1) { + /* we don't want this character! */ + memmove(p1, p1 + 1, (p2 - p1)); + p1[p2 - p1] = '\0'; + p2--; + } else { + p1++; + } } - return (tmp); + cp++; + } + return (tmp); } /***********************************************************************************/ @@ -211,64 +211,64 @@ csv_stringclean(const char *string, const char *chararray) /* returns a copy of the modified string */ /* usage: p = csv_stringtrim(string, "\"", 0) */ /***********************************************************************************/ -char * +char* #ifdef DEBUG_MEM -CSV_STRINGTRIM(const char *string, const char *enclosure, int strip_max, DEBUG_PARAMS) +CSV_STRINGTRIM(const char* string, const char* enclosure, int strip_max, DEBUG_PARAMS) #else -csv_stringtrim(const char *string, const char *enclosure, int strip_max) +csv_stringtrim(const char* string, const char* enclosure, int strip_max) #endif { - static const char *p1 = NULL; - char *p2 = NULL; - char * tmp = xxstrdup(string,file,line); - size_t elen; - int stripped = 0; - - if (!strlen(string)) { - return (tmp); - } + static const char* p1 = NULL; + char* p2 = NULL; + char* tmp = xxstrdup(string,file,line); + size_t elen; + int stripped = 0; - if (!enclosure) { - elen = 0; - } else { - elen = strlen(enclosure); - } - - p2 = tmp + strlen(tmp) - 1; - p1 = tmp; - - /* trim off trailing whitespace */ - while ((p2 > p1) && isspace(*p2)) { - p2--; - } - - /* advance p1 past any leading whitespace */ - while ((p1 < p2) && (isspace(*p1))) { - p1++; - } - - /* if no maximum strippage, assign a reasonable value to max */ - strip_max = strip_max ? strip_max : 9999; - - /* if we have enclosures, skip past them in pairs */ - if (elen) { - while ( - (stripped < strip_max) && - ((size_t) (p2 - p1 + 1) >= (elen * 2)) && - (strncmp(p1, enclosure, elen) == 0) && - (strncmp((p2 - elen + 1), enclosure, elen) == 0)) { - p2 -= elen; - p1 += elen; - stripped++; - } + if (!strlen(string)) { + return (tmp); + } + + if (!enclosure) { + elen = 0; + } else { + elen = strlen(enclosure); + } + + p2 = tmp + strlen(tmp) - 1; + p1 = tmp; + + /* trim off trailing whitespace */ + while ((p2 > p1) && isspace(*p2)) { + p2--; + } + + /* advance p1 past any leading whitespace */ + while ((p1 < p2) && (isspace(*p1))) { + p1++; + } + + /* if no maximum strippage, assign a reasonable value to max */ + strip_max = strip_max ? strip_max : 9999; + + /* if we have enclosures, skip past them in pairs */ + if (elen) { + while ( + (stripped < strip_max) && + ((size_t)(p2 - p1 + 1) >= (elen * 2)) && + (strncmp(p1, enclosure, elen) == 0) && + (strncmp((p2 - elen + 1), enclosure, elen) == 0)) { + p2 -= elen; + p1 += elen; + stripped++; } + } - /* copy what's left over back into tmp. */ - memmove(tmp, p1, (p2 - p1) + 1); + /* copy what's left over back into tmp. */ + memmove(tmp, p1, (p2 - p1) + 1); - tmp[(p2 - p1) + 1] = '\0'; + tmp[(p2 - p1) + 1] = '\0'; - return (tmp); + return (tmp); } /*****************************************************************************/ @@ -279,111 +279,114 @@ csv_stringtrim(const char *string, const char *enclosure, int strip_max) /* usage: p = csv_lineparse(string, ",", "\"", line) [initial call] */ /* p = csv_lineparse(NULL, ",", "\"", line) [subsequent calls] */ /*****************************************************************************/ -char * -csv_lineparse(const char *stringstart, const char *delimited_by, - const char *enclosed_in, const int line_no) +char* +csv_lineparse(const char* stringstart, const char* delimited_by, + const char* enclosed_in, const int line_no) { - const char *sp; - static const char *p = NULL; - static char *tmp = NULL; - size_t dlen = 0, elen = 0, efound = 0; - int enclosedepth = 0; - short int dfound; - short int hyper_whitespace_delimiter = 0; - - if (tmp) { - xfree(tmp); - tmp = NULL; - } - - if (strcmp(delimited_by, "\\w") == 0) - hyper_whitespace_delimiter = 1; - - /* - * This is tacky. Our "csv" format is actually "commaspace" format. - * Changing that causes unwanted churn, but it also makes "real" - * comma separated data (such as likely to be produced by Excel, etc.) - * unreadable. So we silently change it here on a read and let the - * whitespace eater consume the space. - */ - if (strcmp(delimited_by, ", ") == 0) { - delimited_by = ","; - } + const char* sp; + static const char* p = NULL; + static char* tmp = NULL; + size_t dlen = 0, elen = 0, efound = 0; + int enclosedepth = 0; + short int dfound; + short int hyper_whitespace_delimiter = 0; + + if (tmp) { + xfree(tmp); + tmp = NULL; + } + + if (strcmp(delimited_by, "\\w") == 0) { + hyper_whitespace_delimiter = 1; + } + + /* + * This is tacky. Our "csv" format is actually "commaspace" format. + * Changing that causes unwanted churn, but it also makes "real" + * comma separated data (such as likely to be produced by Excel, etc.) + * unreadable. So we silently change it here on a read and let the + * whitespace eater consume the space. + */ + if (strcmp(delimited_by, ", ") == 0) { + delimited_by = ","; + } + + if (!p) { + /* first pass thru */ + p = stringstart; if (!p) { - /* first pass thru */ - p = stringstart; - - if (!p) { - /* last pass out */ - return (NULL); - } + /* last pass out */ + return (NULL); } - - /* the beginning of the string we start with (this pass) */ - sp = p; - - /* length of delimiters and enclosures */ - if ((delimited_by) && (!hyper_whitespace_delimiter)) - dlen = strlen(delimited_by); - if (enclosed_in) - elen = strlen(enclosed_in); - dfound = 0; - - while ((*p) && (!dfound)) { - if ((elen) && (strncmp(p, enclosed_in, elen) == 0)) - { - efound = 1; - p+=elen; - if (enclosedepth) - enclosedepth--; - else - enclosedepth++; - continue; - } - - if (!enclosedepth) { - if ((dlen) && (strncmp(p, delimited_by, dlen) == 0)) { - dfound = 1; - } else if ((hyper_whitespace_delimiter) && (ISWHITESPACE(*p))) { - dfound = 1; - while (ISWHITESPACE(*p)) - p++; - } else { - p++; - } - } - else { - p++; - } - } - - /* allocate enough space for this data field */ - tmp = (char *) xcalloc((p - sp) + 1, sizeof(char)); - - strncpy(tmp, sp, (p - sp)); - tmp[p - sp] = '\0'; - - if (elen && efound) { - char *c = csv_stringtrim(tmp, enclosed_in, 0); - xfree(tmp); - tmp = c; + } + + /* the beginning of the string we start with (this pass) */ + sp = p; + + /* length of delimiters and enclosures */ + if ((delimited_by) && (!hyper_whitespace_delimiter)) { + dlen = strlen(delimited_by); + } + if (enclosed_in) { + elen = strlen(enclosed_in); + } + dfound = 0; + + while ((*p) && (!dfound)) { + if ((elen) && (strncmp(p, enclosed_in, elen) == 0)) { + efound = 1; + p+=elen; + if (enclosedepth) { + enclosedepth--; + } else { + enclosedepth++; + } + continue; } - if (dfound) { - /* skip over the delimited_by */ - p += dlen; + if (!enclosedepth) { + if ((dlen) && (strncmp(p, delimited_by, dlen) == 0)) { + dfound = 1; + } else if ((hyper_whitespace_delimiter) && (ISWHITESPACE(*p))) { + dfound = 1; + while (ISWHITESPACE(*p)) { + p++; + } + } else { + p++; + } } else { - /* end of the line */ - p = NULL; + p++; } - - if (enclosedepth != 0) { - warning(MYNAME - ": Warning- Unbalanced Field Enclosures (%s) on line %d\n", - enclosed_in, line_no); - } - return (tmp); + } + + /* allocate enough space for this data field */ + tmp = (char*) xcalloc((p - sp) + 1, sizeof(char)); + + strncpy(tmp, sp, (p - sp)); + tmp[p - sp] = '\0'; + + if (elen && efound) { + char* c = csv_stringtrim(tmp, enclosed_in, 0); + xfree(tmp); + tmp = c; + } + + if (dfound) { + /* skip over the delimited_by */ + p += dlen; + } else { + /* end of the line */ + p = NULL; + } + + if (enclosedepth != 0) { + warning(MYNAME + ": Warning- Unbalanced Field Enclosures (%s) on line %d\n", + enclosed_in, line_no); + } + return (tmp); } #if CSVFMTS_ENABLED @@ -392,17 +395,17 @@ csv_lineparse(const char *stringstart, const char *delimited_by, /* usage: i = dec_to_intdeg(31.1234); */ /*****************************************************************************/ static int -dec_to_intdeg(const double d) +dec_to_intdeg(const double d) { - int ideg = 0; - - if (d >= 0) { - ideg = (2147483647) - (d * 8388608); - } else { - ideg = (2147483647) - (fabs(d) * 8388608) + 1; - } + int ideg = 0; + + if (d >= 0) { + ideg = (2147483647) - (d * 8388608); + } else { + ideg = (2147483647) - (fabs(d) * 8388608) + 1; + } - return(ideg); + return(ideg); } /*****************************************************************************/ @@ -410,17 +413,17 @@ dec_to_intdeg(const double d) /* usage: lat = dec_to_intdeg(ilat); */ /*****************************************************************************/ static double -intdeg_to_dec(const int ideg) +intdeg_to_dec(const int ideg) { - double d; - - if (ideg >= 0) { - d = ((2147483647) - ideg) / (double)8388608; - } else { - d = ((-2147483647-1) + ideg) / (double)8388608; - } + double d; - return(d); + if (ideg >= 0) { + d = ((2147483647) - ideg) / (double)8388608; + } else { + d = ((-2147483647-1) + ideg) / (double)8388608; + } + + return(d); } /*****************************************************************************/ @@ -428,33 +431,33 @@ intdeg_to_dec(const int ideg) /* usage: lat = decdir_to_dec("W90.1234"); */ /* lat = decdir_to_dec("30.1234N"); */ /*****************************************************************************/ -static double -decdir_to_dec(const char * decdir) +static double +decdir_to_dec(const char* decdir) { - char *p; - const char *cp; - double rval; - int sign = 0; - - cp = &decdir[0]; - - if ((*cp == 'W') || (*cp == 'S')) - sign = -1; - else - if ((*cp == 'N') || (*cp == 'E')) - sign = 1; - - rval = sign ? strtod(&decdir[1], &p) : strtod(&decdir[0], &p); - - if (sign == 0) { - if ((*p == 'W') || (*p == 'S')) - sign = -1; - else - if ((*p == 'N') || (*p == 'E')) - sign = 1; + char* p; + const char* cp; + double rval; + int sign = 0; + + cp = &decdir[0]; + + if ((*cp == 'W') || (*cp == 'S')) { + sign = -1; + } else if ((*cp == 'N') || (*cp == 'E')) { + sign = 1; + } + + rval = sign ? strtod(&decdir[1], &p) : strtod(&decdir[0], &p); + + if (sign == 0) { + if ((*p == 'W') || (*p == 'S')) { + sign = -1; + } else if ((*p == 'N') || (*p == 'E')) { + sign = 1; } - - return(rval * sign); + } + + return(rval * sign); } /*****************************************************************************/ @@ -463,15 +466,14 @@ decdir_to_dec(const char * decdir) /* lat = ddmmdir_to_degrees("30.1234N"); */ /*****************************************************************************/ static double -ddmmdir_to_degrees(const char * ddmmdir) +ddmmdir_to_degrees(const char* ddmmdir) { - // if not N or E, prepend a '-' to ddmm2degrees input - // see XT_LAT_NMEA which handles ddmm directly - if (strchr(ddmmdir, 'W') || strchr(ddmmdir, 'S')) - { - return ddmm2degrees(- atof(ddmmdir)); - } - return ddmm2degrees(atof(ddmmdir)); + // if not N or E, prepend a '-' to ddmm2degrees input + // see XT_LAT_NMEA which handles ddmm directly + if (strchr(ddmmdir, 'W') || strchr(ddmmdir, 'S')) { + return ddmm2degrees(- atof(ddmmdir)); + } + return ddmm2degrees(atof(ddmmdir)); } #endif @@ -480,131 +482,172 @@ ddmmdir_to_degrees(const char * ddmmdir) * human_to_dec() - convert a "human-readable" lat and/or lon to decimal * usage: human_to_dec( "N 41° 09.12' W 085° 09.36'", &lat, &lon ); * human_to_dec( "41 9 5.652 N", &lat, &lon ); - * + * * which: 0-no preference 1-prefer lat 2-prefer lon *****************************************************************************/ void -human_to_dec( const char *instr, double *outlat, double *outlon, int which ) +human_to_dec(const char* instr, double* outlat, double* outlon, int which) { - double unk[3] = {999,999,999}; - double lat[3] = {999,999,999}; - double lon[3] = {999,999,999}; - int latsign = 0; - int lonsign = 0; - int unksign = 1; - - const char *cur; - double *numres = unk; - int numind = 0; - char *buff; - - if (strchr(instr, ',') != NULL) { - char *c; - buff = xstrdup(instr); - while ((c = strchr(buff, ','))) *c = '.'; + double unk[3] = {999,999,999}; + double lat[3] = {999,999,999}; + double lon[3] = {999,999,999}; + int latsign = 0; + int lonsign = 0; + int unksign = 1; + + const char* cur; + double* numres = unk; + int numind = 0; + char* buff; + + if (strchr(instr, ',') != NULL) { + char* c; + buff = xstrdup(instr); + while ((c = strchr(buff, ','))) { + *c = '.'; } - else { - buff = (char *)instr; + } else { + buff = (char*)instr; + } + + cur = buff; + + while (cur && *cur) { + switch (*cur) { + case 'n': + case 's': + case 'N': + case 'S': + if (unk[0] != 999) { + numind = 0; + numres = unk; + lat[0] = unk[0]; + lat[1] = unk[1]; + lat[2] = unk[2]; + unk[0] = unk[1] = unk[2] = 999; + } else { + numres = lat; + numind = 0; + lat[0] = lat[1] = lat[2] = 999; + } + + if (*cur == 'n' || *cur == 'N') { + latsign = 1; + } else { + latsign = -1; + } + cur++; + break; + case 'w': + case 'e': + case 'W': + case 'E': + if (unk[0] != 999) { + numind = 0; + numres = unk; + lon[0] = unk[0]; + lon[1] = unk[1]; + lon[2] = unk[2]; + unk[0] = unk[1] = unk[2] = 999; + } else { + numres = lon; + numind = 0; + lon[0] = lon[1] = lon[2] = 999; + } + + if (*cur == 'e' || *cur == 'E') { + lonsign = 1; + } else { + lonsign = -1; + } + cur++; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '0': + case '.': + case ',': + numres[numind] = atof(cur); + while (cur && *cur && strchr("1234567890.,",*cur)) { + cur++; + } + break; + case '-': + unksign = -1; + cur++; + break; + default: + if (numres[numind] != 999) { + numind++; + if (numind > 2) { + numres = unk; + numind = 0; + } + } + cur++; + break; + } + } + + if (lat[0] == 999 && lon[0] == 999) { + if (which == 1) { + lat[0] = unk[0]; + lat[1] = unk[1]; + lat[2] = unk[2]; + latsign = unksign; + } else if (which == 2) { + lon[0] = unk[0]; + lon[1] = unk[1]; + lon[2] = unk[2]; + lonsign = unksign; + } + } + + if (outlat) { + if (lat[0] != 999) { + *outlat = lat[0]; + } + if (lat[1] != 999) { + *outlat += lat[1]/60.0; + } + if (lat[2] != 999) { + *outlat += lat[2]/3600.0; + } + if (*outlat > 360) { + *outlat = ddmm2degrees(*outlat); /* NMEA style */ } - - cur = buff; - - while ( cur && *cur ) { - switch (*cur) { - case 'n': case 's': case 'N': case 'S': - if ( unk[0] != 999 ) { - numind = 0; - numres = unk; - lat[0] = unk[0]; - lat[1] = unk[1]; - lat[2] = unk[2]; - unk[0] = unk[1] = unk[2] = 999; - } - else { - numres = lat; - numind = 0; - lat[0] = lat[1] = lat[2] = 999; - } - - if ( *cur == 'n' || *cur == 'N' ) - latsign = 1; - else - latsign = -1; - cur++; - break; - case 'w': case 'e': case 'W': case 'E': - if ( unk[0] != 999 ) { - numind = 0; - numres = unk; - lon[0] = unk[0]; - lon[1] = unk[1]; - lon[2] = unk[2]; - unk[0] = unk[1] = unk[2] = 999; - } - else { - numres = lon; - numind = 0; - lon[0] = lon[1] = lon[2] = 999; - } - - if ( *cur == 'e' || *cur == 'E' ) - lonsign = 1; - else - lonsign = -1; - cur++; - break; - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '0': - case '.': case ',': - numres[numind] = atof(cur); - while (cur && *cur && strchr("1234567890.,",*cur)) cur++; - break; - case '-': - unksign = -1; - cur++; - break; - default: - if (numres[numind] != 999) { - numind++; - if ( numind > 2 ) { - numres = unk; - numind = 0; - } - } - cur++; - break; - } + if (latsign) { + *outlat *= latsign; } - - if ( lat[0] == 999 && lon[0] == 999 ) { - if ( which == 1 ) { - lat[0] = unk[0]; lat[1] = unk[1]; lat[2] = unk[2]; - latsign = unksign; - } - else if ( which == 2 ) { - lon[0] = unk[0]; lon[1] = unk[1]; lon[2] = unk[2]; - lonsign = unksign; - } + } + if (outlon) { + if (lon[0] != 999) { + *outlon = lon[0]; } - - if ( outlat ) { - if ( lat[0] != 999 ) *outlat = lat[0]; - if ( lat[1] != 999 ) *outlat += lat[1]/60.0; - if ( lat[2] != 999 ) *outlat += lat[2]/3600.0; - if ( *outlat > 360) *outlat = ddmm2degrees(*outlat); /* NMEA style */ - if ( latsign ) *outlat *= latsign; + if (lon[1] != 999) { + *outlon += lon[1]/60.0; } - if ( outlon ) { - if ( lon[0] != 999 ) *outlon = lon[0]; - if ( lon[1] != 999 ) *outlon += lon[1]/60.0; - if ( lon[2] != 999 ) *outlon += lon[2]/3600.0; - if ( *outlon > 360) *outlon = ddmm2degrees(*outlon); /* NMEA style */ - if ( lonsign ) *outlon *= lonsign; + if (lon[2] != 999) { + *outlon += lon[2]/3600.0; } - if (buff != instr) { - xfree(buff); + if (*outlon > 360) { + *outlon = ddmm2degrees(*outlon); /* NMEA style */ } + if (lonsign) { + *outlon *= lonsign; + } + } + if (buff != instr) { + xfree(buff); + } } #if CSVFMTS_ENABLED @@ -613,78 +656,81 @@ human_to_dec( const char *instr, double *outlat, double *outlon, int which ) */ void -dec_to_human( char *buff, const char *format, const char *dirs, double val ) +dec_to_human(char* buff, const char* format, const char* dirs, double val) { - char *subformat = NULL; - const char *formatptr = NULL; - char *percent = NULL; - char *type = NULL; - - int index = 0; - int intvals[3] = {0,0,0}; - double dblvals[3] = {0,0,0}; - int sign = 0; - - sign = (val < 0) ? 0 : 1; - - dblvals[0] = fabs(val); - intvals[0] = (int)dblvals[0]; - dblvals[1] = 60*(dblvals[0]-intvals[0]); - intvals[1] = (int)dblvals[1]; - dblvals[2] = 60*(dblvals[1]-intvals[1]); - intvals[2] = (int)dblvals[2]; - - subformat = (char*) xmalloc( strlen(format)+2); - formatptr = format; - - buff[0] = '\0'; - - while ( formatptr && *formatptr ) { - strcpy( subformat, formatptr ); - percent = strchr( subformat, '%' ); - if ( percent ) { - type = percent+1+strcspn( percent+1, "cdiouxXeEfgG%" ); - *(type+1) = '\0'; - switch( *type ) { - case 'c': - sprintf( buff+strlen(buff), subformat, dirs[sign] ); - break; - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - if (index>2) fatal(MYNAME ": too many format specifiers\n"); - sprintf( buff+strlen(buff), subformat, intvals[index]); - index++; - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - if (index>2) fatal(MYNAME ": too many format specifiers\n"); - sprintf( buff+strlen(buff), subformat, dblvals[index]); - index++; - break; - case '%': - sprintf( buff+strlen(buff), "%s", subformat ); - break; - default: - fatal(MYNAME ": invalid format specifier\n"); - break; - - } - } - else { - sprintf( buff+strlen(buff), "%s", subformat ); - } - formatptr += strlen(subformat); - } - - xfree(subformat); -} + char* subformat = NULL; + const char* formatptr = NULL; + char* percent = NULL; + char* type = NULL; + + int index = 0; + int intvals[3] = {0,0,0}; + double dblvals[3] = {0,0,0}; + int sign = 0; + + sign = (val < 0) ? 0 : 1; + + dblvals[0] = fabs(val); + intvals[0] = (int)dblvals[0]; + dblvals[1] = 60*(dblvals[0]-intvals[0]); + intvals[1] = (int)dblvals[1]; + dblvals[2] = 60*(dblvals[1]-intvals[1]); + intvals[2] = (int)dblvals[2]; + + subformat = (char*) xmalloc(strlen(format)+2); + formatptr = format; + + buff[0] = '\0'; + + while (formatptr && *formatptr) { + strcpy(subformat, formatptr); + percent = strchr(subformat, '%'); + if (percent) { + type = percent+1+strcspn(percent+1, "cdiouxXeEfgG%"); + *(type+1) = '\0'; + switch (*type) { + case 'c': + sprintf(buff+strlen(buff), subformat, dirs[sign]); + break; + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + if (index>2) { + fatal(MYNAME ": too many format specifiers\n"); + } + sprintf(buff+strlen(buff), subformat, intvals[index]); + index++; + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (index>2) { + fatal(MYNAME ": too many format specifiers\n"); + } + sprintf(buff+strlen(buff), subformat, dblvals[index]); + index++; + break; + case '%': + sprintf(buff+strlen(buff), "%s", subformat); + break; + default: + fatal(MYNAME ": invalid format specifier\n"); + break; + + } + } else { + sprintf(buff+strlen(buff), "%s", subformat); + } + formatptr += strlen(subformat); + } + + xfree(subformat); +} /*****************************************************************************/ /* xcsv_file_init() - prepare xcsv_file for first use. */ @@ -692,24 +738,24 @@ dec_to_human( char *buff, const char *format, const char *dirs, double val ) void xcsv_file_init(void) { - memset(&xcsv_file, '\0', sizeof(xcsv_file_t)); - - QUEUE_INIT(&xcsv_file.prologue); - QUEUE_INIT(&xcsv_file.epilogue); - - QUEUE_INIT(&xcsv_file.ifield); - /* ofield is alloced to allow pointing back at ifields - * where applicable. - */ - xcsv_file.ofield = (queue*) xcalloc(sizeof(queue), 1); - QUEUE_INIT(xcsv_file.ofield); - /* - * Provide a sane default for CSV _files_. - */ - xcsv_file.type = ff_type_file; - - xcsv_file.mkshort_handle = (struct short_handle *) mkshort_new_handle(); - xcsv_file.gps_datum = GPS_DATUM_WGS84; + memset(&xcsv_file, '\0', sizeof(xcsv_file_t)); + + QUEUE_INIT(&xcsv_file.prologue); + QUEUE_INIT(&xcsv_file.epilogue); + + QUEUE_INIT(&xcsv_file.ifield); + /* ofield is alloced to allow pointing back at ifields + * where applicable. + */ + xcsv_file.ofield = (queue*) xcalloc(sizeof(queue), 1); + QUEUE_INIT(xcsv_file.ofield); + /* + * Provide a sane default for CSV _files_. + */ + xcsv_file.type = ff_type_file; + + xcsv_file.mkshort_handle = mkshort_new_handle(); + xcsv_file.gps_datum = GPS_DATUM_WGS84; } /*****************************************************************************/ @@ -717,18 +763,18 @@ xcsv_file_init(void) /* usage: xcsv_ifield_add("DESCRIPTION", "", "%s") */ /*****************************************************************************/ void -xcsv_ifield_add(char *key, char *val, char *pfc) +xcsv_ifield_add(char* key, char* val, char* pfc) { - field_map_t *fmp = (field_map_t *) xcalloc(sizeof(*fmp), 1); - struct xt_mapping *xm = in_word_set(key, strlen(key)); - - fmp->key = key; - fmp->hashed_key = xm ? xm->xt_token : -1; - fmp->val = val; - fmp->printfc = pfc; - - ENQUEUE_TAIL(&xcsv_file.ifield, &fmp->Q); - xcsv_file.ifield_ct++; + field_map_t* fmp = (field_map_t*) xcalloc(sizeof(*fmp), 1); + struct xt_mapping* xm = in_word_set(key, strlen(key)); + + fmp->key = key; + fmp->hashed_key = xm ? xm->xt_token : -1; + fmp->val = val; + fmp->printfc = pfc; + + ENQUEUE_TAIL(&xcsv_file.ifield, &fmp->Q); + xcsv_file.ifield_ct++; } /*****************************************************************************/ @@ -736,19 +782,19 @@ xcsv_ifield_add(char *key, char *val, char *pfc) /* usage: xcsv_ofield_add("LAT_DECIMAL", "", "%08.5lf") */ /*****************************************************************************/ void -xcsv_ofield_add(char *key, char *val, char *pfc, int options) +xcsv_ofield_add(char* key, char* val, char* pfc, int options) { - field_map_t *fmp = (field_map_t *) xcalloc(sizeof(*fmp), 1); - struct xt_mapping *xm = in_word_set(key, strlen(key)); - - fmp->key = key; - fmp->hashed_key = xm ? xm->xt_token : -1; - fmp->val = val; - fmp->printfc = pfc; - fmp->options = options; - - ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q); - xcsv_file.ofield_ct++; + field_map_t* fmp = (field_map_t*) xcalloc(sizeof(*fmp), 1); + struct xt_mapping* xm = in_word_set(key, strlen(key)); + + fmp->key = key; + fmp->hashed_key = xm ? xm->xt_token : -1; + fmp->val = val; + fmp->printfc = pfc; + fmp->options = options; + + ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q); + xcsv_file.ofield_ct++; } /*****************************************************************************/ @@ -756,13 +802,13 @@ xcsv_ofield_add(char *key, char *val, char *pfc, int options) /* usage: xcsv_prologue_add("Four score and seven years ago today,") */ /*****************************************************************************/ void -xcsv_prologue_add(char *prologue) +xcsv_prologue_add(char* prologue) { - ogue_t* ogp = (ogue_t*) xcalloc(sizeof(*ogp), 1); + ogue_t* ogp = (ogue_t*) xcalloc(sizeof(*ogp), 1); - ogp->val = prologue; - ENQUEUE_TAIL(&xcsv_file.prologue, &ogp->Q); - xcsv_file.prologue_lines++; + ogp->val = prologue; + ENQUEUE_TAIL(&xcsv_file.prologue, &ogp->Q); + xcsv_file.prologue_lines++; } /*****************************************************************************/ @@ -770,34 +816,35 @@ xcsv_prologue_add(char *prologue) /* usage: xcsv_epilogue_add("shall not perish from the earth.") */ /*****************************************************************************/ void -xcsv_epilogue_add(char *epilogue) +xcsv_epilogue_add(char* epilogue) { - ogue_t * ogp = (ogue_t*) xcalloc(sizeof(*ogp), 1); + ogue_t* ogp = (ogue_t*) xcalloc(sizeof(*ogp), 1); - ogp->val = epilogue; - ENQUEUE_TAIL(&xcsv_file.epilogue, &ogp->Q); - xcsv_file.epilogue_lines++; + ogp->val = epilogue; + ENQUEUE_TAIL(&xcsv_file.epilogue, &ogp->Q); + xcsv_file.epilogue_lines++; } static time_t -yyyymmdd_to_time(const char *s) +yyyymmdd_to_time(const char* s) { - int t = atol(s); - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - tm.tm_mday = t % 100; - t = t / 100; - tm.tm_mon = t % 100 - 1; - t = t / 100; - tm.tm_year = t - 1900; - - if (mkgmtime(&tm) > 0) - return mktime(&tm); - else - return 0; + int t = atol(s); + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + tm.tm_mday = t % 100; + t = t / 100; + tm.tm_mon = t % 100 - 1; + t = t / 100; + tm.tm_year = t - 1900; + + if (mkgmtime(&tm) > 0) { + return mktime(&tm); + } else { + return 0; + } } @@ -807,133 +854,137 @@ yyyymmdd_to_time(const char *s) */ static time_t -sscanftime( const char *s, const char *format, const int gmt ) +sscanftime(const char* s, const char* format, const int gmt) { - struct tm stm; - memset(&stm, 0, sizeof(stm)); - - if ( strptime( s, format, &stm ) ) - { - if ((stm.tm_mday == 0) && (stm.tm_mon == 0) && (stm.tm_year == 0)) { - stm.tm_mday = 1; - stm.tm_mon = 0; - stm.tm_year = 70; - } - stm.tm_isdst = -1; - if (gmt) - return mkgmtime(&stm); - else - return mktime(&stm); - } - // Don't fuss for empty strings. - if (*s) { - warning("date parse of string '%s' with format '%s' failed.\n", - s, format); - } - return 0; + struct tm stm; + memset(&stm, 0, sizeof(stm)); + + if (strptime(s, format, &stm)) { + if ((stm.tm_mday == 0) && (stm.tm_mon == 0) && (stm.tm_year == 0)) { + stm.tm_mday = 1; + stm.tm_mon = 0; + stm.tm_year = 70; + } + stm.tm_isdst = -1; + if (gmt) { + return mkgmtime(&stm); + } else { + return mktime(&stm); + } + } + // Don't fuss for empty strings. + if (*s) { + warning("date parse of string '%s' with format '%s' failed.\n", + s, format); + } + return 0; } static time_t -addhms( const char *s, const char *format ) +addhms(const char* s, const char* format) { - time_t tt =0; - int hour =0; - int min =0; - int sec =0; - char * ampm = NULL; - int ac; - - ampm = (char*) xmalloc( strlen(s) ); - ac = sscanf(s, format, &hour, &min, &sec, &m); - /* If no time format in arg string, assume AM */ - if (ac < 4) { - ampm[0] = 0; - } - if (ac) { - tt = ((tolower(ampm[0])=='P')?43200:0)+3600*hour+60*min+sec; - } - xfree(ampm); - - return tt; + time_t tt =0; + int hour =0; + int min =0; + int sec =0; + char* ampm = NULL; + int ac; + + ampm = (char*) xmalloc(strlen(s)); + ac = sscanf(s, format, &hour, &min, &sec, &m); + /* If no time format in arg string, assume AM */ + if (ac < 4) { + ampm[0] = 0; + } + if (ac) { + tt = ((tolower(ampm[0])=='P')?43200:0)+3600*hour+60*min+sec; + } + xfree(ampm); + + return tt; } -static -int -writetime(char * buff, size_t bufsize, const char * format, time_t t, int gmt ) +static +int +writetime(char* buff, size_t bufsize, const char* format, time_t t, int gmt) { - static struct tm * stmp; + static struct tm* stmp; - if (gmt) - stmp = gmtime(&t); - else - stmp = localtime(&t); + if (gmt) { + stmp = gmtime(&t); + } else { + stmp = localtime(&t); + } - return strftime(buff, bufsize, format, stmp ); + return strftime(buff, bufsize, format, stmp); } #if 0 /* not used */ -static -int -writeisotime(char * buff, size_t bufsize, const char * format, time_t t) +static +int +writeisotime(char* buff, size_t bufsize, const char* format, time_t t) { - static struct tm * stmp; - char * ibuff = NULL; - int i; - - ibuff = xmalloc(bufsize); - stmp = gmtime(&t); - strftime(ibuff, bufsize, format, stmp ); - i = snprintf(buff, bufsize, format, ibuff ); - xfree(ibuff); - return i; + static struct tm* stmp; + char* ibuff = NULL; + int i; + + ibuff = xmalloc(bufsize); + stmp = gmtime(&t); + strftime(ibuff, bufsize, format, stmp); + i = snprintf(buff, bufsize, format, ibuff); + xfree(ibuff); + return i; } #endif -static -int -writehms(char * buff, size_t bufsize, const char * format, time_t t, int gmt ) +static +int +writehms(char* buff, size_t bufsize, const char* format, time_t t, int gmt) { - static struct tm no_time = {0}; - static struct tm * stmp = &no_time; - - if (gmt) - stmp = gmtime(&t); - else - stmp = localtime(&t); - - if (stmp == NULL) stmp = &no_time; - - return snprintf(buff, bufsize, format, - stmp->tm_hour, stmp->tm_min, stmp->tm_sec, - (stmp->tm_hour>=12?"PM":"AM") ); + static struct tm no_time = {0}; + static struct tm* stmp = &no_time; + + if (gmt) { + stmp = gmtime(&t); + } else { + stmp = localtime(&t); + } + + if (stmp == NULL) { + stmp = &no_time; + } + + return snprintf(buff, bufsize, format, + stmp->tm_hour, stmp->tm_min, stmp->tm_sec, + (stmp->tm_hour>=12?"PM":"AM")); } -static -long +static +long time_to_yyyymmdd(time_t t) { - long b; - struct tm *tm = gmtime(&t); + long b; + struct tm* tm = gmtime(&t); - b = (1900 + tm->tm_year) * 10000 + - (1 + tm->tm_mon) * 100 + - tm->tm_mday; + b = (1900 + tm->tm_year) * 10000 + + (1 + tm->tm_mon) * 100 + + tm->tm_mday; - return b; + return b; } -static garmin_fs_t * -gmsd_init(waypoint *wpt) +static garmin_fs_t* +gmsd_init(waypoint* wpt) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - return gmsd; + garmin_fs_t* gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data*) gmsd); + } + return gmsd; } /*****************************************************************************/ @@ -941,1082 +992,1104 @@ gmsd_init(waypoint *wpt) /* usage: xcsv_parse_val("-123.34", *waypt, *field_map) */ /*****************************************************************************/ static void -xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp, - route_head **trk) +xcsv_parse_val(const char* s, waypoint* wpt, const field_map_t* fmp, + route_head** trk) { - char *enclosure = ""; - geocache_data *gc_data = NULL; + char* enclosure = ""; + geocache_data* gc_data = NULL; + + if (!fmp->printfc) { + fatal(MYNAME ": xcsv style '%s' is missing format specifier", fmp->key); + } + + if (0 == strcmp(fmp->printfc, "\"%s\"")) { + enclosure = "\""; + } + switch (fmp->hashed_key) { + case XT_IGNORE: + /* IGNORE -- Categorically ignore this... */ + break; + case XT_CONSTANT: + /* CONSTANT -- Ignore on Input... */ + break; + case XT_ANYNAME: + /* ANYNAME -- Ignore -- this is output magic. */ + break; + case XT_INDEX: + /* IGNORE -- Calculated Sequence # For Ouput*/ + break; + case XT_SHORTNAME: + wpt->shortname = csv_stringtrim(s, enclosure, 0); + break; + case XT_DESCRIPTION: + wpt->description = csv_stringtrim(s, enclosure, 0); + break; + case XT_NOTES: + wpt->notes = csv_stringtrim(s, "", 0); + break; + case XT_URL: + wpt->url = csv_stringtrim(s, "", 0); + break; + case XT_URL_LINK_TEXT: + wpt->url_link_text = csv_stringtrim(s, "", 0); + break; + case XT_ICON_DESCR: + wpt->icon_descr = csv_stringtrim(s, "", 0); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; - if (!fmp->printfc) { - fatal(MYNAME ": xcsv style '%s' is missing format specifier", fmp->key); + /* LATITUDE CONVERSIONS**************************************************/ + case XT_LAT_DECIMAL: + /* latitude as a pure decimal value */ + wpt->latitude = atof(s); + break; + case XT_LAT_DECIMALDIR: + case XT_LAT_DIRDECIMAL: + /* latitude as a decimal with N/S in it. */ + wpt->latitude = decdir_to_dec(s); + break; + case XT_LAT_INT32DEG: + /* latitude as a 32 bit integer offset */ + wpt->latitude = intdeg_to_dec((int) atof(s)); + break; + case XT_LAT_HUMAN_READABLE: + human_to_dec(s, &wpt->latitude, &wpt->longitude, 1); + break; + case XT_LAT_DDMMDIR: + wpt->latitude = ddmmdir_to_degrees(s); + break; + case XT_LAT_NMEA: + wpt->latitude = ddmm2degrees(atof(s)); + break; + // XT_LAT_10E is handled outside the switch. + /* LONGITUDE CONVERSIONS ***********************************************/ + case XT_LON_DECIMAL: + /* longitude as a pure decimal value */ + wpt->longitude = atof(s); + break; + case XT_LON_DECIMALDIR: + case XT_LON_DIRDECIMAL: + /* longitude as a decimal with N/S in it. */ + wpt->longitude = decdir_to_dec(s); + break; + case XT_LON_INT32DEG: + /* longitude as a 32 bit integer offset */ + wpt->longitude = intdeg_to_dec((int) atof(s)); + break; + case XT_LON_HUMAN_READABLE: + human_to_dec(s, &wpt->latitude, &wpt->longitude, 2); + break; + case XT_LON_DDMMDIR: + wpt->longitude = ddmmdir_to_degrees(s); + break; + case XT_LON_NMEA: + wpt->longitude = ddmm2degrees(atof(s)); + break; + // case XT_LON_10E is handled outside the switch. + /* LAT AND LON CONVERSIONS ********************************************/ + case XT_LATLON_HUMAN_READABLE: + human_to_dec(s, &wpt->latitude, &wpt->longitude, 0); + break; + /* DIRECTIONS **********************************************************/ + case XT_LAT_DIR: + /* latitude N/S. Ignore on input for now */ + break; + case XT_LON_DIR: + /* longitude E/W. Ingore on input for now */ + break; + /* SPECIAL COORDINATES/GRID */ + case XT_MAP_EN_BNG: + parse_coordinates(s, DATUM_OSGB36, grid_bng, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + case XT_UTM_ZONE: + utm_zone = atoi(s); + break; + case XT_UTM_ZONEC: + utm_zonec = atoi(s); + break; + case XT_UTM_ZONEF: + utm_zone = atoi(s); + utm_zonec = s[strlen(s) - 1]; + break; + case XT_UTM_EASTING: + utm_easting = atof(s); + break; + case XT_UTM_NORTHING: + utm_northing = atof(s); + break; + case XT_UTM: { + char* ss; + int i = 0;; + + utm_zone = strtod(s, &ss); + utm_zonec = ss[i]; + ss++; + utm_easting = strtod(ss, &ss); + while (*ss && !isdigit(*ss)) { + ss++; + } + utm_northing = strtod(ss, NULL); + } + break; + /* ALTITUDE CONVERSIONS ************************************************/ + case XT_ALT_FEET: + /* altitude in feet as a decimal value */ + wpt->altitude = FEET_TO_METERS(atof(s)); + if (wpt->altitude < unknown_alt + 1) { + wpt->altitude = unknown_alt; + } + break; + case XT_ALT_METERS: + /* altitude in meters as a decimal value */ + wpt->altitude = atof(s); + if (wpt->altitude < unknown_alt + 1) { + wpt->altitude = unknown_alt; } + break; - if (0 == strcmp(fmp->printfc, "\"%s\"")) { - enclosure = "\""; + /* PATH CONVERSIONS ************************************************/ + case XT_PATH_SPEED: + WAYPT_SET(wpt, speed, atof(s)); + break; + case XT_PATH_SPEED_KPH: + WAYPT_SET(wpt, speed, KPH_TO_MPS(atof(s))); + break; + case XT_PATH_SPEED_MPH: + WAYPT_SET(wpt, speed, MPH_TO_MPS(atof(s))); + break; + case XT_PATH_SPEED_KNOTS: + WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(s))); + break; + case XT_PATH_COURSE: + WAYPT_SET(wpt, course, atof(s)); + break; + + /* TIME CONVERSIONS ***************************************************/ + case XT_EXCEL_TIME: + /* Time as Excel Time */ + wpt->creation_time = EXCEL_TO_TIMET(atof(s)); + break; + case XT_TIMET_TIME: + /* Time as time_t */ + wpt->creation_time = atol(s); + break; + case XT_YYYYMMDD_TIME: + wpt->creation_time = yyyymmdd_to_time(s); + break; + case XT_GMT_TIME: + wpt->creation_time += sscanftime(s, fmp->printfc, 1); + break; + case XT_LOCAL_TIME: + wpt->creation_time += sscanftime(s, fmp->printfc, 0); + break; + /* Useful when time and date are in separate fields + GMT / Local offset is handled by the two cases above */ + case XT_HMSG_TIME: + case XT_HMSL_TIME: + wpt->creation_time += addhms(s, fmp->printfc); + break; + case XT_ISO_TIME: + case XT_ISO_TIME_MS: + wpt->creation_time = xml_parse_time(s, &wpt->microseconds); + break; + case XT_NET_TIME: + dotnet_time_to_time_t(atof(s), &wpt->creation_time, &wpt->microseconds); + break; + case XT_GEOCACHE_LAST_FOUND: + waypt_alloc_gc_data(wpt)->last_found = yyyymmdd_to_time(s); + break; + + /* GEOCACHING STUFF ***************************************************/ + case XT_GEOCACHE_DIFF: + /* Geocache Difficulty as an int */ + waypt_alloc_gc_data(wpt)->diff = atof(s) * 10; + break; + case XT_GEOCACHE_TERR: + /* Geocache Terrain as an int */ + waypt_alloc_gc_data(wpt)->terr = atof(s) * 10; + break; + case XT_GEOCACHE_TYPE: + /* Geocache Type */ + waypt_alloc_gc_data(wpt)->type = gs_mktype(s); + break; + case XT_GEOCACHE_CONTAINER: + waypt_alloc_gc_data(wpt)->container = gs_mkcont(s); + break; + case XT_GEOCACHE_HINT: + waypt_alloc_gc_data(wpt)->hint = csv_stringtrim(s, "", 0); + break; + case XT_GEOCACHE_PLACER: + waypt_alloc_gc_data(wpt)->placer = csv_stringtrim(s, "", 0); + break; + case XT_GEOCACHE_ISAVAILABLE: + gc_data = waypt_alloc_gc_data(wpt); + if (case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0) { + gc_data->is_available = status_false; + } else if (case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0) { + gc_data->is_available = status_true; + } else { + gc_data->is_available = status_unknown; + } + break; + case XT_GEOCACHE_ISARCHIVED: + gc_data = waypt_alloc_gc_data(wpt); + if (case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0) { + gc_data->is_archived = status_false; + } else if (case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0) { + gc_data->is_archived = status_true; + } else { + gc_data->is_archived = status_unknown; + } + break; + + /* GPS STUFF *******************************************************/ + case XT_GPS_HDOP: + wpt->hdop = atof(s); + break; + case XT_GPS_VDOP: + wpt->vdop = atof(s); + break; + case XT_GPS_PDOP: + wpt->pdop = atof(s); + break; + case XT_GPS_SAT: + wpt->sat = atoi(s); + break; + case XT_GPS_FIX: + wpt->fix = (fix_type)(atoi(s)-(fix_type)1); + if (wpt->fix < fix_2d) { + if (!case_ignore_strcmp(s, "none")) { + wpt->fix = fix_none; + } else if (!case_ignore_strcmp(s, "dgps")) { + wpt->fix = fix_dgps; + } else if (!case_ignore_strcmp(s, "pps")) { + wpt->fix = fix_pps; + } else { + wpt->fix = fix_unknown; + } + } + break; + /* Tracks and routes *********************************************/ + case XT_ROUTE_NAME: + if (csv_route) { + csv_route->rte_name = csv_stringtrim(s, enclosure, 0); + } + break; + case XT_TRACK_NEW: + if (atoi(s) && csv_track && !QUEUE_EMPTY(&csv_track->Q)) { + *trk = route_head_alloc(); + csv_track = *trk; + + track_add_head(*trk); + } + break; + case XT_TRACK_NAME: + if (!csv_track) { + csv_track = route_head_alloc(); + } + csv_track->rte_name = csv_stringtrim(s, enclosure, 0); + break; + + /* OTHER STUFF ***************************************************/ + case XT_PATH_DISTANCE_MILES: + /* Ignored on input */ + break; + case XT_HEART_RATE: + wpt->heartrate = atoi(s); + break; + case XT_CADENCE: + wpt->cadence = atoi(s); + break; + case XT_PATH_DISTANCE_KM: + /* Ignored on input */ + break; + /* GMSD ****************************************************************/ + case XT_COUNTRY: { + garmin_fs_t* gmsd = gmsd_init(wpt); + GMSD_SET(country, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_STATE: { + garmin_fs_t* gmsd = gmsd_init(wpt); + GMSD_SET(state, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_CITY: { + garmin_fs_t* gmsd = gmsd_init(wpt); + GMSD_SET(city, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_STREET_ADDR: { + garmin_fs_t* gmsd = gmsd_init(wpt); + GMSD_SET(addr, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_POSTAL_CODE: { + garmin_fs_t* gmsd = gmsd_init(wpt); + GMSD_SET(postal_code, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_PHONE_NR: { + garmin_fs_t* gmsd = gmsd_init(wpt); + GMSD_SET(phone_nr, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_FACILITY: { + garmin_fs_t* gmsd = gmsd_init(wpt); + GMSD_SET(facility, csv_stringtrim(s, enclosure, 0)); + } + break; + case -1: + if (strncmp(fmp->key, "LON_10E", 7) == 0) { + wpt->longitude = atof(s) / pow((double)10, atof(fmp->key+7)); + } else if (strncmp(fmp->key, "LAT_10E", 7) == 0) { + wpt->latitude = atof(s) / pow((double)10, atof(fmp->key+7)); + } else { + warning(MYNAME ": Unknown style directive: %s\n", fmp->key); + } + break; + + default: + fatal("This can't happen\n"); + break; + } +} + +/*****************************************************************************/ +/* xcsv_data_read() - read input file, parsing lines, fields and handling */ +/* any data conversion (the input meat) */ +/*****************************************************************************/ +void +xcsv_data_read(void) +{ + char* buff; + char* s; + waypoint* wpt_tmp; + int linecount = 0; + queue* elem, *tmp; + field_map_t* fmp; + ogue_t* ogp; + route_head* rte = NULL; + route_head* trk = NULL; + utm_northing = 0; + utm_easting = 0; + utm_zone = 0; + utm_zonec = 'N'; + + csv_route = csv_track = NULL; + if (xcsv_file.datatype == trkdata) { + csv_track = trk; + } else if (xcsv_file.datatype == rtedata) { + csv_route = rte; + } + + while ((buff = gbfgetstr(xcsv_file.xcsvfp))) { + if ((linecount == 0) && xcsv_file.xcsvfp->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + linecount++; + /* Whack trailing space; leading space may matter if our field sep + * is whitespace and we have leading whitespace. + */ + rtrim(buff); + + /* skip over x many lines on the top for the prologue... */ + if ((xcsv_file.prologue_lines) && ((linecount - 1) < + xcsv_file.prologue_lines)) { + continue; + } + + /* We should skip over epilogue lines also. Since we don't want to + * pre-read the file to know how many data lines we should be seeing, + * we take this cheap shot at the data and cross our fingers. + */ + + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t*) elem; + if (strncmp(buff, ogp->val, strlen(ogp->val)) == 0) { + buff[0] = '\0'; + break; + } + } + + if (strlen(buff)) { + wpt_tmp = waypt_new(); + + s = buff; + s = csv_lineparse(s, xcsv_file.field_delimiter, "", linecount); + + if (QUEUE_EMPTY(&xcsv_file.ifield)) { + fatal(MYNAME ": attempt to read, but style '%s' has no IFIELDs in it.\n", xcsv_file.description? xcsv_file.description : "unknown"); + } + + /* reset the ifield queue */ + elem = QUEUE_FIRST(&xcsv_file.ifield); + + /* now rip the line apart, advancing the queue for each tear + * off the beginning of buff since there's no index into queue. + */ + while (s) { + fmp = (field_map_t*) elem; + xcsv_parse_val(s, wpt_tmp, fmp, &trk); + + elem = QUEUE_NEXT(elem); + + if (elem == &xcsv_file.ifield) { + /* we've wrapped the queue. so stop parsing! */ + while (s) { + s=csv_lineparse(NULL, "\xff","",linecount); + } + break; + } + + s = csv_lineparse(NULL, xcsv_file.field_delimiter, "", + linecount); + } + + if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt_tmp->latitude, wpt_tmp->longitude, 0.0, + &wpt_tmp->latitude, &wpt_tmp->longitude, &alt, xcsv_file.gps_datum); + } + + if (utm_easting || utm_northing) { + GPS_Math_UTM_EN_To_Known_Datum(&wpt_tmp->latitude, + &wpt_tmp->longitude, + utm_easting, utm_northing, + utm_zone, utm_zonec, + DATUM_WGS84); + } + + switch (xcsv_file.datatype) { + case unknown_gpsdata: + case wptdata: + waypt_add(wpt_tmp); + break; + case trkdata: + if (trk == NULL) { + trk = route_head_alloc(); + csv_track = trk; + track_add_head(trk); + } + track_add_wpt(trk, wpt_tmp); + break; + case rtedata: + if (rte == NULL) { + rte = route_head_alloc(); + csv_route = rte; + route_add_head(rte); + } + route_add_wpt(rte, wpt_tmp); + break; + default: + ; + } + } + + } +} + +static void +xcsv_resetpathlen(const route_head* head) +{ + pathdist = 0; + oldlat = 999; + oldlon = 999; + csv_route = csv_track = NULL; + switch (xcsv_file.datatype) { + case trkdata: + csv_track = (route_head*) head; + break; + case rtedata: + csv_route = (route_head*) head; + break; + default: + break; + } +} + +/*****************************************************************************/ +/* xcsv_waypt_pr() - write output file, handling output conversions */ +/* (the output meat) */ +/*****************************************************************************/ +static void +xcsv_waypt_pr(const waypoint* wpt) +{ + char buff[1024]; + char* shortname = NULL; + char* description = NULL; + char* anyname = NULL; + char* write_delimiter; + int i; + field_map_t* fmp; + queue* elem, *tmp; + double latitude, longitude; + int32 utmz; + double utme, utmn; + char utmzc; + + buff[0] = '\0'; + + if (oldlon < 900) { + pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon), + RAD(wpt->latitude),RAD(wpt->longitude))); + } + longitude = oldlon = wpt->longitude; + latitude = oldlat = wpt->latitude; + + if (xcsv_file.field_delimiter && strcmp(xcsv_file.field_delimiter, "\\w") == 0) { + write_delimiter = " "; + } else { + write_delimiter = xcsv_file.field_delimiter; + } + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) { + shortname = mkshort_from_wpt(xcsv_file.mkshort_handle, wpt); + } else { + shortname = csv_stringclean(wpt->description, xcsv_file.badchars); + } + } else { + /* no shortname available -- let shortname default on output */ + } + } else { + shortname = csv_stringclean(wpt->shortname, xcsv_file.badchars); + } + + if (! wpt->description) { + if (shortname) { + description = csv_stringclean(shortname, xcsv_file.badchars); + } else { + /* no description -- let description default on output */ + } + } else { + description = csv_stringclean(wpt->description, xcsv_file.badchars); + } + + if (prefer_shortnames) { + if (description) { + xfree(description); } - switch(fmp->hashed_key) { + description = shortname; + } else if (description) { + char* odesc = description; + description = xstrdup(odesc); + xfree(odesc); + } + if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { + double alt; + GPS_Math_WGS84_To_Known_Datum_M(latitude, longitude, 0.0, + &latitude, &longitude, &alt, xcsv_file.gps_datum); + } + + i = 0; + QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { + char* obuff; + double lat = latitude; + double lon = longitude; + /* + * A klunky concept. This should evaluate to true for any + * field if we think we don't have realistic value for it. + * This is used by the 'optional' attribute for suppressing + * fields on output. + */ + int field_is_unknown = 0; + + fmp = (field_map_t*) elem; + + if ((i != 0) && !(fmp->options & OPTIONS_NODELIM)) { + gbfprintf(xcsv_file.xcsvfp, write_delimiter); + } + + if (fmp->options & OPTIONS_ABSOLUTE) { + lat = fabs(lat); + lon = fabs(lon); + } + + i++; +#define writebuff(b, fmt, data) snprintf(b, sizeof(b), fmt, data) + switch (fmp->hashed_key) { case XT_IGNORE: - /* IGNORE -- Categorically ignore this... */ - break; - case XT_CONSTANT: - /* CONSTANT -- Ignore on Input... */ - break; - case XT_ANYNAME: - /* ANYNAME -- Ignore -- this is output magic. */ - break; + /* IGNORE -- Write the char printf conversion */ + writebuff(buff, fmp->printfc, ""); + break; case XT_INDEX: - /* IGNORE -- Calculated Sequence # For Ouput*/ - break; + writebuff(buff, fmp->printfc, waypt_out_count + atoi(fmp->val)); + break; + case XT_CONSTANT: { + const char* cp = xcsv_get_char_from_constant_table(fmp->val); + if (cp) { + writebuff(buff, fmp->printfc, cp); + } else { + writebuff(buff, fmp->printfc, fmp->val); + } + } + break; case XT_SHORTNAME: - wpt->shortname = csv_stringtrim(s, enclosure, 0); - break; + writebuff(buff, fmp->printfc, + (shortname && *shortname) ? shortname : fmp->val); + break; + case XT_ANYNAME: + if (wpt->shortname) { + anyname = xstrdup(wpt->shortname); + } else if (wpt->description) { + anyname = mkshort(xcsv_file.mkshort_handle, wpt->description); + } else if (wpt->notes) { + anyname = xstrdup(wpt->notes); + } else { + anyname = xstrdup(fmp->val); + } + + if ((anyname) && (global_opts.synthesize_shortnames)) { + anyname = xstrdup(shortname); + } + + writebuff(buff, fmp->printfc, anyname); + + xfree(anyname); + break; case XT_DESCRIPTION: - wpt->description = csv_stringtrim(s, enclosure, 0); - break; + writebuff(buff, fmp->printfc, + (description && *description) ? description : fmp->val); + break; case XT_NOTES: - wpt->notes = csv_stringtrim(s, "", 0); - break; - case XT_URL: - wpt->url = csv_stringtrim(s, "", 0); - break; + writebuff(buff, fmp->printfc, + (wpt->notes && *wpt->notes) ? wpt->notes : fmp->val); + break; + case XT_URL: { + int off = 0; + if (xcsv_urlbase) { + strcpy(buff, xcsv_urlbase); + off = strlen(xcsv_urlbase); + } + if (wpt->url) { + snprintf(buff + off, sizeof(buff) - off, fmp->printfc, wpt->url); + } else { + strcpy(buff, (fmp->val && *fmp->val) ? fmp->val : "\"\""); + } + } + break; case XT_URL_LINK_TEXT: - wpt->url_link_text = csv_stringtrim(s, "", 0); - break; + snprintf(buff, sizeof(buff), fmp->printfc, + (wpt->url_link_text && *wpt->url_link_text) ? wpt->url_link_text : fmp->val); + break; case XT_ICON_DESCR: - wpt->icon_descr = csv_stringtrim(s, "", 0); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - break; + writebuff(buff, fmp->printfc, + (wpt->icon_descr && *wpt->icon_descr) ? + wpt->icon_descr : fmp->val); + break; - /* LATITUDE CONVERSIONS**************************************************/ + /* LATITUDE CONVERSION***********************************************/ case XT_LAT_DECIMAL: - /* latitude as a pure decimal value */ - wpt->latitude = atof(s); - break; + /* latitude as a pure decimal value */ + writebuff(buff, fmp->printfc, lat); + break; case XT_LAT_DECIMALDIR: + /* latitude as a decimal value with N/S after it */ + snprintf(buff, sizeof(buff), fmp->printfc, fabs(lat), + LAT_DIR(lat)); + break; case XT_LAT_DIRDECIMAL: - /* latitude as a decimal with N/S in it. */ - wpt->latitude = decdir_to_dec(s); - break; + /* latitude as a decimal value with N/S before it */ + snprintf(buff, sizeof(buff), fmp->printfc, + LAT_DIR(lat), + fabs(lat)); + break; case XT_LAT_INT32DEG: - /* latitude as a 32 bit integer offset */ - wpt->latitude = intdeg_to_dec((int) atof(s)); - break; - case XT_LAT_HUMAN_READABLE: - human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 ); - break; + /* latitude as an integer offset from 0 degrees */ + writebuff(buff, fmp->printfc, + dec_to_intdeg(lat)); + break; case XT_LAT_DDMMDIR: - wpt->latitude = ddmmdir_to_degrees(s); + /*latitude as (degrees * 100) + decimal minutes, with N/S after it */ + dec_to_human(buff, fmp->printfc, "SN", degrees2ddmm(lat)); + break; + case XT_LAT_HUMAN_READABLE: + dec_to_human(buff, fmp->printfc, "SN", lat); break; case XT_LAT_NMEA: - wpt->latitude = ddmm2degrees(atof(s)); - break; - // XT_LAT_10E is handled outside the switch. - /* LONGITUDE CONVERSIONS ***********************************************/ + writebuff(buff, fmp->printfc, degrees2ddmm(lat)); + break; + // case XT_LAT_10E is handled outside the switch. + /* LONGITUDE CONVERSIONS*********************************************/ case XT_LON_DECIMAL: - /* longitude as a pure decimal value */ - wpt->longitude = atof(s); - break; + /* longitude as a pure decimal value */ + writebuff(buff, fmp->printfc, lon); + break; case XT_LON_DECIMALDIR: + /* latitude as a decimal value with N/S after it */ + snprintf(buff, sizeof(buff), fmp->printfc, + fabs(lon), + LON_DIR(lon)); + break; case XT_LON_DIRDECIMAL: - /* longitude as a decimal with N/S in it. */ - wpt->longitude = decdir_to_dec(s); - break; + /* latitude as a decimal value with N/S before it */ + snprintf(buff, sizeof(buff), fmp->printfc, + LON_DIR(lon), + fabs(lon)); + break; case XT_LON_INT32DEG: - /* longitude as a 32 bit integer offset */ - wpt->longitude = intdeg_to_dec((int) atof(s)); - break; - case XT_LON_HUMAN_READABLE: - human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 ); - break; + /* longitudee as an integer offset from 0 degrees */ + writebuff(buff, fmp->printfc, + dec_to_intdeg(lon)); + break; case XT_LON_DDMMDIR: - wpt->longitude = ddmmdir_to_degrees(s); + /* longidute as (degrees * 100) + decimal minutes, with W/E after it*/ + dec_to_human(buff, fmp->printfc, "WE", degrees2ddmm(lon)); + break; + case XT_LON_HUMAN_READABLE: + dec_to_human(buff, fmp->printfc, "WE", lon); break; - case XT_LON_NMEA: - wpt->longitude = ddmm2degrees(atof(s)); - break; - // case XT_LON_10E is handled outside the switch. - /* LAT AND LON CONVERSIONS ********************************************/ case XT_LATLON_HUMAN_READABLE: - human_to_dec( s, &wpt->latitude, &wpt->longitude, 0 ); - break; - /* DIRECTIONS **********************************************************/ + dec_to_human(buff, fmp->printfc, "SN", lat); + if (!isspace(buff[strlen(buff)])) { + strcat(buff, " "); + } + dec_to_human(buff+strlen(buff), fmp->printfc, "WE", + lon); + break; + case XT_LON_NMEA: + writebuff(buff, fmp->printfc, degrees2ddmm(lon)); + break; + // case XT_LON_10E is handled outside the switch. + /* DIRECTIONS *******************************************************/ case XT_LAT_DIR: - /* latitude N/S. Ignore on input for now */ - break; + /* latitude N/S as a char */ + writebuff(buff, fmp->printfc, + LAT_DIR(lat)); + break; case XT_LON_DIR: - /* longitude E/W. Ingore on input for now */ - break; - /* SPECIAL COORDINATES/GRID */ - case XT_MAP_EN_BNG: - parse_coordinates(s, DATUM_OSGB36, grid_bng, - &wpt->latitude, &wpt->longitude, MYNAME); - break; + /* longitude E/W as a char */ + writebuff(buff, fmp->printfc, + LON_DIR(lon)); + break; + + /* SPECIAL COORDINATES */ + case XT_MAP_EN_BNG: { + char map[3]; + double north, east; + if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map)) + fatal(MYNAME ": Position (%.5f/%.5f) outside of BNG.\n", + wpt->latitude, wpt->longitude); + snprintf(buff, sizeof(buff), fmp->printfc, map, (int)(east + 0.5), (int)(north + 0.5)); + } + break; + case XT_UTM: { + char tbuf[100]; + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + snprintf(tbuf, sizeof(tbuf), "%d%c %6.0f %7.0f", + utmz, utmzc, utme, utmn); + writebuff(buff, fmp->printfc, tbuf); + } + break; case XT_UTM_ZONE: - utm_zone = atoi(s); - break; + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + writebuff(buff, fmp->printfc, utmz); + break; case XT_UTM_ZONEC: - utm_zonec = atoi(s); - break; - case XT_UTM_ZONEF: - utm_zone = atoi(s); - utm_zonec = s[strlen(s) - 1]; - break; - case XT_UTM_EASTING: - utm_easting = atof(s); - break; + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + writebuff(buff, fmp->printfc, utmzc); + break; + case XT_UTM_ZONEF: { + char tbuf[10]; + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + tbuf[0] = 0; + snprintf(tbuf, sizeof(tbuf), "%d%c", utmz, utmzc); + writebuff(buff, fmp->printfc, tbuf); + } + break; case XT_UTM_NORTHING: - utm_northing = atof(s); - break; - case XT_UTM: { - char *ss; - int i = 0;; - - utm_zone = strtod(s, &ss); - utm_zonec = ss[i]; - ss++; - utm_easting = strtod(ss, &ss); - while(*ss && !isdigit(*ss)) ss++; - utm_northing = strtod(ss, NULL); - } - break; - /* ALTITUDE CONVERSIONS ************************************************/ + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + writebuff(buff, fmp->printfc, utmn); + break; + case XT_UTM_EASTING: + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + writebuff(buff, fmp->printfc, utme); + break; + + /* ALTITUDE CONVERSIONS**********************************************/ case XT_ALT_FEET: - /* altitude in feet as a decimal value */ - wpt->altitude = FEET_TO_METERS(atof(s)); - if (wpt->altitude < unknown_alt + 1) - wpt->altitude = unknown_alt; - break; + /* altitude in feet as a decimal value */ + writebuff(buff, fmp->printfc, + METERS_TO_FEET(wpt->altitude)); + break; case XT_ALT_METERS: - /* altitude in meters as a decimal value */ - wpt->altitude = atof(s); - if (wpt->altitude < unknown_alt + 1) - wpt->altitude = unknown_alt; - break; - - /* PATH CONVERSIONS ************************************************/ + /* altitude in meters as a decimal value */ + writebuff(buff, fmp->printfc, + wpt->altitude); + break; + + /* DISTANCE CONVERSIONS**********************************************/ + case XT_PATH_DISTANCE_MILES: + /* path (route/track) distance in miles */ + writebuff(buff, fmp->printfc, pathdist); + break; + case XT_PATH_DISTANCE_KM: + /* path (route/track) distance in */ + writebuff(buff, fmp->printfc, pathdist * 5280*12*2.54/100/1000); + break; case XT_PATH_SPEED: - WAYPT_SET(wpt, speed, atof(s)); - break; + writebuff(buff, fmp->printfc, wpt->speed); + break; case XT_PATH_SPEED_KPH: - WAYPT_SET(wpt, speed, KPH_TO_MPS(atof(s))); - break; + writebuff(buff, fmp->printfc, MPS_TO_KPH(wpt->speed)); + break; case XT_PATH_SPEED_MPH: - WAYPT_SET(wpt, speed, MPH_TO_MPS(atof(s))); - break; + writebuff(buff, fmp->printfc, MPS_TO_MPH(wpt->speed)); + break; case XT_PATH_SPEED_KNOTS: - WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(s))); - break; + writebuff(buff, fmp->printfc, MPS_TO_KNOTS(wpt->speed)); + break; case XT_PATH_COURSE: - WAYPT_SET(wpt, course, atof(s)); - break; + writebuff(buff, fmp->printfc, wpt->course); + break; - /* TIME CONVERSIONS ***************************************************/ + /* HEART RATE CONVERSION***********************************************/ + case XT_HEART_RATE: + writebuff(buff, fmp->printfc, wpt->heartrate); + break; + /* CADENCE CONVERSION***********************************************/ + case XT_CADENCE: + writebuff(buff, fmp->printfc, wpt->cadence); + break; + /* TIME CONVERSIONS**************************************************/ case XT_EXCEL_TIME: - /* Time as Excel Time */ - wpt->creation_time = EXCEL_TO_TIMET(atof(s)); - break; + /* creation time as an excel (double) time */ + writebuff(buff, fmp->printfc, TIMET_TO_EXCEL(wpt->creation_time)); + break; case XT_TIMET_TIME: - /* Time as time_t */ - wpt->creation_time = atol(s); - break; + /* time as a time_t variable */ + writebuff(buff, fmp->printfc, wpt->creation_time); + break; case XT_YYYYMMDD_TIME: - wpt->creation_time = yyyymmdd_to_time(s); - break; + writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->creation_time)); + break; case XT_GMT_TIME: - wpt->creation_time += sscanftime(s, fmp->printfc, 1); - break; + writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1); + break; case XT_LOCAL_TIME: - wpt->creation_time += sscanftime(s, fmp->printfc, 0); - break; - /* Useful when time and date are in separate fields - GMT / Local offset is handled by the two cases above */ + writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0); + break; case XT_HMSG_TIME: + writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1); + break; case XT_HMSL_TIME: - wpt->creation_time += addhms(s, fmp->printfc); - break; - case XT_ISO_TIME: - case XT_ISO_TIME_MS: - wpt->creation_time = xml_parse_time(s, &wpt->microseconds); - break; - case XT_NET_TIME: - dotnet_time_to_time_t(atof(s), &wpt->creation_time, &wpt->microseconds); - break; + writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0); + break; + case XT_ISO_TIME: + writetime(buff, sizeof buff, "%Y-%m-%dT%H:%M:%SZ", wpt->creation_time, 1); + break; + case XT_ISO_TIME_MS: + xml_fill_in_time(buff, wpt->creation_time, + wpt->microseconds, XML_LONG_TIME); + break; case XT_GEOCACHE_LAST_FOUND: - waypt_alloc_gc_data(wpt)->last_found = yyyymmdd_to_time(s); - break; + writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->gc_data->last_found)); + break; - /* GEOCACHING STUFF ***************************************************/ + /* GEOCACHE STUFF **************************************************/ case XT_GEOCACHE_DIFF: - /* Geocache Difficulty as an int */ - waypt_alloc_gc_data(wpt)->diff = atof(s) * 10; - break; + /* Geocache Difficulty as a double */ + writebuff(buff, fmp->printfc, wpt->gc_data->diff / 10.0); + field_is_unknown = !wpt->gc_data->diff; + break; case XT_GEOCACHE_TERR: - /* Geocache Terrain as an int */ - waypt_alloc_gc_data(wpt)->terr = atof(s) * 10; - break; - case XT_GEOCACHE_TYPE: - /* Geocache Type */ - waypt_alloc_gc_data(wpt)->type = gs_mktype(s); - break; + /* Geocache Terrain as a double */ + writebuff(buff, fmp->printfc, wpt->gc_data->terr / 10.0); + field_is_unknown = !wpt->gc_data->terr; + break; case XT_GEOCACHE_CONTAINER: - waypt_alloc_gc_data(wpt)->container = gs_mkcont(s); - break; + /* Geocache Container */ + writebuff(buff, fmp->printfc, gs_get_container(wpt->gc_data->container)); + field_is_unknown = wpt->gc_data->container == gc_unknown; + break; + case XT_GEOCACHE_TYPE: + /* Geocache Type */ + writebuff(buff, fmp->printfc, gs_get_cachetype(wpt->gc_data->type)); + field_is_unknown = wpt->gc_data->type == gt_unknown; + break; case XT_GEOCACHE_HINT: - waypt_alloc_gc_data(wpt)->hint = csv_stringtrim(s, "", 0); - break; + writebuff(buff, fmp->printfc, NONULL(wpt->gc_data->hint)); + field_is_unknown = !wpt->gc_data->hint; + break; case XT_GEOCACHE_PLACER: - waypt_alloc_gc_data(wpt)->placer = csv_stringtrim(s, "", 0); - break; + writebuff(buff, fmp->printfc, NONULL(wpt->gc_data->placer)); + field_is_unknown = !wpt->gc_data->placer; + break; case XT_GEOCACHE_ISAVAILABLE: - gc_data = waypt_alloc_gc_data(wpt); - if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0 ) - gc_data->is_available = status_false; - else if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0 ) - gc_data->is_available = status_true; - else - gc_data->is_available = status_unknown; - break; + if (wpt->gc_data->is_available == status_false) { + writebuff(buff, fmp->printfc, "False"); + } else if (wpt->gc_data->is_available == status_true) { + writebuff(buff, fmp->printfc, "True"); + } else { + writebuff(buff, fmp->printfc, "Unknown"); + } + break; case XT_GEOCACHE_ISARCHIVED: - gc_data = waypt_alloc_gc_data(wpt); - if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0 ) - gc_data->is_archived = status_false; - else if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0 ) - gc_data->is_archived = status_true; - else - gc_data->is_archived = status_unknown; - break; - - /* GPS STUFF *******************************************************/ + if (wpt->gc_data->is_archived == status_false) { + writebuff(buff, fmp->printfc, "False"); + } else if (wpt->gc_data->is_archived == status_true) { + writebuff(buff, fmp->printfc, "True"); + } else { + writebuff(buff, fmp->printfc, "Unknown"); + } + break; + /* Tracks and Routes ***********************************************/ + case XT_TRACK_NAME: + if (csv_track) { + writebuff(buff, fmp->printfc, NONULL(csv_track->rte_name)); + } + break; + case XT_ROUTE_NAME: + if (csv_route) { + writebuff(buff, fmp->printfc, NONULL(csv_route->rte_name)); + } + break; + + /* GPS STUFF *******************************************************/ case XT_GPS_HDOP: - wpt->hdop = atof(s); - break; + writebuff(buff, fmp->printfc, wpt->hdop); + field_is_unknown = !wpt->hdop; + break; case XT_GPS_VDOP: - wpt->vdop = atof(s); - break; + writebuff(buff, fmp->printfc, wpt->vdop); + field_is_unknown = !wpt->vdop; + break; case XT_GPS_PDOP: - wpt->pdop = atof(s); - break; + writebuff(buff, fmp->printfc, wpt->pdop); + field_is_unknown = !wpt->pdop; + break; case XT_GPS_SAT: - wpt->sat = atoi(s); - break; - case XT_GPS_FIX: - wpt->fix = (fix_type)(atoi(s)-(fix_type)1); - if ( wpt->fix < fix_2d) { - if (!case_ignore_strcmp(s, "none")) - wpt->fix = fix_none; - else if (!case_ignore_strcmp(s, "dgps")) - wpt->fix = fix_dgps; - else if (!case_ignore_strcmp(s, "pps")) - wpt->fix = fix_pps; - else - wpt->fix = fix_unknown; - } - break; - /* Tracks and routes *********************************************/ - case XT_ROUTE_NAME: - if (csv_route) csv_route->rte_name = csv_stringtrim(s, enclosure, 0); - break; - case XT_TRACK_NEW: - if (atoi(s) && csv_track && !QUEUE_EMPTY(&csv_track->Q)) { - *trk = route_head_alloc(); - csv_track = *trk; - - track_add_head(*trk); - } - break; - case XT_TRACK_NAME: - if (!csv_track) { - csv_track = route_head_alloc(); - } - csv_track->rte_name = csv_stringtrim(s, enclosure, 0); - break; - - /* OTHER STUFF ***************************************************/ - case XT_PATH_DISTANCE_MILES: - /* Ignored on input */ - break; - case XT_HEART_RATE: - wpt->heartrate = atoi(s); - break; - case XT_CADENCE: - wpt->cadence = atoi(s); - break; - case XT_PATH_DISTANCE_KM: - /* Ignored on input */ - break; - /* GMSD ****************************************************************/ + writebuff(buff, fmp->printfc, wpt->sat); + field_is_unknown = !wpt->sat; + break; + case XT_GPS_FIX: { + char* fix = NULL; + switch (wpt->fix) { + case fix_unknown: + field_is_unknown = 1; + fix = "Unknown"; + break; + case fix_none: + fix = "None"; + break; + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + } + writebuff(buff, fmp->printfc, fix); + } + break; + /* GMSD ************************************************************/ case XT_COUNTRY: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(country, csv_stringtrim(s, enclosure, 0)); - } - break; + garmin_fs_t* gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(country, "")); + } + break; case XT_STATE: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(state, csv_stringtrim(s, enclosure, 0)); - } - break; + garmin_fs_t* gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(state, "")); + } + break; case XT_CITY: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(city, csv_stringtrim(s, enclosure, 0)); - } - break; - case XT_STREET_ADDR: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(addr, csv_stringtrim(s, enclosure, 0)); - } - break; + garmin_fs_t* gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(city, "")); + } + break; case XT_POSTAL_CODE: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(postal_code, csv_stringtrim(s, enclosure, 0)); - } - break; + garmin_fs_t* gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(postal_code, "")); + } + break; + case XT_STREET_ADDR: { + garmin_fs_t* gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(addr, "")); + } + break; case XT_PHONE_NR: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(phone_nr, csv_stringtrim(s, enclosure, 0)); - } - break; - case XT_FACILITY: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(facility, csv_stringtrim(s, enclosure, 0)); - } - break; - case -1: - if (strncmp(fmp->key, "LON_10E", 7) == 0) { - wpt->longitude = atof(s) / pow((double)10, atof(fmp->key+7)); - } else - if (strncmp(fmp->key, "LAT_10E", 7) == 0) { - wpt->latitude = atof(s) / pow((double)10, atof(fmp->key+7)); - } else { - warning( MYNAME ": Unknown style directive: %s\n", fmp->key); - } - break; - - default: - fatal("This can't happen\n"); - break; + garmin_fs_t* gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(phone_nr, "")); } -} - -/*****************************************************************************/ -/* xcsv_data_read() - read input file, parsing lines, fields and handling */ -/* any data conversion (the input meat) */ -/*****************************************************************************/ -void -xcsv_data_read(void) -{ - char *buff; - char *s; - waypoint *wpt_tmp; - int linecount = 0; - queue *elem, *tmp; - field_map_t *fmp; - ogue_t *ogp; - route_head *rte = NULL; - route_head *trk = NULL; - utm_northing = 0; - utm_easting = 0; - utm_zone = 0; - utm_zonec = 'N'; - - csv_route = csv_track = NULL; - if (xcsv_file.datatype == trkdata) { - csv_track = trk; - } else - if (xcsv_file.datatype == rtedata) { - csv_route = rte; + break; + case XT_FACILITY: { + garmin_fs_t* gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(facility, "")); } - - while ((buff = gbfgetstr(xcsv_file.xcsvfp))) { - if ((linecount == 0) && xcsv_file.xcsvfp->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - linecount++; - /* Whack trailing space; leading space may matter if our field sep - * is whitespace and we have leading whitespace. - */ - rtrim(buff); - - /* skip over x many lines on the top for the prologue... */ - if ((xcsv_file.prologue_lines) && ((linecount - 1) < - xcsv_file.prologue_lines)) { - continue; - } - - /* We should skip over epilogue lines also. Since we don't want to - * pre-read the file to know how many data lines we should be seeing, - * we take this cheap shot at the data and cross our fingers. - */ - - QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { - ogp = (ogue_t *) elem; - if (strncmp(buff, ogp->val, strlen(ogp->val)) == 0) { - buff[0] = '\0'; - break; - } - } - - if (strlen(buff)) { - wpt_tmp = waypt_new(); - - s = buff; - s = csv_lineparse(s, xcsv_file.field_delimiter, "", linecount); - - if (QUEUE_EMPTY(&xcsv_file.ifield)) { - fatal(MYNAME ": attempt to read, but style '%s' has no IFIELDs in it.\n", xcsv_file.description? xcsv_file.description : "unknown"); - } - - /* reset the ifield queue */ - elem = QUEUE_FIRST(&xcsv_file.ifield); - - /* now rip the line apart, advancing the queue for each tear - * off the beginning of buff since there's no index into queue. - */ - while (s) { - fmp = (field_map_t *) elem; - xcsv_parse_val(s, wpt_tmp, fmp, &trk); - - elem = QUEUE_NEXT(elem); - - if (elem == &xcsv_file.ifield) { - /* we've wrapped the queue. so stop parsing! */ - while (s) { - s=csv_lineparse(NULL, "\xff","",linecount); - } - break; - } - - s = csv_lineparse(NULL, xcsv_file.field_delimiter, "", - linecount); - } - - if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { - double alt; - GPS_Math_Known_Datum_To_WGS84_M(wpt_tmp->latitude, wpt_tmp->longitude, 0.0, - &wpt_tmp->latitude, &wpt_tmp->longitude, &alt, xcsv_file.gps_datum); - } - - if (utm_easting || utm_northing) { - GPS_Math_UTM_EN_To_Known_Datum(&wpt_tmp->latitude, - &wpt_tmp->longitude, - utm_easting, utm_northing, - utm_zone, utm_zonec, - DATUM_WGS84); - } - - switch(xcsv_file.datatype) { - case 0: - case wptdata: - waypt_add(wpt_tmp); - break; - case trkdata: - if (trk == NULL) { - trk = route_head_alloc(); - csv_track = trk; - track_add_head(trk); - } - track_add_wpt(trk, wpt_tmp); - break; - case rtedata: - if (rte == NULL) { - rte = route_head_alloc(); - csv_route = rte; - route_add_head(rte); - } - route_add_wpt(rte, wpt_tmp); - break; - default: ; - } - } - + break; + /* specials */ + case XT_FILENAME: + writebuff(buff, fmp->printfc, wpt->session->filename); + break; + case XT_FORMAT: + writebuff(buff, fmp->printfc, wpt->session->name); + break; + case -1: + if (strncmp(fmp->key, "LON_10E", 7) == 0) { + writebuff(buff, fmp->printfc, lon * pow((double)10, atof(fmp->key+7))); + } else if (strncmp(fmp->key, "LAT_10E", 7) == 0) { + writebuff(buff, fmp->printfc, lat * pow((double)10, atof(fmp->key+7))); + } + break; + default: + warning(MYNAME ": Unknown style directive: %s\n", fmp->key); + break; } -} + obuff = csv_stringclean(buff, xcsv_file.badchars); -static void -xcsv_resetpathlen(const route_head *head) -{ - pathdist = 0; - oldlat = 999; - oldlon = 999; - csv_route = csv_track = NULL; - switch (xcsv_file.datatype) { - case trkdata: - csv_track = (route_head *) head; - break; - case rtedata: - csv_route = (route_head *) head; - break; - default: - break; + if (field_is_unknown && fmp->options & OPTIONS_OPTIONAL) { + goto next; } -} -/*****************************************************************************/ -/* xcsv_waypt_pr() - write output file, handling output conversions */ -/* (the output meat) */ -/*****************************************************************************/ -static void -xcsv_waypt_pr(const waypoint *wpt) -{ - char buff[1024]; - char *shortname = NULL; - char *description = NULL; - char * anyname = NULL; - char * write_delimiter; - int i; - field_map_t *fmp; - queue *elem, *tmp; - double latitude, longitude; - int32 utmz; - double utme, utmn; - char utmzc; - - buff[0] = '\0'; - - if ( oldlon < 900 ) { - pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon), - RAD(wpt->latitude),RAD(wpt->longitude))); - } - longitude = oldlon = wpt->longitude; - latitude = oldlat = wpt->latitude; - - if (xcsv_file.field_delimiter && strcmp(xcsv_file.field_delimiter, "\\w") == 0) - write_delimiter = " "; - else - write_delimiter = xcsv_file.field_delimiter; - - if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { - if (wpt->description) { - if (global_opts.synthesize_shortnames) - shortname = mkshort_from_wpt(xcsv_file.mkshort_handle, wpt); - else - shortname = csv_stringclean(wpt->description, xcsv_file.badchars); - } else { - /* no shortname available -- let shortname default on output */ - } - } else{ - shortname = csv_stringclean(wpt->shortname, xcsv_file.badchars); - } - if (! wpt->description) { - if (shortname) { - description = csv_stringclean(shortname, xcsv_file.badchars); - } else { - /* no description -- let description default on output */ - } + /* As a special case (pronounced "horrible hack") we allow + * ""%s"" to smuggle bad characters through. + */ + if (0 == strcmp(fmp->printfc, "\"%s\"")) { + gbfprintf(xcsv_file.xcsvfp, "\"%s\"", obuff); } else { - description = csv_stringclean(wpt->description, xcsv_file.badchars); - } - - if (prefer_shortnames) { - if (description) { - xfree(description); - } - description = shortname; - } else if (description) { - char *odesc = description; - description = xstrdup(odesc); - xfree(odesc); - } - if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { - double alt; - GPS_Math_WGS84_To_Known_Datum_M(latitude, longitude, 0.0, - &latitude, &longitude, &alt, xcsv_file.gps_datum); + gbfprintf(xcsv_file.xcsvfp, "%s", obuff); } - i = 0; - QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { - char *obuff; - double lat = latitude; - double lon = longitude; - /* - * A klunky concept. This should evaluate to true for any - * field if we think we don't have realistic value for it. - * This is used by the 'optional' attribute for suppressing - * fields on output. - */ - int field_is_unknown = 0; - - fmp = (field_map_t *) elem; - - if ((i != 0) && !(fmp->options & OPTIONS_NODELIM)) - gbfprintf (xcsv_file.xcsvfp, write_delimiter); - - if (fmp->options & OPTIONS_ABSOLUTE) { - lat = fabs(lat); - lon = fabs(lon); - } - - i++; -#define writebuff(b, fmt, data) snprintf(b, sizeof(b), fmt, data) - switch(fmp->hashed_key) { - case XT_IGNORE: - /* IGNORE -- Write the char printf conversion */ - writebuff(buff, fmp->printfc, ""); - break; - case XT_INDEX: - writebuff(buff, fmp->printfc, waypt_out_count + atoi(fmp->val)); - break; - case XT_CONSTANT: { - const char *cp = xcsv_get_char_from_constant_table(fmp->val); - if (cp) { - writebuff(buff, fmp->printfc, cp); - } else { - writebuff(buff, fmp->printfc, fmp->val); - } - } - break; - case XT_SHORTNAME: - writebuff(buff, fmp->printfc, - (shortname && *shortname) ? shortname : fmp->val); - break; - case XT_ANYNAME: - if (wpt->shortname) { - anyname = xstrdup(wpt->shortname); - } else - if (wpt->description) { - anyname = mkshort(xcsv_file.mkshort_handle, wpt->description); - } else - if (wpt->notes) { - anyname = xstrdup(wpt->notes); - } else - anyname = xstrdup(fmp->val); - - if ((anyname) && (global_opts.synthesize_shortnames)) { - anyname = xstrdup(shortname); - } - - writebuff(buff, fmp->printfc, anyname); - - xfree(anyname); - break; - case XT_DESCRIPTION: - writebuff(buff, fmp->printfc, - (description && *description) ? description : fmp->val); - break; - case XT_NOTES: - writebuff(buff, fmp->printfc, - (wpt->notes && *wpt->notes) ? wpt->notes : fmp->val); - break; - case XT_URL: { - int off = 0; - if (xcsv_urlbase) { - strcpy(buff, xcsv_urlbase); - off = strlen(xcsv_urlbase); - } - if (wpt->url) - snprintf(buff + off, sizeof(buff) - off, fmp->printfc, wpt->url); - else - strcpy(buff, (fmp->val && *fmp->val) ? fmp->val : "\"\""); - } - break; - case XT_URL_LINK_TEXT: - snprintf(buff, sizeof(buff), fmp->printfc, - (wpt->url_link_text && *wpt->url_link_text) ? wpt->url_link_text : fmp->val); - break; - case XT_ICON_DESCR: - writebuff(buff, fmp->printfc, - (wpt->icon_descr && *wpt->icon_descr) ? - wpt->icon_descr : fmp->val); - break; - - /* LATITUDE CONVERSION***********************************************/ - case XT_LAT_DECIMAL: - /* latitude as a pure decimal value */ - writebuff(buff, fmp->printfc, lat); - break; - case XT_LAT_DECIMALDIR: - /* latitude as a decimal value with N/S after it */ - snprintf(buff, sizeof(buff), fmp->printfc, fabs(lat), - LAT_DIR(lat)); - break; - case XT_LAT_DIRDECIMAL: - /* latitude as a decimal value with N/S before it */ - snprintf(buff, sizeof(buff), fmp->printfc, - LAT_DIR(lat), - fabs(lat)); - break; - case XT_LAT_INT32DEG: - /* latitude as an integer offset from 0 degrees */ - writebuff(buff, fmp->printfc, - dec_to_intdeg(lat)); - break; - case XT_LAT_DDMMDIR: - /*latitude as (degrees * 100) + decimal minutes, with N/S after it */ - dec_to_human( buff, fmp->printfc, "SN", degrees2ddmm(lat) ); - break; - case XT_LAT_HUMAN_READABLE: - dec_to_human( buff, fmp->printfc, "SN", lat ); - break; - case XT_LAT_NMEA: - writebuff(buff, fmp->printfc, degrees2ddmm(lat)); - break; - // case XT_LAT_10E is handled outside the switch. - /* LONGITUDE CONVERSIONS*********************************************/ - case XT_LON_DECIMAL: - /* longitude as a pure decimal value */ - writebuff(buff, fmp->printfc, lon); - break; - case XT_LON_DECIMALDIR: - /* latitude as a decimal value with N/S after it */ - snprintf(buff, sizeof(buff), fmp->printfc, - fabs(lon), - LON_DIR(lon)); - break; - case XT_LON_DIRDECIMAL: - /* latitude as a decimal value with N/S before it */ - snprintf(buff, sizeof(buff), fmp->printfc, - LON_DIR(lon), - fabs(lon)); - break; - case XT_LON_INT32DEG: - /* longitudee as an integer offset from 0 degrees */ - writebuff(buff, fmp->printfc, - dec_to_intdeg(lon)); - break; - case XT_LON_DDMMDIR: - /* longidute as (degrees * 100) + decimal minutes, with W/E after it*/ - dec_to_human( buff, fmp->printfc, "WE", degrees2ddmm(lon) ); - break; - case XT_LON_HUMAN_READABLE: - dec_to_human( buff, fmp->printfc, "WE", lon ); - break; - case XT_LATLON_HUMAN_READABLE: - dec_to_human( buff, fmp->printfc, "SN", lat ); - if ( !isspace(buff[strlen(buff)])) strcat( buff, " " ); - dec_to_human( buff+strlen(buff), fmp->printfc, "WE", - lon ); - break; - case XT_LON_NMEA: - writebuff(buff, fmp->printfc, degrees2ddmm(lon)); - break; - // case XT_LON_10E is handled outside the switch. - /* DIRECTIONS *******************************************************/ - case XT_LAT_DIR: - /* latitude N/S as a char */ - writebuff(buff, fmp->printfc, - LAT_DIR(lat)); - break; - case XT_LON_DIR: - /* longitude E/W as a char */ - writebuff(buff, fmp->printfc, - LON_DIR(lon)); - break; - - /* SPECIAL COORDINATES */ - case XT_MAP_EN_BNG: { - char map[3]; - double north, east; - if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map)) - fatal(MYNAME ": Position (%.5f/%.5f) outside of BNG.\n", - wpt->latitude, wpt->longitude); - snprintf(buff, sizeof(buff), fmp->printfc, map, (int)(east + 0.5), (int)(north + 0.5)); - } - break; - case XT_UTM: { - char tbuf[100]; - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - snprintf(tbuf, sizeof(tbuf), "%d%c %6.0f %7.0f", - utmz, utmzc, utme, utmn); - writebuff(buff, fmp->printfc, tbuf); - } - break; - case XT_UTM_ZONE: - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - writebuff(buff, fmp->printfc, utmz); - break; - case XT_UTM_ZONEC: - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - writebuff(buff, fmp->printfc, utmzc); - break; - case XT_UTM_ZONEF: { - char tbuf[10]; - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - tbuf[0] = 0; - snprintf(tbuf, sizeof(tbuf), "%d%c", utmz, utmzc); - writebuff(buff, fmp->printfc, tbuf); - } - break; - case XT_UTM_NORTHING: - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - writebuff(buff, fmp->printfc, utmn); - break; - case XT_UTM_EASTING: - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - writebuff(buff, fmp->printfc, utme); - break; - - /* ALTITUDE CONVERSIONS**********************************************/ - case XT_ALT_FEET: - /* altitude in feet as a decimal value */ - writebuff(buff, fmp->printfc, - METERS_TO_FEET(wpt->altitude)); - break; - case XT_ALT_METERS: - /* altitude in meters as a decimal value */ - writebuff(buff, fmp->printfc, - wpt->altitude); - break; - - /* DISTANCE CONVERSIONS**********************************************/ - case XT_PATH_DISTANCE_MILES: - /* path (route/track) distance in miles */ - writebuff( buff, fmp->printfc, pathdist ); - break; - case XT_PATH_DISTANCE_KM: - /* path (route/track) distance in */ - writebuff( buff, fmp->printfc, pathdist * 5280*12*2.54/100/1000 ); - break; - case XT_PATH_SPEED: - writebuff( buff, fmp->printfc, wpt->speed ); - break; - case XT_PATH_SPEED_KPH: - writebuff( buff, fmp->printfc, MPS_TO_KPH(wpt->speed)); - break; - case XT_PATH_SPEED_MPH: - writebuff( buff, fmp->printfc, MPS_TO_MPH(wpt->speed)); - break; - case XT_PATH_SPEED_KNOTS: - writebuff( buff, fmp->printfc, MPS_TO_KNOTS(wpt->speed)); - break; - case XT_PATH_COURSE: - writebuff( buff, fmp->printfc, wpt->course ); - break; - - /* HEART RATE CONVERSION***********************************************/ - case XT_HEART_RATE: - writebuff(buff, fmp->printfc, wpt->heartrate); - break; - /* CADENCE CONVERSION***********************************************/ - case XT_CADENCE: - writebuff(buff, fmp->printfc, wpt->cadence); - break; - /* TIME CONVERSIONS**************************************************/ - case XT_EXCEL_TIME: - /* creation time as an excel (double) time */ - writebuff(buff, fmp->printfc, TIMET_TO_EXCEL(wpt->creation_time)); - break; - case XT_TIMET_TIME: - /* time as a time_t variable */ - writebuff(buff, fmp->printfc, wpt->creation_time); - break; - case XT_YYYYMMDD_TIME: - writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->creation_time)); - break; - case XT_GMT_TIME: - writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1 ); - break; - case XT_LOCAL_TIME: - writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0 ); - break; - case XT_HMSG_TIME: - writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1 ); - break; - case XT_HMSL_TIME: - writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0 ); - break; - case XT_ISO_TIME: - writetime(buff, sizeof buff, "%Y-%m-%dT%H:%M:%SZ", wpt->creation_time, 1 ); - break; - case XT_ISO_TIME_MS: - xml_fill_in_time(buff, wpt->creation_time, - wpt->microseconds, XML_LONG_TIME); - break; - case XT_GEOCACHE_LAST_FOUND: - writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->gc_data->last_found)); - break; - - /* GEOCACHE STUFF **************************************************/ - case XT_GEOCACHE_DIFF: - /* Geocache Difficulty as a double */ - writebuff(buff, fmp->printfc, wpt->gc_data->diff / 10.0); - field_is_unknown = !wpt->gc_data->diff; - break; - case XT_GEOCACHE_TERR: - /* Geocache Terrain as a double */ - writebuff(buff, fmp->printfc, wpt->gc_data->terr / 10.0); - field_is_unknown = !wpt->gc_data->terr; - break; - case XT_GEOCACHE_CONTAINER: - /* Geocache Container */ - writebuff(buff, fmp->printfc, gs_get_container(wpt->gc_data->container)); - field_is_unknown = wpt->gc_data->container == gc_unknown; - break; - case XT_GEOCACHE_TYPE: - /* Geocache Type */ - writebuff(buff, fmp->printfc, gs_get_cachetype(wpt->gc_data->type)); - field_is_unknown = wpt->gc_data->type == gt_unknown; - break; - case XT_GEOCACHE_HINT: - writebuff(buff, fmp->printfc, NONULL(wpt->gc_data->hint)); - field_is_unknown = !wpt->gc_data->hint; - break; - case XT_GEOCACHE_PLACER: - writebuff(buff, fmp->printfc, NONULL(wpt->gc_data->placer)); - field_is_unknown = !wpt->gc_data->placer; - break; - case XT_GEOCACHE_ISAVAILABLE: - if ( wpt->gc_data->is_available == status_false ) - writebuff(buff, fmp->printfc, "False"); - else if ( wpt->gc_data->is_available == status_true ) - writebuff(buff, fmp->printfc, "True"); - else - writebuff(buff, fmp->printfc, "Unknown"); - break; - case XT_GEOCACHE_ISARCHIVED: - if ( wpt->gc_data->is_archived == status_false ) - writebuff(buff, fmp->printfc, "False"); - else if ( wpt->gc_data->is_archived == status_true ) - writebuff(buff, fmp->printfc, "True"); - else - writebuff(buff, fmp->printfc, "Unknown"); - break; - /* Tracks and Routes ***********************************************/ - case XT_TRACK_NAME: - if (csv_track) writebuff(buff, fmp->printfc, NONULL(csv_track->rte_name)); - break; - case XT_ROUTE_NAME: - if (csv_route) writebuff(buff, fmp->printfc, NONULL(csv_route->rte_name)); - break; - - /* GPS STUFF *******************************************************/ - case XT_GPS_HDOP: - writebuff(buff, fmp->printfc, wpt->hdop); - field_is_unknown = !wpt->hdop; - break; - case XT_GPS_VDOP: - writebuff(buff, fmp->printfc, wpt->vdop); - field_is_unknown = !wpt->vdop; - break; - case XT_GPS_PDOP: - writebuff(buff, fmp->printfc, wpt->pdop); - field_is_unknown = !wpt->pdop; - break; - case XT_GPS_SAT: - writebuff(buff, fmp->printfc, wpt->sat); - field_is_unknown = !wpt->sat; - break; - case XT_GPS_FIX: { - char *fix = NULL; - switch (wpt->fix) { - case fix_unknown: - field_is_unknown = 1; - fix = "Unknown"; - break; - case fix_none: - fix = "None"; - break; - case fix_2d: - fix = "2d"; - break; - case fix_3d: - fix = "3d"; - break; - case fix_dgps: - fix = "dgps"; - break; - case fix_pps: - fix = "pps"; - break; - } - writebuff(buff, fmp->printfc, fix); - } - break; - /* GMSD ************************************************************/ - case XT_COUNTRY: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(country, "")); - } - break; - case XT_STATE: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(state, "")); - } - break; - case XT_CITY: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(city, "")); - } - break; - case XT_POSTAL_CODE: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(postal_code, "")); - } - break; - case XT_STREET_ADDR: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(addr, "")); - } - break; - case XT_PHONE_NR: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(phone_nr, "")); - } - break; - case XT_FACILITY: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(facility, "")); - } - break; - /* specials */ - case XT_FILENAME: - writebuff(buff, fmp->printfc, wpt->session->filename); - break; - case XT_FORMAT: - writebuff(buff, fmp->printfc, wpt->session->name); - break; - case -1: - if (strncmp(fmp->key, "LON_10E", 7) == 0) { - writebuff(buff, fmp->printfc, lon * pow((double)10, atof(fmp->key+7))); - } else - if (strncmp(fmp->key, "LAT_10E", 7) == 0) { - writebuff(buff, fmp->printfc, lat * pow((double)10, atof(fmp->key+7))); - } - break; - default: - warning( MYNAME ": Unknown style directive: %s\n", fmp->key); - break; - } - obuff = csv_stringclean(buff, xcsv_file.badchars); - - if (field_is_unknown && fmp->options & OPTIONS_OPTIONAL) { - goto next; - } - - - /* As a special case (pronounced "horrible hack") we allow - * ""%s"" to smuggle bad characters through. - */ - if (0 == strcmp(fmp->printfc, "\"%s\"")) { - gbfprintf (xcsv_file.xcsvfp, "\"%s\"", obuff); - } else { - gbfprintf (xcsv_file.xcsvfp, "%s", obuff); - } - next: - xfree(obuff); - } + xfree(obuff); + } - gbfprintf (xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); - if (description && description != shortname) - xfree(description); + if (description && description != shortname) { + xfree(description); + } - if (shortname) - xfree(shortname); + if (shortname) { + xfree(shortname); + } - /* increment the index counter */ - waypt_out_count++; + /* increment the index counter */ + waypt_out_count++; } static void -xcsv_noop(const route_head *wp) +xcsv_noop(const route_head* wp) { - /* no-op */ + /* no-op */ } /*****************************************************************************/ @@ -2026,75 +2099,79 @@ xcsv_noop(const route_head *wp) void xcsv_data_write(void) { - queue *elem, *tmp; - ogue_t *ogp; - time_t time; - struct tm tm; - char tbuf[32]; - - /* reset the index counter */ - waypt_out_count = 0; - - time = gpsbabel_time; - if (time == 0) /* testo script ? */ - tm = *gmtime(&time); - else - tm = *localtime(&time); - - /* output prologue lines, if any. */ - QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { - char *cout, *ctmp; - ogp = (ogue_t *) elem; - - cout = xstrdup((ogp->val) ? ogp->val : ""); - - while ((ctmp = strsub(cout, "__FILE__", xcsv_file.fname))) { - xfree(cout); - cout = ctmp; - } - - while ((ctmp = strsub(cout, "__VERSION__", (time == 0) ? "" : gpsbabel_version))) { - xfree(cout); - cout = ctmp; - } - - while (strstr(cout, "__DATE__")) { - strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", &tm); - ctmp = strsub(cout, "__DATE__", tbuf); - xfree(cout); - cout = ctmp; - } - - while (strstr(cout, "__TIME__")) { - strftime(tbuf, sizeof(tbuf), "%H:%S:%M", &tm); - ctmp = strsub(cout, "__TIME__", tbuf); - xfree(cout); - cout = ctmp; - } - - while (strstr(cout, "__DATE_AND_TIME__")) { - strftime(tbuf, sizeof(tbuf), "%a %b %d %H:%M:%S %Y", &tm); - ctmp = strsub(cout, "__DATE_AND_TIME__", tbuf); - xfree(cout); - cout = ctmp; - } - - gbfprintf(xcsv_file.xcsvfp, "%s", cout); - xfree(cout); - gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + queue* elem, *tmp; + ogue_t* ogp; + time_t time; + struct tm tm; + char tbuf[32]; + + /* reset the index counter */ + waypt_out_count = 0; + + time = gpsbabel_time; + if (time == 0) { /* testo script ? */ + tm = *gmtime(&time); + } else { + tm = *localtime(&time); + } + + /* output prologue lines, if any. */ + QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { + char* cout, *ctmp; + ogp = (ogue_t*) elem; + + cout = xstrdup((ogp->val) ? ogp->val : ""); + + while ((ctmp = strsub(cout, "__FILE__", xcsv_file.fname))) { + xfree(cout); + cout = ctmp; } - if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) - waypt_disp_all(xcsv_waypt_pr); - if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == rtedata)) - route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); - if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == trkdata)) - track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + while ((ctmp = strsub(cout, "__VERSION__", (time == 0) ? "" : gpsbabel_version))) { + xfree(cout); + cout = ctmp; + } - /* output epilogue lines, if any. */ - QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { - ogp = (ogue_t *) elem; - gbfprintf (xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter); + while (strstr(cout, "__DATE__")) { + strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", &tm); + ctmp = strsub(cout, "__DATE__", tbuf); + xfree(cout); + cout = ctmp; + } + + while (strstr(cout, "__TIME__")) { + strftime(tbuf, sizeof(tbuf), "%H:%S:%M", &tm); + ctmp = strsub(cout, "__TIME__", tbuf); + xfree(cout); + cout = ctmp; } + + while (strstr(cout, "__DATE_AND_TIME__")) { + strftime(tbuf, sizeof(tbuf), "%a %b %d %H:%M:%S %Y", &tm); + ctmp = strsub(cout, "__DATE_AND_TIME__", tbuf); + xfree(cout); + cout = ctmp; + } + + gbfprintf(xcsv_file.xcsvfp, "%s", cout); + xfree(cout); + gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + } + + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) { + waypt_disp_all(xcsv_waypt_pr); + } + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == rtedata)) { + route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + } + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == trkdata)) { + track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + } + + /* output epilogue lines, if any. */ + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t*) elem; + gbfprintf(xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter); + } } #endif diff --git a/gpsbabel/csv_util.h b/gpsbabel/csv_util.h index ab29e3771..18a8c62f2 100644 --- a/gpsbabel/csv_util.h +++ b/gpsbabel/csv_util.h @@ -19,54 +19,54 @@ /* function prototypes */ -char * +char* #ifndef DEBUG_MEM -csv_stringtrim(const char *string, const char *enclosure, int strip_max); +csv_stringtrim(const char* string, const char* enclosure, int strip_max); #else -CSV_STRINGTRIM(const char *string, const char *enclosure, int strip_max, DEBUG_PARAMS); +CSV_STRINGTRIM(const char* string, const char* enclosure, int strip_max, DEBUG_PARAMS); #define csv_stringtrim( s, e,m ) CSV_STRINGTRIM( s, e, m, __FILE__, __LINE__) #endif -char * -csv_lineparse(const char *stringstart, const char *delimited_by, const char *enclosed_in, const int line_no); +char* +csv_lineparse(const char* stringstart, const char* delimited_by, const char* enclosed_in, const int line_no); void -human_to_dec( const char *instr, double *outlat, double *outlon, int which ); +human_to_dec(const char* instr, double* outlat, double* outlon, int which); -char * +char* #ifndef DEBUG_MEM -csv_stringclean(const char *string, const char *chararray); +csv_stringclean(const char* string, const char* chararray); #else -CSV_STRINGCLEAN(const char *string, const char *chararray,DEBUG_PARAMS); +CSV_STRINGCLEAN(const char* string, const char* chararray,DEBUG_PARAMS); #define csv_stringclean(s,c) CSV_STRINGCLEAN(s,c,__FILE__,__LINE__) #endif -void +void xcsv_data_read(void); -void +void xcsv_data_write(void); -void -xcsv_file_init(void); +void +xcsv_file_init(void); -void -xcsv_prologue_add(char *); +void +xcsv_prologue_add(char*); -void -xcsv_epilogue_add(char *); +void +xcsv_epilogue_add(char*); -void -xcsv_ifield_add(char *, char *, char *); +void +xcsv_ifield_add(char*, char*, char*); -void -xcsv_ofield_add(char *, char *, char *, int options); +void +xcsv_ofield_add(char*, char*, char*, int options); -void +void xcsv_destroy_style(void); -const char * -xcsv_get_char_from_constant_table(char *key); +const char* +xcsv_get_char_from_constant_table(char* key); /****************************************************************************/ /* types required for various xcsv functions */ @@ -77,65 +77,65 @@ xcsv_get_char_from_constant_table(char *key); #define OPTIONS_ABSOLUTE 2 #define OPTIONS_OPTIONAL 3 typedef struct field_map { - queue Q; - char * key; - char * val; - char * printfc; - int hashed_key; - int options; + queue Q; + char* key; + char* val; + char* printfc; + int hashed_key; + int options; } field_map_t; /* a queuing struct for prologues / epilogues */ typedef struct ogue { - queue Q; - char * val; + queue Q; + char* val; } ogue_t; /* something to map config file constants to chars */ typedef struct char_map { - const char * key; - const char * chars; + const char* key; + const char* chars; } char_map_t; -/* - * a type describing all the wonderful elements of xcsv files, in a +/* + * a type describing all the wonderful elements of xcsv files, in a * nutshell. */ typedef struct { - int is_internal; /* bool - is internal (1) or parsed (0) */ - - int prologue_lines; /* # of lines to ignore at top of the file */ - int epilogue_lines; /* # of lines to ignore at bottom of file */ - - /* header lines for writing at the top of the file. */ - queue prologue; - - /* footer lines for writing at the bottom of the file. */ - queue epilogue; - - char * field_delimiter; /* comma, quote, etc... */ - char * record_delimiter; /* newline, c/r, etc... */ - - char * badchars; /* characters we never write to output */ - - queue ifield; /* input field mapping */ - queue * ofield; /* output field mapping */ - - int ifield_ct; /* actual # of ifields */ - int ofield_ct; /* actual # of ofields */ - - gbfile * xcsvfp; /* ptr to current *open* data file */ - char * fname; /* ptr to filename of above. */ - - char * description; /* Description for help text */ - char * extension; /* preferred filename extension (for wrappers)*/ - - short_handle mkshort_handle;/* handle for mkshort() */ - ff_type type; /* format type for GUI wrappers. */ - - int gps_datum; /* result of GPS_Lookup_Datum_Index */ - gpsdata_type datatype; /* can be wptdata, rtedata or trkdata */ - /* ... or ZERO to keep the old behaviour */ + int is_internal; /* bool - is internal (1) or parsed (0) */ + + int prologue_lines; /* # of lines to ignore at top of the file */ + int epilogue_lines; /* # of lines to ignore at bottom of file */ + + /* header lines for writing at the top of the file. */ + queue prologue; + + /* footer lines for writing at the bottom of the file. */ + queue epilogue; + + char* field_delimiter; /* comma, quote, etc... */ + char* record_delimiter; /* newline, c/r, etc... */ + + char* badchars; /* characters we never write to output */ + + queue ifield; /* input field mapping */ + queue* ofield; /* output field mapping */ + + int ifield_ct; /* actual # of ifields */ + int ofield_ct; /* actual # of ofields */ + + gbfile* xcsvfp; /* ptr to current *open* data file */ + char* fname; /* ptr to filename of above. */ + + char* description; /* Description for help text */ + char* extension; /* preferred filename extension (for wrappers)*/ + + short_handle mkshort_handle;/* handle for mkshort() */ + ff_type type; /* format type for GUI wrappers. */ + + int gps_datum; /* result of GPS_Lookup_Datum_Index */ + gpsdata_type datatype; /* can be wptdata, rtedata or trkdata */ + /* ... or ZERO to keep the old behaviour */ } xcsv_file_t; diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index dab33a81f..c5ce80c34 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -96,8 +96,8 @@ #define KNOTS_TO_MPS(a) (KPH_TO_MPS((a)*1.852)) /* - * Snprintf is in SUS (so it's in most UNIX-like substance) and it's in - * C99 (albeit with slightly different semantics) but it isn't in C89. + * Snprintf is in SUS (so it's in most UNIX-like substance) and it's in + * C99 (albeit with slightly different semantics) but it isn't in C89. * This tweaks allows us to use snprintf on the holdout. */ #if __WIN32__ @@ -126,10 +126,10 @@ # define GB_PATHSEP '/' #endif -/* +/* * Toss in some GNU C-specific voodoo for checking. */ -#if __GNUC__ +#if __GNUC__ # define PRINTFLIKE(x,y) __attribute__ ((__format__ (__printf__, (x), (y)))) # define NORETURN void __attribute__ ((__noreturn__)) #else @@ -157,30 +157,31 @@ ((struct_type *)((char *)(memberp) - offsetof(struct_type, member_name))) typedef enum { - fix_unknown=-1, - fix_none=0, - fix_2d=1, - fix_3d, - fix_dgps, - fix_pps + fix_unknown=-1, + fix_none=0, + fix_2d=1, + fix_3d, + fix_dgps, + fix_pps } fix_type; typedef enum { - status_unknown=0, - status_true, - status_false + status_unknown=0, + status_true, + status_false } status_type; - + /* * Define globally on which kind of data gpsbabel is working. * Important for "file types" that are essentially a communication * protocol for a receiver, like the Magellan serial data. */ typedef enum { - trkdata = 1 , - wptdata, - rtedata, - posndata + unknown_gpsdata = 0, + trkdata = 1 , + wptdata, + rtedata, + posndata } gpsdata_type; #define NOTHINGMASK 0 @@ -197,16 +198,16 @@ typedef enum { #define doing_posn ((global_opts.masked_objective & POSNDATAMASK) == POSNDATAMASK) typedef struct { - int synthesize_shortnames; - int debug_level; - gpsdata_type objective; - unsigned int masked_objective; - int verbose_status; /* set by GUI wrappers for status */ - int smart_icons; - int smart_names; - cet_cs_vec_t *charset; - char *charset_name; - inifile_t *inifile; + int synthesize_shortnames; + int debug_level; + gpsdata_type objective; + unsigned int masked_objective; + int verbose_status; /* set by GUI wrappers for status */ + int smart_icons; + int smart_names; + cet_cs_vec_t* charset; + char* charset_name; + inifile_t* inifile; } global_options; extern global_options global_opts; @@ -225,83 +226,87 @@ extern int geocaches_present; #define XML_LONG_TIME 2 /* - * Extended data if waypoint happens to represent a geocache. This is + * Extended data if waypoint happens to represent a geocache. This is * totally voluntary data... */ typedef enum { - gt_unknown = 0 , - gt_traditional, - gt_multi, - gt_virtual, - gt_letterbox, - gt_event, - gt_suprise, - gt_webcam, - gt_earth, - gt_locationless, - gt_benchmark, /* Extension to Groundspeak for GSAK */ - gt_cito, - gt_ape, - gt_mega, - gt_wherigo + gt_unknown = 0 , + gt_traditional, + gt_multi, + gt_virtual, + gt_letterbox, + gt_event, + gt_suprise, + gt_webcam, + gt_earth, + gt_locationless, + gt_benchmark, /* Extension to Groundspeak for GSAK */ + gt_cito, + gt_ape, + gt_mega, + gt_wherigo } geocache_type; typedef enum { - gc_unknown = 0, - gc_micro, - gc_other, - gc_regular, - gc_large, - gc_virtual, - gc_small + gc_unknown = 0, + gc_micro, + gc_other, + gc_regular, + gc_large, + gc_virtual, + gc_small } geocache_container; typedef struct { - int is_html; - char *utfstring; + int is_html; + char* utfstring; } utf_string; typedef struct { - int id; /* The decimal cache number */ - geocache_type type:5; - geocache_container container:4; - unsigned int diff:6; /* (multiplied by ten internally) */ - unsigned int terr:6; /* (likewise) */ - status_type is_archived:2; - status_type is_available:2; - time_t exported; - time_t last_found; - char *placer; /* Placer name */ - int placer_id; /* Placer id */ - char *hint; /* all these UTF8, XML entities removed, May be not HTML. */ - utf_string desc_short; - utf_string desc_long; + int id; /* The decimal cache number */ + geocache_type type:5; + geocache_container container:4; + unsigned int diff:6; /* (multiplied by ten internally) */ + unsigned int terr:6; /* (likewise) */ + status_type is_archived:2; + status_type is_available:2; + status_type is_memberonly:2; + status_type has_customcoords:2; + time_t exported; + time_t last_found; + char* placer; /* Placer name */ + int placer_id; /* Placer id */ + char* hint; /* all these UTF8, XML entities removed, May be not HTML. */ + utf_string desc_short; + utf_string desc_long; + int favorite_points; + char* personal_note; } geocache_data ; typedef struct xml_tag { - char *tagname; - char *cdata; - int cdatalen; - char *parentcdata; - int parentcdatalen; - char **attributes; - struct xml_tag *parent; - struct xml_tag *sibling; - struct xml_tag *child; + char* tagname; + char* cdata; + int cdatalen; + char* parentcdata; + int parentcdatalen; + char** attributes; + struct xml_tag* parent; + struct xml_tag* sibling; + struct xml_tag* child; } xml_tag ; -typedef void (*fs_destroy)(void *); -typedef void (*fs_copy)(void **, void *); -typedef void (*fs_convert)(void *); +typedef void (*fs_destroy)(void*); +typedef void (*fs_copy)(void**, void*); +typedef void (*fs_convert)(void*); typedef struct format_specific_data { - long type; - struct format_specific_data *next; - - fs_destroy destroy; - fs_copy copy; - fs_convert convert; + long type; + struct format_specific_data* next; + + fs_destroy destroy; + fs_copy copy; + fs_convert convert; } format_specific_data; typedef struct { @@ -310,17 +315,17 @@ typedef struct { } gb_color; -format_specific_data *fs_chain_copy( format_specific_data *source ); -void fs_chain_destroy( format_specific_data *chain ); -format_specific_data *fs_chain_find( format_specific_data *chain, long type ); -void fs_chain_add( format_specific_data **chain, format_specific_data *data ); +format_specific_data* fs_chain_copy(format_specific_data* source); +void fs_chain_destroy(format_specific_data* chain); +format_specific_data* fs_chain_find(format_specific_data* chain, long type); +void fs_chain_add(format_specific_data** chain, format_specific_data* data); typedef struct fs_xml { - format_specific_data fs; - xml_tag *tag; + format_specific_data fs; + xml_tag* tag; } fs_xml; -fs_xml *fs_xml_alloc( long type ); +fs_xml* fs_xml_alloc(long type); #define FS_GPX 0x67707800L #define FS_AN1W 0x616e3177L @@ -333,33 +338,33 @@ fs_xml *fs_xml_alloc( long type ); * Structures and functions for multiple URLs per waypoint. */ typedef struct url_link { - struct url_link *url_next; - char *url; - char *url_link_text; + struct url_link* url_next; + char* url; + char* url_link_text; } url_link; /* * Misc bitfields inside struct waypoint; */ typedef struct { - unsigned int icon_descr_is_dynamic:1; - unsigned int shortname_is_synthetic:1; - unsigned int cet_converted:1; /* strings are converted to UTF8; interesting only for input */ - unsigned int fmt_use:1; /* lightweight "extra data" */ - /* "flagged fields" */ - unsigned int temperature:1; /* temperature field is set */ - unsigned int proximity:1; /* proximity field is set */ - unsigned int course:1; /* course field is set */ - unsigned int speed:1; /* speed field is set */ - unsigned int depth:1; /* depth field is set */ - /* !ToDo! - unsigned int altitude:1; /+ altitude field is set +/ - ... and others - */ - unsigned int is_split:1; /* the waypoint represents a split */ - unsigned int new_trkseg:1; /* True if first in new trkseg. */ - - + unsigned int icon_descr_is_dynamic:1; + unsigned int shortname_is_synthetic:1; + unsigned int cet_converted:1; /* strings are converted to UTF8; interesting only for input */ + unsigned int fmt_use:1; /* lightweight "extra data" */ + /* "flagged fields" */ + unsigned int temperature:1; /* temperature field is set */ + unsigned int proximity:1; /* proximity field is set */ + unsigned int course:1; /* course field is set */ + unsigned int speed:1; /* speed field is set */ + unsigned int depth:1; /* depth field is set */ + /* !ToDo! + unsigned int altitude:1; /+ altitude field is set +/ + ... and others + */ + unsigned int is_split:1; /* the waypoint represents a split */ + unsigned int new_trkseg:1; /* True if first in new trkseg. */ + + } wp_flags; // These are dicey as they're collected on read. Subsequent filters may change @@ -380,271 +385,288 @@ const global_trait* get_traits(); #define WAYPT_UNSET(wpt,member) wpt->wpt_flags.member = 0 #define WAYPT_HAS(wpt,member) (wpt->wpt_flags.member) /* - * This is a waypoint, as stored in the GPSR. It tries to not + * This is a waypoint, as stored in the GPSR. It tries to not * cater to any specific model or protocol. Anything that needs to * be truncated, edited, or otherwise trimmed should be done on the * way to the target. */ typedef struct { - queue Q; /* Master waypoint q. Not for use + queue Q; /* Master waypoint q. Not for use by modules. */ - double latitude; /* Degrees */ - double longitude; /* Degrees */ - double altitude; /* Meters. */ - - /* - * The "thickness" of a waypoint; adds an element of 3D. Can be - * used to construct rudimentary polygons for, say, airspace - * definitions. The units are meters. - */ - double depth; - - /* - * An alarm trigger value that can be considered to be a circle - * surrounding a waypoint (or cylinder if depth is also defined). - * The units are meters. - */ - double proximity; - - /* shortname is a waypoint name as stored in receiver. It should - * strive to be, well, short, and unique. Enforcing length and - * character restrictions is the job of the output. A typical - * minimum length for shortname is 6 characters for NMEA units, - * 8 for Magellan and 10 for Vista. These are only guidelines. - */ - char *shortname; - /* - * description is typically a human readable description of the - * waypoint. It may be used as a comment field in some receivers. - * These are probably under 40 bytes, but that's only a guideline. - */ - char *description; - /* - * notes are relatively long - over 100 characters - prose associated - * with the above. Unlike shortname and description, these are never - * used to compute anything else and are strictly "passed through". - * Few formats support this. - */ - char *notes; - - /* This is a bit icky. Multiple waypoint support is an - * afterthought and I don't want to change our data structures. - * So we have the first in the waypoint itself and subsequent - * ones in a linked list. - * We also use an implicit anonymous union here, so these three - * members must match struct url_link... - */ - struct url_link *url_next; - char *url; - char *url_link_text; - - wp_flags wpt_flags; - const char *icon_descr; - time_t creation_time; /* standardized in UTC/GMT */ - int microseconds; /* Optional millionths of a second. */ - - /* - * route priority is for use by the simplify filter. If we have - * some reason to believe that the route point is more important, - * we can give it a higher (numerically; 0 is the lowest) priority. - * This causes it to be removed last. - * This is currently used by the saroute input filter to give named - * waypoints (representing turns) a higher priority. - * This is also used by the google input filter because they were - * nice enough to use exactly the same priority scheme. - */ - int route_priority; - - /* Optional dilution of precision: positional, horizontal, veritcal. - * 1 <= dop <= 50 - */ - float hdop; - float vdop; - float pdop; - float course; /* Optional: degrees true */ - float speed; /* Optional: meters per second. */ - fix_type fix; /* Optional: 3d, 2d, etc. */ - int sat; /* Optional: number of sats used for fix */ - - unsigned char heartrate; /* Beats/min. likely to get moved to fs. */ - unsigned char cadence; /* revolutions per minute */ - float power; /* watts, as measured by cyclists */ - float temperature; /* Degrees celsius */ - const geocache_data *gc_data; - format_specific_data *fs; - session_t *session; /* pointer to a session struct */ - void *extra_data; /* Extra data added by, say, a filter. */ + double latitude; /* Degrees */ + double longitude; /* Degrees */ + double altitude; /* Meters. */ + + /* + * The "thickness" of a waypoint; adds an element of 3D. Can be + * used to construct rudimentary polygons for, say, airspace + * definitions. The units are meters. + */ + double depth; + + /* + * An alarm trigger value that can be considered to be a circle + * surrounding a waypoint (or cylinder if depth is also defined). + * The units are meters. + */ + double proximity; + + /* shortname is a waypoint name as stored in receiver. It should + * strive to be, well, short, and unique. Enforcing length and + * character restrictions is the job of the output. A typical + * minimum length for shortname is 6 characters for NMEA units, + * 8 for Magellan and 10 for Vista. These are only guidelines. + */ + char* shortname; + /* + * description is typically a human readable description of the + * waypoint. It may be used as a comment field in some receivers. + * These are probably under 40 bytes, but that's only a guideline. + */ + char* description; + /* + * notes are relatively long - over 100 characters - prose associated + * with the above. Unlike shortname and description, these are never + * used to compute anything else and are strictly "passed through". + * Few formats support this. + */ + char* notes; + + /* This is a bit icky. Multiple waypoint support is an + * afterthought and I don't want to change our data structures. + * So we have the first in the waypoint itself and subsequent + * ones in a linked list. + * We also use an implicit anonymous union here, so these three + * members must match struct url_link... + */ + struct url_link* url_next; + char* url; + char* url_link_text; + + wp_flags wpt_flags; + const char* icon_descr; + time_t creation_time; /* standardized in UTC/GMT */ + int microseconds; /* Optional millionths of a second. */ + + /* + * route priority is for use by the simplify filter. If we have + * some reason to believe that the route point is more important, + * we can give it a higher (numerically; 0 is the lowest) priority. + * This causes it to be removed last. + * This is currently used by the saroute input filter to give named + * waypoints (representing turns) a higher priority. + * This is also used by the google input filter because they were + * nice enough to use exactly the same priority scheme. + */ + int route_priority; + + /* Optional dilution of precision: positional, horizontal, veritcal. + * 1 <= dop <= 50 + */ + float hdop; + float vdop; + float pdop; + float course; /* Optional: degrees true */ + float speed; /* Optional: meters per second. */ + fix_type fix; /* Optional: 3d, 2d, etc. */ + int sat; /* Optional: number of sats used for fix */ + + unsigned char heartrate; /* Beats/min. likely to get moved to fs. */ + unsigned char cadence; /* revolutions per minute */ + float power; /* watts, as measured by cyclists */ + float temperature; /* Degrees celsius */ + const geocache_data* gc_data; + format_specific_data* fs; + session_t* session; /* pointer to a session struct */ + void* extra_data; /* Extra data added by, say, a filter. */ } waypoint; typedef struct { - queue Q; /* Link onto parent list. */ - queue waypoint_list; /* List of child waypoints */ - char *rte_name; - char *rte_desc; - char *rte_url; - int rte_num; - int rte_waypt_ct; /* # waypoints in waypoint list */ - format_specific_data *fs; - unsigned short cet_converted; /* strings are converted to UTF8; interesting only for input */ - gb_color line_color; /* Optional line color for rendering */ - int line_width; /* in pixels (sigh). < 0 is unknown. */ - session_t *session; /* pointer to a session struct */ + queue Q; /* Link onto parent list. */ + queue waypoint_list; /* List of child waypoints */ + char* rte_name; + char* rte_desc; + char* rte_url; + int rte_num; + int rte_waypt_ct; /* # waypoints in waypoint list */ + format_specific_data* fs; + unsigned short cet_converted; /* strings are converted to UTF8; interesting only for input */ + gb_color line_color; /* Optional line color for rendering */ + int line_width; /* in pixels (sigh). < 0 is unknown. */ + session_t* session; /* pointer to a session struct */ } route_head; /* * Structure of recomputed track/roue data. */ typedef struct { - double distance_meters; - double max_alt; - double min_alt; - double max_spd; /* Meters/sec */ - double min_spd; /* Meters/sec */ - double avg_hrt; /* Avg Heartrate */ - double avg_cad; /* Avg Cadence */ - time_t start; /* Min time */ - time_t end; /* Max time */ - int min_hrt; /* Min Heartrate */ - int max_hrt; /* Max Heartrate */ - int max_cad; /* Max Cadence */ + double distance_meters; + double max_alt; /* unknown_alt => invalid */ + double min_alt; /* -unknown_alt => invalid */ + double max_spd; /* Meters/sec */ + double min_spd; /* Meters/sec */ + double avg_hrt; /* Avg Heartrate */ + double avg_cad; /* Avg Cadence */ + time_t start; /* Min time */ + time_t end; /* Max time */ + int min_hrt; /* Min Heartrate */ + int max_hrt; /* Max Heartrate */ + int max_cad; /* Max Cadence */ } computed_trkdata; /* * Bounding box information. */ typedef struct { - double max_lat; - double max_lon; - double max_alt; - double min_lat; - double min_lon; - double min_alt; + double max_lat; + double max_lon; + double max_alt; /* unknown_alt => invalid */ + double min_lat; + double min_lon; + double min_alt; /* -unknown_alt => invalid */ } bounds; typedef struct { - volatile int request_terminate; + volatile int request_terminate; } posn_status; extern posn_status tracking_status; -typedef void (*ff_init) (char const *); -typedef void (*ff_deinit) (void); -typedef void (*ff_read) (void); -typedef void (*ff_write) (void); -typedef void (*ff_exit) (void); -typedef void (*ff_writeposn) (waypoint *); -typedef waypoint * (*ff_readposn) (posn_status *); +typedef void (*ff_init)(char const*); +typedef void (*ff_deinit)(void); +typedef void (*ff_read)(void); +typedef void (*ff_write)(void); +typedef void (*ff_exit)(void); +typedef void (*ff_writeposn)(waypoint*); +typedef waypoint* (*ff_readposn)(posn_status*); #ifndef DEBUG_MEM -char * get_option(const char *iarglist, const char *argname); +char* get_option(const char* iarglist, const char* argname); #else #define DEBUG_PARAMS const char *file, const int line -char *GET_OPTION(const char *iarglist, const char *argname, DEBUG_PARAMS); +char* GET_OPTION(const char* iarglist, const char* argname, DEBUG_PARAMS); #define get_option(iarglist, argname) GET_OPTION(iarglist, argname, __FILE__, __LINE__) #endif -typedef void (*filter_init) (char const *); -typedef void (*filter_process) (void); -typedef void (*filter_deinit) (void); -typedef void (*filter_exit) (void); - -typedef void (*waypt_cb) (const waypoint *); -typedef void (*route_hdr)(const route_head *); -typedef void (*route_trl)(const route_head *); -void waypt_add (waypoint *); -waypoint * waypt_dupe (const waypoint *); -waypoint * waypt_new(void); -void waypt_del (waypoint *); -void waypt_free (waypoint *); +typedef void (*filter_init)(char const*); +typedef void (*filter_process)(void); +typedef void (*filter_deinit)(void); +typedef void (*filter_exit)(void); + +typedef void (*waypt_cb)(const waypoint*); +typedef void (*route_hdr)(const route_head*); +typedef void (*route_trl)(const route_head*); +void waypt_add(waypoint*); +waypoint* waypt_dupe(const waypoint*); +waypoint* waypt_new(void); +void waypt_del(waypoint*); +void waypt_free(waypoint*); void waypt_disp_all(waypt_cb); -void waypt_disp_session(const session_t *se, waypt_cb cb); -void waypt_init_bounds(bounds *bounds); -int waypt_bounds_valid(bounds *bounds); -void waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp); -void waypt_compute_bounds(bounds *); +void waypt_disp_session(const session_t* se, waypt_cb cb); +void waypt_init_bounds(bounds* bounds); +int waypt_bounds_valid(bounds* bounds); +void waypt_add_to_bounds(bounds* bounds, const waypoint* waypointp); +void waypt_compute_bounds(bounds*); double gcgeodist(const double lat1, const double lon1, const double lat2, const double lon2); -void waypt_flush(queue *); +void waypt_flush(queue*); void waypt_flush_all(void); unsigned int waypt_count(void); void set_waypt_count(unsigned int nc); -void waypt_add_url(waypoint *wpt, char *link, char *url_link_text); -void free_gpx_extras (xml_tag * tag); -void xcsv_setup_internal_style(const char *style_buf); -void xcsv_read_internal_style(const char *style_buf); -waypoint * find_waypt_by_name(const char *name); -void waypt_backup(signed int *count, queue **head_bak); -void waypt_restore(signed int count, queue *head_bak); - -geocache_data *waypt_alloc_gc_data(waypoint *wpt); -int waypt_empty_gc_data(const waypoint *wpt); -geocache_type gs_mktype(const char *t); -geocache_container gs_mkcont(const char *t); - -route_head *route_head_alloc(void); -void route_add (waypoint *); -void route_add_wpt(route_head *rte, waypoint *wpt); -void route_del_wpt(route_head *rte, waypoint *wpt); -void track_add_wpt(route_head *rte, waypoint *wpt); -void track_del_wpt(route_head *rte, waypoint *wpt); -void route_add_head(route_head *rte); -void route_del_head(route_head *rte); -void route_reverse(const route_head *rte_hd); -waypoint * route_find_waypt_by_name(route_head *rh, const char *name); -void track_add_head(route_head *rte); -void track_del_head(route_head *rte); -void track_insert_head(route_head *rte, route_head *predecessor); -void route_disp(const route_head *rte, waypt_cb); +void waypt_add_url(waypoint* wpt, char* link, char* url_link_text); +void free_gpx_extras(xml_tag* tag); +void xcsv_setup_internal_style(const char* style_buf); +void xcsv_read_internal_style(const char* style_buf); +waypoint* find_waypt_by_name(const char* name); +void waypt_backup(signed int* count, queue** head_bak); +void waypt_restore(signed int count, queue* head_bak); + +geocache_data* waypt_alloc_gc_data(waypoint* wpt); +int waypt_empty_gc_data(const waypoint* wpt); +geocache_type gs_mktype(const char* t); +geocache_container gs_mkcont(const char* t); + +route_head* route_head_alloc(void); +void route_add(waypoint*); +void route_add_wpt(route_head* rte, waypoint* wpt); +void route_del_wpt(route_head* rte, waypoint* wpt); +void track_add_wpt(route_head* rte, waypoint* wpt); +void track_del_wpt(route_head* rte, waypoint* wpt); +void route_add_head(route_head* rte); +void route_del_head(route_head* rte); +void route_reverse(const route_head* rte_hd); +waypoint* route_find_waypt_by_name(route_head* rh, const char* name); +void track_add_head(route_head* rte); +void track_del_head(route_head* rte); +void track_insert_head(route_head* rte, route_head* predecessor); +void route_disp(const route_head* rte, waypt_cb); void route_disp_all(route_hdr, route_trl, waypt_cb); void track_disp_all(route_hdr, route_trl, waypt_cb); -void route_disp_session(const session_t *se, route_hdr rh, route_trl rt, waypt_cb wc); -void track_disp_session(const session_t *se, route_hdr rh, route_trl rt, waypt_cb wc); -void route_flush( queue *); +void route_disp_session(const session_t* se, route_hdr rh, route_trl rt, waypt_cb wc); +void track_disp_session(const session_t* se, route_hdr rh, route_trl rt, waypt_cb wc); +void route_flush(queue*); void route_flush_all(void); void route_flush_all_routes(void); void route_flush_all_tracks(void); -route_head * route_find_route_by_name(const char *name); -route_head * route_find_track_by_name(const char *name); +route_head* route_find_route_by_name(const char* name); +route_head* route_find_track_by_name(const char* name); unsigned int route_waypt_count(void); unsigned int route_count(void); unsigned int track_waypt_count(void); unsigned int track_count(void); -void route_copy( int *dst_count, int *dst_wpt_count, queue **dst, queue *src ); -void route_backup(signed int *count, queue **head_bak); -void route_restore( queue *head_bak); -void route_append( queue *src ); -void track_backup(signed int *count, queue **head_bak); -void track_restore( queue *head_bak); -void track_append( queue *src ); -void route_flush( queue *head ); -void track_recompute( const route_head *trk, computed_trkdata **); +void route_copy(int* dst_count, int* dst_wpt_count, queue** dst, queue* src); +void route_backup(signed int* count, queue** head_bak); +void route_restore(queue* head_bak); +void route_append(queue* src); +void track_backup(signed int* count, queue** head_bak); +void track_restore(queue* head_bak); +void track_append(queue* src); +void route_flush(queue* head); +void track_recompute(const route_head* trk, computed_trkdata**); /* * All shortname functions take a shortname handle as the first arg. * This is an opaque pointer. Callers must not fondle the contents of it. */ -typedef struct short_handle * short_handle; -#ifndef DEBUG_MEM -char *mkshort (short_handle, const char *); -void *mkshort_new_handle(void); +// This is a crutch until the new C++ shorthandle goes in. +#define PRIME 37 +typedef struct { + unsigned int target_len; + char* badchars; + char* goodchars; + char* defname; + queue namelist[PRIME]; + + /* Various internal flags at end to allow alignment flexibility. */ + unsigned int mustupper:1; + unsigned int whitespaceok:1; + unsigned int repeating_whitespaceok:1; + unsigned int must_uniq:1; + unsigned int is_utf8:1; +} mkshort_handle_imp; +typedef mkshort_handle_imp* short_handle; + +#ifndef DEBUG_MEM +char* mkshort(short_handle, const char*); +short_handle mkshort_new_handle(void); #else -char *MKSHORT(short_handle, const char *, DEBUG_PARAMS); -void *MKSHORT_NEW_HANDLE(DEBUG_PARAMS); +char* MKSHORT(short_handle, const char*, DEBUG_PARAMS); +void* MKSHORT_NEW_HANDLE(DEBUG_PARAMS); #define mkshort( a, b) MKSHORT(a,b,__FILE__, __LINE__) #define mkshort_new_handle() MKSHORT_NEW_HANDLE(__FILE__,__LINE__) #endif -char *mkshort_from_wpt(short_handle h, const waypoint *wpt); -void mkshort_del_handle(short_handle *h); +char* mkshort_from_wpt(short_handle h, const waypoint* wpt); +void mkshort_del_handle(short_handle* h); void setshort_length(short_handle, int n); -void setshort_badchars(short_handle, const char *); -void setshort_goodchars(short_handle, const char *); +void setshort_badchars(short_handle, const char*); +void setshort_goodchars(short_handle, const char*); void setshort_mustupper(short_handle, int n); void setshort_mustuniq(short_handle, int n); void setshort_whitespace_ok(short_handle, int n); void setshort_repeating_whitespace_ok(short_handle, int n); -void setshort_defname(short_handle, const char *s); +void setshort_defname(short_handle, const char* s); void setshort_is_utf8(short_handle h, const int is_utf8); /* @@ -652,8 +674,8 @@ void setshort_is_utf8(short_handle h, const int is_utf8); */ #define VMFL_NOZERO (1 << 0) typedef struct vmem { - void *mem; /* visible memory object */ - size_t size; /* allocated size of object */ + char* mem; /* visible memory object */ + size_t size; /* allocated size of object */ } vmem_t; vmem_t vmem_alloc(size_t, int flags); void vmem_free(vmem_t*); @@ -668,7 +690,7 @@ void vmem_realloc(vmem_t*, size_t); #define ARGTYPE_FILE 0x00000005 #define ARGTYPE_OUTFILE 0x00000006 -/* REQUIRED means that the option is required to be set. +/* REQUIRED means that the option is required to be set. * See also BEGIN/END_REQ */ #define ARGTYPE_REQUIRED 0x40000000 @@ -677,19 +699,19 @@ void vmem_realloc(vmem_t*, size_t); #define ARGTYPE_HIDDEN 0x20000000 /* BEGIN/END_EXCL mark the beginning and end of an exclusive range of - * options. No more than one of the options in the range may be selected + * options. No more than one of the options in the range may be selected * or set. If exactly one must be set, use with BEGIN/END_REQ * Both of these flags set is just like neither set, so avoid doing that. */ #define ARGTYPE_BEGIN_EXCL 0x10000000 #define ARGTYPE_END_EXCL 0x08000000 -/* BEGIN/END_REQ mark the beginning and end of a required range of +/* BEGIN/END_REQ mark the beginning and end of a required range of * options. One or more of the options in the range MUST be selected or set. - * If exactly one must be set, use with BEGIN/END_EXCL + * If exactly one must be set, use with BEGIN/END_EXCL * Both of these flags set is synonymous with REQUIRED, so use that instead * for "groups" of exactly one option. */ #define ARGTYPE_BEGIN_REQ 0x04000000 -#define ARGTYPE_END_REQ 0x02000000 +#define ARGTYPE_END_REQ 0x02000000 #define ARGTYPE_TYPEMASK 0x00000fff #define ARGTYPE_FLAGMASK 0xfffff000 @@ -698,114 +720,114 @@ void vmem_realloc(vmem_t*, size_t); #define ARG_TERMINATOR {0, 0, 0, 0, 0, ARG_NOMINMAX} typedef struct arglist { - const char *argstring; - char **argval; - const char *helpstring; - const char *defaultvalue; - const gbuint32 argtype; - const char *minvalue; /* minimum value for numeric options */ - const char *maxvalue; /* maximum value for numeric options */ - char *argvalptr; /* !!! internal helper. Not used in definitions !!! */ + const char* argstring; + char** argval; + const char* helpstring; + const char* defaultvalue; + const gbuint32 argtype; + const char* minvalue; /* minimum value for numeric options */ + const char* maxvalue; /* maximum value for numeric options */ + char* argvalptr; /* !!! internal helper. Not used in definitions !!! */ } arglist_t; typedef enum { - ff_type_file = 1, /* normal format: useful to a GUI. */ - ff_type_internal, /* fmt not useful with default options */ - ff_type_serial /* format describes a serial protocol (GUI can display port names) */ + ff_type_file = 1, /* normal format: useful to a GUI. */ + ff_type_internal, /* fmt not useful with default options */ + ff_type_serial /* format describes a serial protocol (GUI can display port names) */ } ff_type; typedef enum { - ff_cap_rw_wpt, - ff_cap_rw_trk, - ff_cap_rw_rte + ff_cap_rw_wpt, + ff_cap_rw_trk, + ff_cap_rw_rte } ff_cap_array; typedef enum { - ff_cap_none, - ff_cap_read = 1, - ff_cap_write = 2 + ff_cap_none, + ff_cap_read = 1, + ff_cap_write = 2 } ff_cap; #define FF_CAP_RW_ALL \ - { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write } + { (ff_cap) (ff_cap_read | ff_cap_write), (ff_cap) (ff_cap_read | ff_cap_write), (ff_cap) (ff_cap_read | ff_cap_write) } #define FF_CAP_RW_WPT \ - { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none} + { (ff_cap) (ff_cap_read | ff_cap_write), ff_cap_none, ff_cap_none} /* * Format capabilities for realtime positioning. */ typedef struct position_ops { - ff_init rd_init; - ff_readposn rd_position; - ff_deinit rd_deinit; + ff_init rd_init; + ff_readposn rd_position; + ff_deinit rd_deinit; - ff_init wr_init; - ff_writeposn wr_position; - ff_deinit wr_deinit; + ff_init wr_init; + ff_writeposn wr_position; + ff_deinit wr_deinit; } position_ops_t; /* * Describe the file format to the caller. */ typedef struct ff_vecs { - ff_type type; - ff_cap cap[3]; - ff_init rd_init; - ff_init wr_init; - ff_deinit rd_deinit; - ff_deinit wr_deinit; - ff_read read; - ff_write write; - ff_exit exit; - arglist_t *args; - const char *encode; - int fixed_encode; - position_ops_t position_ops; - const char *name; /* dyn. initialized by find_vec */ + ff_type type; + ff_cap cap[3]; + ff_init rd_init; + ff_init wr_init; + ff_deinit rd_deinit; + ff_deinit wr_deinit; + ff_read read; + ff_write write; + ff_exit exit; + arglist_t* args; + const char* encode; + int fixed_encode; + position_ops_t position_ops; + const char* name; /* dyn. initialized by find_vec */ } ff_vecs_t; typedef struct style_vecs { - const char *name; - const char *style_buf; + const char* name; + const char* style_buf; } style_vecs_t; extern style_vecs_t style_list[]; void waypt_init(void); void route_init(void); -void waypt_disp(const waypoint *); +void waypt_disp(const waypoint*); void waypt_status_disp(int total_ct, int myct); -double waypt_time(const waypoint *wpt); -double waypt_speed(const waypoint *A, const waypoint *B); -double waypt_speed_ex(const waypoint *A, const waypoint *B); -double waypt_course(const waypoint *A, const waypoint *B); -double waypt_distance(const waypoint *A, const waypoint *B); -double waypt_distance_ex(const waypoint *A, const waypoint *B); - -NORETURN fatal(const char *, ...) PRINTFLIKE(1, 2); -void is_fatal(const int condition, const char *, ...) PRINTFLIKE(2, 3); -void warning(const char *, ...) PRINTFLIKE(1, 2); - -ff_vecs_t *find_vec(char * const, char **); -void assign_option(const char *vecname, arglist_t *ap, const char *val); -void disp_vec_options(const char *vecname, arglist_t *ap); +double waypt_time(const waypoint* wpt); +double waypt_speed(const waypoint* A, const waypoint* B); +double waypt_speed_ex(const waypoint* A, const waypoint* B); +double waypt_course(const waypoint* A, const waypoint* B); +double waypt_distance(const waypoint* A, const waypoint* B); +double waypt_distance_ex(const waypoint* A, const waypoint* B); + +NORETURN fatal(const char*, ...) PRINTFLIKE(1, 2); +void is_fatal(const int condition, const char*, ...) PRINTFLIKE(2, 3); +void warning(const char*, ...) PRINTFLIKE(1, 2); + +ff_vecs_t* find_vec(char* const, char**); +void assign_option(const char* vecname, arglist_t* ap, const char* val); +void disp_vec_options(const char* vecname, arglist_t* ap); void disp_vecs(void); -void disp_vec( const char *vecname ); +void disp_vec(const char* vecname); void init_vecs(void); void exit_vecs(void); void disp_formats(int version); -const char * name_option(long type); +const char* name_option(long type); void printposn(const double c, int is_lat); #ifndef DEBUG_MEM -void *xcalloc(size_t nmemb, size_t size); -void *xmalloc(size_t size); -void *xrealloc(void *p, size_t s); -void xfree(void *mem); -char *xstrdup(const char *s); -char *xstrndup(const char *s, size_t n); -char *xstrndupt(const char *s, size_t n); -char *xstrappend(char *src, const char *addon); +void* xcalloc(size_t nmemb, size_t size); +void* xmalloc(size_t size); +void* xrealloc(void* p, size_t s); +void xfree(void* mem); +char* xstrdup(const char* s); +char* xstrndup(const char* s, size_t n); +char* xstrndupt(const char* s, size_t n); +char* xstrappend(char* src, const char* addon); #define xxcalloc(nmemb, size, file, line) xcalloc(nmemb, size) #define xxmalloc(size, file, line) xmalloc(size) #define xxrealloc(p, s, file, line) xrealloc(p,s) @@ -813,16 +835,16 @@ char *xstrappend(char *src, const char *addon); #define xxstrdup(s, file, line) xstrdup(s) #define xxstrappend(src, addon, file, line) xstrappend(src, addon) #else /* DEBUG_MEM */ -void *XCALLOC(size_t nmemb, size_t size, DEBUG_PARAMS ); -void *XMALLOC(size_t size, DEBUG_PARAMS ); -void *XREALLOC(void *p, size_t s, DEBUG_PARAMS ); -void XFREE(void *mem, DEBUG_PARAMS ); -char *XSTRDUP(const char *s, DEBUG_PARAMS ); -char *XSTRNDUP(const char *src, size_t size, DEBUG_PARAMS ); -char *XSTRNDUPT(const char *src, size_t size, DEBUG_PARAMS ); -char *XSTRAPPEND(char *src, const char *addon, DEBUG_PARAMS ); +void* XCALLOC(size_t nmemb, size_t size, DEBUG_PARAMS); +void* XMALLOC(size_t size, DEBUG_PARAMS); +void* XREALLOC(void* p, size_t s, DEBUG_PARAMS); +void XFREE(void* mem, DEBUG_PARAMS); +char* XSTRDUP(const char* s, DEBUG_PARAMS); +char* XSTRNDUP(const char* src, size_t size, DEBUG_PARAMS); +char* XSTRNDUPT(const char* src, size_t size, DEBUG_PARAMS); +char* XSTRAPPEND(char* src, const char* addon, DEBUG_PARAMS); void debug_mem_open(); -void debug_mem_output( char *format, ... ); +void debug_mem_output(char* format, ...); void debug_mem_close(); #define xcalloc(nmemb, size) XCALLOC(nmemb, size, __FILE__, __LINE__) #define xmalloc(size) XMALLOC(size, __FILE__, __LINE__) @@ -841,45 +863,45 @@ void debug_mem_close(); #define xxstrappend XSTRAPPEND #endif /* DEBUG_MEM */ -FILE *xfopen(const char *fname, const char *type, const char *errtxt); -void xfprintf(const char *errtxt, FILE *stream, const char *format, ...); -void xfputs(const char *errtxt, const char *s, FILE *stream); - -int case_ignore_strcmp(const char *s1, const char *s2); -int case_ignore_strncmp(const char *s1, const char *s2, int n); -int str_match(const char *str, const char *match); -int case_ignore_str_match(const char *str, const char *match); -char * strenquote(const char *str, const char quot_char); - -char *strsub(const char *s, const char *search, const char *replace); -char *gstrsub(const char *s, const char *search, const char *replace); -char *xstrrstr(const char *s1, const char *s2); -void rtrim(char *s); -char * lrtrim(char *s); -int xasprintf(char **strp, const char *fmt, ...); -int xvasprintf(char **strp, const char *fmt, va_list ap); -char *strupper(char *src); -char *strlower(char *src); +FILE* xfopen(const char* fname, const char* type, const char* errtxt); +void xfprintf(const char* errtxt, FILE* stream, const char* format, ...); +void xfputs(const char* errtxt, const char* s, FILE* stream); + +int case_ignore_strcmp(const char* s1, const char* s2); +int case_ignore_strncmp(const char* s1, const char* s2, int n); +int str_match(const char* str, const char* match); +int case_ignore_str_match(const char* str, const char* match); +char* strenquote(const char* str, const char quot_char); + +char* strsub(const char* s, const char* search, const char* replace); +char* gstrsub(const char* s, const char* search, const char* replace); +char* xstrrstr(const char* s1, const char* s2); +void rtrim(char* s); +char* lrtrim(char* s); +int xasprintf(char** strp, const char* fmt, ...) PRINTFLIKE(2, 3); +int xvasprintf(char** strp, const char* fmt, va_list ap); +char* strupper(char* src); +char* strlower(char* src); signed int get_tz_offset(void); -time_t mklocaltime(struct tm *t); -time_t mkgmtime(struct tm *t); +time_t mklocaltime(struct tm* t); +time_t mkgmtime(struct tm* t); time_t current_time(void); -void dotnet_time_to_time_t(double dotnet, time_t *t, int *ms); -signed int month_lookup(const char *m); -const char *get_cache_icon(const waypoint *waypointp); -const char *gs_get_cachetype(geocache_type t); -const char *gs_get_container(geocache_container t); -char * xml_entitize(const char * str); -char * html_entitize(const char * str); -char * strip_html(const utf_string*); -char * strip_nastyhtml(const char * in); -char * convert_human_date_format(const char *human_datef); /* "MM,YYYY,DD" -> "%m,%Y,%d" */ -char * convert_human_time_format(const char *human_timef); /* "HH+mm+ss" -> "%H+%M+%S" */ -char * pretty_deg_format(double lat, double lon, char fmt, const char *sep, int html); /* decimal -> dd.dddd or dd mm.mmm or dd mm ss */ - -char * get_filename(const char *fname); /* extract the filename portion */ - -/* +void dotnet_time_to_time_t(double dotnet, time_t* t, int* ms); +signed int month_lookup(const char* m); +const char* get_cache_icon(const waypoint* waypointp); +const char* gs_get_cachetype(geocache_type t); +const char* gs_get_container(geocache_container t); +char* xml_entitize(const char* str); +char* html_entitize(const char* str); +char* strip_html(const utf_string*); +char* strip_nastyhtml(const char* in); +char* convert_human_date_format(const char* human_datef); /* "MM,YYYY,DD" -> "%m,%Y,%d" */ +char* convert_human_time_format(const char* human_timef); /* "HH+mm+ss" -> "%H+%M+%S" */ +char* pretty_deg_format(double lat, double lon, char fmt, const char* sep, int html); /* decimal -> dd.dddd or dd mm.mmm or dd mm ss */ + +char* get_filename(const char* fname); /* extract the filename portion */ + +/* * Character encoding transformations. */ @@ -890,78 +912,78 @@ char * get_filename(const char *fname); /* extract the filename portion */ #define CET_CHARSET_MS_ANSI "MS-ANSI" #define CET_CHARSET_LATIN1 "ISO-8859-1" -#define str_utf8_to_cp1252(str) cet_str_utf8_to_cp1252((str)) +#define str_utf8_to_cp1252(str) cet_str_utf8_to_cp1252((str)) #define str_cp1252_to_utf8(str) cet_str_cp1252_to_utf8((str)) -#define str_utf8_to_iso8859_1(str) cet_str_utf8_to_iso8859_1((str)) +#define str_utf8_to_iso8859_1(str) cet_str_utf8_to_iso8859_1((str)) #define str_iso8859_1_to_utf8(str) cet_str_iso8859_1_to_utf8((str)) /* this lives in gpx.c */ -time_t xml_parse_time( const char *cdatastr, int * microsecs ); - -xml_tag *xml_findfirst( xml_tag *root, const char *tagname ); -xml_tag *xml_findnext( xml_tag *root, xml_tag *cur, const char *tagname ); -char *xml_attribute( xml_tag *tag, const char *attrname ); +time_t xml_parse_time(const char* cdatastr, int* microsecs); + +xml_tag* xml_findfirst(xml_tag* root, const char* tagname); +xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const char* tagname); +char* xml_attribute(xml_tag* tag, const char* attrname); -char * rot13( const char *str ); +char* rot13(const char* str); /* * PalmOS records like fixed-point numbers, which should be rounded * to deal with possible floating-point representation errors. */ -signed int si_round( double d ); +signed int si_round(double d); -/* +/* * Data types for Palm/OS files. */ typedef struct { - unsigned char data[4]; + unsigned char data[4]; } pdb_32; typedef struct { - unsigned char data[2]; + unsigned char data[2]; } pdb_16; typedef struct { - unsigned char data[8]; + unsigned char data[8]; } pdb_double; typedef struct { - unsigned char data[4]; + unsigned char data[4]; } pdb_float; /* * Protypes for Endianness helpers. */ -signed int be_read16(const void *p); -unsigned int be_readu16(const void *p); -signed int be_read32(const void *p); -signed int le_read16(const void *p); -unsigned int le_readu16(const void *p); -signed int le_read32(const void *p); -unsigned int le_readu32(const void *p); -void le_read64(void *dest, const void *src); -void be_write16(void *pp, const unsigned i); -void be_write32(void *pp, const unsigned i); -void le_write16(void *pp, const unsigned i); -void le_write32(void *pp, const unsigned i); +signed int be_read16(const void* p); +unsigned int be_readu16(const void* p); +signed int be_read32(const void* p); +signed int le_read16(const void* p); +unsigned int le_readu16(const void* p); +signed int le_read32(const void* p); +unsigned int le_readu32(const void* p); +void le_read64(void* dest, const void* src); +void be_write16(void* pp, const unsigned i); +void be_write32(void* pp, const unsigned i); +void le_write16(void* pp, const unsigned i); +void le_write32(void* pp, const unsigned i); double endian_read_double(const void* ptr, int read_le); float endian_read_float(const void* ptr, int read_le); void endian_write_double(void* ptr, double d, int write_le); void endian_write_float(void* ptr, float f, int write_le); -float be_read_float(void *p); -double be_read_double(void *p); -void be_write_float(void *pp, float d); -void be_write_double(void *pp, double d); +float be_read_float(void* p); +double be_read_double(void* p); +void be_write_float(void* pp, float d); +void be_write_double(void* pp, double d); -float le_read_float(const void *p); -double le_read_double(const void *p); -void le_write_float(void *ptr, float f); -void le_write_double(void *p, double d); +float le_read_float(const void* p); +double le_read_double(const void* p); +void le_write_float(void* ptr, float f); +void le_write_double(void* p, double d); #define pdb_write_float be_write_float #define pdb_read_float be_read_float @@ -976,13 +998,13 @@ double ddmm2degrees(double ddmm_val); double degrees2ddmm(double deg_val); typedef enum { - grid_unknown = -1, - grid_lat_lon_ddd = 0, - grid_lat_lon_dmm = 1, - grid_lat_lon_dms = 2, - grid_bng = 3, - grid_utm = 4, - grid_swiss = 5 + grid_unknown = -1, + grid_lat_lon_ddd = 0, + grid_lat_lon_dmm = 1, + grid_lat_lon_dms = 2, + grid_bng = 3, + grid_utm = 4, + grid_swiss = 5 } grid_type; #define GRID_INDEX_MIN grid_lat_lon_ddd @@ -993,40 +1015,42 @@ typedef enum { /* bit manipulation functions (util.c) */ -char gb_getbit(const void *buf, const gbuint32 nr); -void gb_setbit(void *buf, const gbuint32 nr); +char gb_getbit(const void* buf, const gbuint32 nr); +void gb_setbit(void* buf, const gbuint32 nr); -void *gb_int2ptr(const int i); -int gb_ptr2int(const void *p); +void* gb_int2ptr(const int i); +int gb_ptr2int(const void* p); /* * From parse.c */ -int parse_coordinates(const char *str, int datum, const grid_type grid, - double *latitude, double *longitude, const char *module); -int parse_distance(const char *str, double *val, double scale, const char *module); -int parse_speed(const char *str, double *val, const double scale, const char *module); -time_t parse_date(const char *str, const char *format, const char *module); +int parse_coordinates(const char* str, int datum, const grid_type grid, + double* latitude, double* longitude, const char* module); +int parse_distance(const char* str, double* val, double scale, const char* module); +int parse_speed(const char* str, double* val, const double scale, const char* module); +time_t parse_date(const char* str, const char* format, const char* module); /* * From util_crc.c */ -unsigned long get_crc32(const void * data, int datalen); -unsigned long get_crc32_s(const void * data); +unsigned long get_crc32(const void* data, int datalen); +unsigned long get_crc32_s(const void* data); /* * From units.c */ typedef enum { - units_unknown = 0, - units_statute = 1, - units_metric = 2, - units_nautical =3 + units_unknown = 0, + units_statute = 1, + units_metric = 2, + units_nautical =3, + units_aviation =4 } fmt_units; int fmt_setunits(fmt_units); -double fmt_distance(const double, char **tag); -double fmt_speed(const double, char **tag); +double fmt_distance(const double, char** tag); +double fmt_altitude(const double, char** tag); +double fmt_speed(const double, char** tag); /* * From gbsleep.c @@ -1036,12 +1060,12 @@ void gb_sleep(unsigned long microseconds); /* * From nmea.c */ -int nmea_cksum(const char *const buf); +int nmea_cksum(const char* const buf); /* * Color helpers. */ -int color_to_bbggrr(const char *cname); +int color_to_bbggrr(const char* cname); /* * A constant for unknown altitude. It's tempting to just use zero diff --git a/gpsbabel/delbin.c b/gpsbabel/delbin.c index 34b92d97d..16f6d4d9b 100644 --- a/gpsbabel/delbin.c +++ b/gpsbabel/delbin.c @@ -60,10 +60,10 @@ added in the PN-40 2.5 firmware. //----------------------------------------------------------------------------- // interface to platform-specific device I/O typedef struct { - void (*init)(const char* name); - void (*deinit)(void); - unsigned (*packet_read)(void*); - unsigned (*packet_write)(const void*, unsigned); + void (*init)(const char* name); + void (*deinit)(void); + unsigned(*packet_read)(void*); + unsigned(*packet_write)(const void*, unsigned); } delbin_os_ops_t; // really static, only extern so it can be forward declared @@ -87,9 +87,9 @@ static unsigned delbin_os_packet_size; // Multiple unit support. #define DELBIN_MAX_UNITS 32 static struct { - unsigned int unit_number; - const char *unit_serial_number; - const char *unit_name; + unsigned int unit_number; + const char* unit_serial_number; + const char* unit_name; } delbin_unit_info[DELBIN_MAX_UNITS]; static int n_delbin_units; @@ -97,33 +97,45 @@ static int n_delbin_units; #define sizeofarray(x) (sizeof(x) / sizeof(x[0])) -static char *opt_getposn = NULL; -static char *opt_logs = NULL; -static char *opt_long_notes = NULL; -static char *opt_nuke_wpt = NULL; -static char *opt_nuke_trk = NULL; -static char *opt_nuke_rte = NULL; +static char* opt_getposn = NULL; +static char* opt_logs = NULL; +static char* opt_long_notes = NULL; +static char* opt_nuke_wpt = NULL; +static char* opt_nuke_trk = NULL; +static char* opt_nuke_rte = NULL; /* If true, Order hint to match Cache Register and Topo 7 */ -static char *opt_hint_at_end = NULL; -static char *opt_gcsym = NULL; +static char* opt_hint_at_end = NULL; +static char* opt_gcsym = NULL; static arglist_t delbin_args[] = { - { "get_posn", &opt_getposn, "Return current position as a waypoint", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logs", &opt_logs, "Include groundspeak logs when writing", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "long_notes", &opt_long_notes, "Use long waypoint notes regardless of PN version", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"nukewpt", &opt_nuke_wpt, "Delete all waypoints before sending", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - {"nuketrk", &opt_nuke_trk, "Delete all tracks before sending", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - {"nukerte", &opt_nuke_rte, "Delete all waypoints before sending", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - {"hint_at_end", &opt_hint_at_end, "If true, geocache hint at end of text", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"gcsym", &opt_gcsym, "If set to 0, prefer user-provided symbols over Groundspeaks ones for geocaches", NULL, ARGTYPE_BOOL, ARG_NOMINMAX, "1" }, - ARG_TERMINATOR + { + "get_posn", &opt_getposn, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logs", &opt_logs, "Include groundspeak logs when writing", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "long_notes", &opt_long_notes, "Use long waypoint notes regardless of PN version", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "nukewpt", &opt_nuke_wpt, "Delete all waypoints before sending", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nuketrk", &opt_nuke_trk, "Delete all tracks before sending", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nukerte", &opt_nuke_rte, "Delete all routes before sending", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + {"hint_at_end", &opt_hint_at_end, "If true, geocache hint at end of text", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gcsym", &opt_gcsym, "If set to 0, prefer user-provided symbols over Groundspeaks ones for geocaches", NULL, ARGTYPE_BOOL, ARG_NOMINMAX, "1" }, + ARG_TERMINATOR }; // Whether device understands message 0xb016 @@ -209,10 +221,10 @@ typedef enum { } nuke_dest; typedef struct { - gbuint8 type; - gbuint8 mode; - gbuint8 location; - char object_name[64]; + gbuint8 type; + gbuint8 mode; + gbuint8 location; + char object_name[64]; } msg_delete_t; // Output Waypoint Message @@ -220,23 +232,23 @@ typedef struct { // Input Waypoint Message // Message ID: 0xB014 typedef struct { - gbuint8 total[4]; // U32 - gbuint8 index[4]; // U32 - gbuint8 year; - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 latitude[4]; // S32 rad * 100000000 - gbuint8 longitude[4]; // S32 rad * 100000000 - gbuint8 elevation[4]; // F32 meters - gbuint8 color; - gbuint8 symbol; - gbuint8 name_size; - char name[1]; - // note_size[2] U16 - // note[note_size] + gbuint8 total[4]; // U32 + gbuint8 index[4]; // U32 + gbuint8 year; + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 latitude[4]; // S32 rad * 100000000 + gbuint8 longitude[4]; // S32 rad * 100000000 + gbuint8 elevation[4]; // F32 meters + gbuint8 color; + gbuint8 symbol; + gbuint8 name_size; + char name[1]; + // note_size[2] U16 + // note[note_size] } msg_waypoint_t; // undocumented, seen with PN-40 2.5 firmware @@ -245,12 +257,12 @@ typedef struct { // input waypoint note // Message ID: 0xB016 typedef struct { - gbuint8 index[2]; - gbuint8 total[2]; - gbuint8 name_size; - char name[1]; - // note_size[2] - // note[note_size] + gbuint8 index[2]; + gbuint8 total[2]; + gbuint8 name_size; + char name[1]; + // note_size[2] + // note[note_size] } msg_waypoint_note_t; // Output Track Point Message @@ -258,72 +270,72 @@ typedef struct { // Input Track Point Message // Message ID: 0xB036 typedef struct { - gbuint8 total[4]; // U32 - gbuint8 index[4]; // U32 - gbuint8 number; - struct { - gbuint8 year; - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 latitude[4]; // S32 rad * 100000000 - gbuint8 longitude[4]; // S32 rad * 100000000 - gbuint8 elevation[4]; // F32 meters - gbuint8 speed[2]; // U16 km/h * 10 - gbuint8 heading[2]; // U16 deg * 100 - gbuint8 status; - } point[1]; + gbuint8 total[4]; // U32 + gbuint8 index[4]; // U32 + gbuint8 number; + struct { + gbuint8 year; + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 latitude[4]; // S32 rad * 100000000 + gbuint8 longitude[4]; // S32 rad * 100000000 + gbuint8 elevation[4]; // F32 meters + gbuint8 speed[2]; // U16 km/h * 10 + gbuint8 heading[2]; // U16 deg * 100 + gbuint8 status; + } point[1]; } msg_track_point_t; // Output Track Header (Name) Message // Message ID: 0xB032 typedef struct { - gbuint8 total_tracks[2]; // U16 - gbuint8 number[2]; // U16 - char name[32]; - gbuint8 total_points[4]; // U32 - gbuint8 year; - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 color[2]; // U16 - gbuint8 distance[4]; // U32 m - gbuint8 duration[4]; // U32 sec - gbuint8 comment_size[2]; // U16 - char comment[1]; + gbuint8 total_tracks[2]; // U16 + gbuint8 number[2]; // U16 + char name[32]; + gbuint8 total_points[4]; // U32 + gbuint8 year; + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 color[2]; // U16 + gbuint8 distance[4]; // U32 m + gbuint8 duration[4]; // U32 sec + gbuint8 comment_size[2]; // U16 + char comment[1]; } msg_track_header_t; // Input Upload Track Header Message // Message ID: 0xB035 typedef struct { - char name[32]; - gbuint8 total_points[4]; // U32 - gbuint8 year; - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 color[2]; // U16 - gbuint8 comment_size[2]; // U16 - char comment[1]; + char name[32]; + gbuint8 total_points[4]; // U32 + gbuint8 year; + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 color[2]; // U16 + gbuint8 comment_size[2]; // U16 + char comment[1]; } msg_track_header_in_t; // Output Route Shape Message // Message ID: 0xB054 typedef struct { - gbuint8 total[4]; // U32 - gbuint8 index[4]; // U32 - gbuint8 number; - gbuint8 reserved; - struct { - gbuint8 latitude[4]; // S32 rad * 100000000 - gbuint8 longitude[4]; // S32 rad * 100000000 - } point[1]; + gbuint8 total[4]; // U32 + gbuint8 index[4]; // U32 + gbuint8 number; + gbuint8 reserved; + struct { + gbuint8 latitude[4]; // S32 rad * 100000000 + gbuint8 longitude[4]; // S32 rad * 100000000 + } point[1]; } msg_route_shape_t; // Output Route Point Message @@ -331,142 +343,142 @@ typedef struct { // Input Route Itin Point Message // Message ID: 0xB056 typedef struct { - gbuint8 total[4]; // U32 - gbuint8 index[4]; // U32 - char name[32]; - gbuint8 latitude[4]; // S32 rad * 100000000 - gbuint8 longitude[4]; // S32 rad * 100000000 - gbuint8 time_from_start[4]; // U32 sec - gbuint8 distance_from_start[4]; // F32 km - gbuint8 bearing_in[2]; // U16 deg * 100 - gbuint8 bearing_out[2]; // U16 deg * 100 - gbuint8 bearing_next[2]; // U16 deg * 100 - gbuint8 itinerary_type; - gbuint8 turn_type; - gbuint8 road_class[2]; // U16 - gbuint8 feature_code[4]; // U32 - gbuint8 exit_label_size; - char exit_label[1]; - // comment_size U8 - // comment[comment_size] - // shape_pt_count U32 + gbuint8 total[4]; // U32 + gbuint8 index[4]; // U32 + char name[32]; + gbuint8 latitude[4]; // S32 rad * 100000000 + gbuint8 longitude[4]; // S32 rad * 100000000 + gbuint8 time_from_start[4]; // U32 sec + gbuint8 distance_from_start[4]; // F32 km + gbuint8 bearing_in[2]; // U16 deg * 100 + gbuint8 bearing_out[2]; // U16 deg * 100 + gbuint8 bearing_next[2]; // U16 deg * 100 + gbuint8 itinerary_type; + gbuint8 turn_type; + gbuint8 road_class[2]; // U16 + gbuint8 feature_code[4]; // U32 + gbuint8 exit_label_size; + char exit_label[1]; + // comment_size U8 + // comment[comment_size] + // shape_pt_count U32 } msg_route_point_t; // Output Route Header (Name) Message // Message ID: 0xB052 typedef struct { - gbuint8 total[2]; // U16 - gbuint8 index[2]; // U16 - char name[64]; - gbuint8 type; - gbuint8 total_route_point[4]; // U32 - gbuint8 total_shape_point[4]; // U32 + gbuint8 total[2]; // U16 + gbuint8 index[2]; // U16 + char name[64]; + gbuint8 type; + gbuint8 total_route_point[4]; // U32 + gbuint8 total_shape_point[4]; // U32 } msg_route_header_t; // Input Upload Route Header Message // Message ID: 0xB055 typedef struct { - char name[64]; - gbuint8 type; - gbuint8 total_route_point[4]; // U32 - gbuint8 total_shape_point[4]; // U32 + char name[64]; + gbuint8 type; + gbuint8 total_route_point[4]; // U32 + gbuint8 total_shape_point[4]; // U32 } msg_route_header_in_t; // Output Navigation Message // Message ID: 0xA010 typedef struct { - gbuint8 gps_week[2]; // U16 - gbuint8 time_of_week[8]; // D64 sec - gbuint8 year[2]; // U16 - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 satellites; - gbuint8 latitude[8]; // D64 deg - gbuint8 longitude[8]; // D64 deg - gbuint8 elevation[8]; // D64 meters - gbuint8 geoid_offset[2]; // S16 meters * 10 - gbuint8 speed[4]; // F32 km/h - gbuint8 heading[2]; // U16 deg * 100 - gbuint8 magnetic_variation[2]; // S16 deg * 100 - gbuint8 fix_status; + gbuint8 gps_week[2]; // U16 + gbuint8 time_of_week[8]; // D64 sec + gbuint8 year[2]; // U16 + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 satellites; + gbuint8 latitude[8]; // D64 deg + gbuint8 longitude[8]; // D64 deg + gbuint8 elevation[8]; // D64 meters + gbuint8 geoid_offset[2]; // S16 meters * 10 + gbuint8 speed[4]; // F32 km/h + gbuint8 heading[2]; // U16 deg * 100 + gbuint8 magnetic_variation[2]; // S16 deg * 100 + gbuint8 fix_status; } msg_navigation_t; // Output Satellite Info Message // Message ID: 0xA020 typedef struct { - gbuint8 gps_week[2]; // U16 - gbuint8 time_of_week[8]; // D64 sec - gbuint8 hdop[2]; // U16 - gbuint8 vdop[2]; // U16 - gbuint8 pdop[2]; // U16 - gbuint8 number; - struct { - gbuint8 prn; - gbuint8 azimuth[2]; // S16 deg? * 100 - gbuint8 elevation[2]; // S16 deg? * 100 - gbuint8 Cn0[2]; // U16 snr * 100 - gbuint8 status; - } sat[1]; + gbuint8 gps_week[2]; // U16 + gbuint8 time_of_week[8]; // D64 sec + gbuint8 hdop[2]; // U16 + gbuint8 vdop[2]; // U16 + gbuint8 pdop[2]; // U16 + gbuint8 number; + struct { + gbuint8 prn; + gbuint8 azimuth[2]; // S16 deg? * 100 + gbuint8 elevation[2]; // S16 deg? * 100 + gbuint8 Cn0[2]; // U16 snr * 100 + gbuint8 status; + } sat[1]; } msg_satellite_t; // Output Version Message // Message ID: 0xA001 typedef struct { - gbuint8 firmware_version[4]; - char company[32]; - char product[32]; - char firmware[32]; - char gps_firmware[48]; - char serial[16]; - char extra[16]; + gbuint8 firmware_version[4]; + char company[32]; + char product[32]; + char firmware[32]; + char gps_firmware[48]; + char serial[16]; + char extra[16]; } msg_version_t; // Output Device Capabilities Message // Message ID: 0xB001 typedef struct { - gbuint8 max_waypoints[4]; // U32 - gbuint8 max_tracks[2]; // U16 - gbuint8 max_track_points[4]; // U32 - gbuint8 max_routes[2]; // U16 - gbuint8 max_route_points[4]; // U32 - gbuint8 max_route_shape_points[4]; // U32 - gbuint8 max_maps[2]; // U16 - gbuint8 min_map_version[2]; // U16 - gbuint8 max_map_version[2]; // U16 - gbuint8 total_internal_file_memory[4]; // U32 - gbuint8 avail_internal_file_memory[4]; // U32 - gbuint8 total_external_file_memory[4]; // U32 - gbuint8 avail_external_file_memory[4]; // U32 + gbuint8 max_waypoints[4]; // U32 + gbuint8 max_tracks[2]; // U16 + gbuint8 max_track_points[4]; // U32 + gbuint8 max_routes[2]; // U16 + gbuint8 max_route_points[4]; // U32 + gbuint8 max_route_shape_points[4]; // U32 + gbuint8 max_maps[2]; // U16 + gbuint8 min_map_version[2]; // U16 + gbuint8 max_map_version[2]; // U16 + gbuint8 total_internal_file_memory[4]; // U32 + gbuint8 avail_internal_file_memory[4]; // U32 + gbuint8 total_external_file_memory[4]; // U32 + gbuint8 avail_external_file_memory[4]; // U32 } msg_capabilities_t; //----------------------------------------------------------------------------- #if __APPLE__ || __linux - #include +#include #endif static void debug_out(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - fputs(MYNAME ": ", stderr); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + fputs(MYNAME ": ", stderr); + vfprintf(stderr, fmt, ap); + va_end(ap); } static void debug_out_time(const char* s) { #if __APPLE__ || __linux - struct timeval tv; - gettimeofday(&tv, NULL); - debug_out("%u.%03u %s", (unsigned)tv.tv_sec & 0xf, (unsigned)tv.tv_usec / 1000, s); + struct timeval tv; + gettimeofday(&tv, NULL); + debug_out("%u.%03u %s", (unsigned)tv.tv_sec & 0xf, (unsigned)tv.tv_usec / 1000, s); #else - debug_out("%u %s", (unsigned)time(NULL) & 0xf, s); + debug_out("%u %s", (unsigned)time(NULL) & 0xf, s); #endif } @@ -475,16 +487,16 @@ debug_out_time(const char* s) static gbuint16 checksum(const gbuint8* p, unsigned n) { - int x = 0; - unsigned i; - for (i = n / 2; i > 0; i--) { - x += *p++; - x += *p++ << 8; - } - if (n & 1) { - x += *p; - } - return (gbuint16)-x; + int x = 0; + unsigned i; + for (i = n / 2; i > 0; i--) { + x += *p++; + x += *p++ << 8; + } + if (n & 1) { + x += *p; + } + return (gbuint16)-x; } //----------------------------------------------------------------------------- @@ -493,111 +505,111 @@ checksum(const gbuint8* p, unsigned n) static unsigned packet_read(void* buf) { - unsigned n = delbin_os_ops.packet_read(buf); - if (n == 0) { - fatal(MYNAME ": read 0\n"); - } - if (global_opts.debug_level >= DBGLVL_H) { - unsigned j; - const gbuint8* p = buf; - - debug_out_time("pcktrd"); - for (j = 0; j < n; j++) { - warning(" %02x", p[j]); - } - if (global_opts.debug_level >= DBGLVL_H2) { - warning(" "); - for (j = 0; j < n; j++) { - int c = p[j]; - warning("%c", isprint(c) ? c : '.'); - } - } - warning("\n"); - } - return n; + unsigned n = delbin_os_ops.packet_read(buf); + if (n == 0) { + fatal(MYNAME ": read 0\n"); + } + if (global_opts.debug_level >= DBGLVL_H) { + unsigned j; + const gbuint8* p = (const gbuint8*) buf; + + debug_out_time("pcktrd"); + for (j = 0; j < n; j++) { + warning(" %02x", p[j]); + } + if (global_opts.debug_level >= DBGLVL_H2) { + warning(" "); + for (j = 0; j < n; j++) { + int c = p[j]; + warning("%c", isprint(c) ? c : '.'); + } + } + warning("\n"); + } + return n; } static void packet_write(const void* buf, unsigned size) { - unsigned n; - if (global_opts.debug_level >= DBGLVL_H) { - unsigned j; - const gbuint8* p = buf; - - debug_out_time("pcktwr"); - for (j = 0; j < size; j++) { - warning(" %02x", p[j]); - } - if (global_opts.debug_level >= DBGLVL_H2) { - warning(" "); - for (j = 0; j < size; j++) { - int c = p[j]; - warning("%c", isprint(c) ? c : '.'); - } - } - warning("\n"); - } - n = delbin_os_ops.packet_write(buf, size); - if (n != size) { - fatal(MYNAME ": short write %u %u\n", size, n); - } + unsigned n; + if (global_opts.debug_level >= DBGLVL_H) { + unsigned j; + const gbuint8* p = (const gbuint8*) buf; + + debug_out_time("pcktwr"); + for (j = 0; j < size; j++) { + warning(" %02x", p[j]); + } + if (global_opts.debug_level >= DBGLVL_H2) { + warning(" "); + for (j = 0; j < size; j++) { + int c = p[j]; + warning("%c", isprint(c) ? c : '.'); + } + } + warning("\n"); + } + n = delbin_os_ops.packet_write(buf, size); + if (n != size) { + fatal(MYNAME ": short write %u %u\n", size, n); + } } //----------------------------------------------------------------------------- // dynamically sized buffer with space reserved for message header and trailer typedef struct { - // message data size - unsigned size; - // buffer size - unsigned capacity; - gbuint8* buf; - // convenience pointer to message data area - void* data; + // message data size + unsigned size; + // buffer size + unsigned capacity; + gbuint8* buf; + // convenience pointer to message data area + void* data; } message_t; static void message_init(message_t* m) { - m->capacity = 100; - m->buf = xmalloc(m->capacity); - m->data = m->buf + 2 + 8; + m->capacity = 100; + m->buf = (gbuint8*)xmalloc(m->capacity); + m->data = m->buf + 2 + 8; } static void message_init_size(message_t* m, unsigned size) { - m->size = size; - m->capacity = 2 + 8 + size + 4; - m->buf = xmalloc(m->capacity); - m->data = m->buf + 2 + 8; + m->size = size; + m->capacity = 2 + 8 + size + 4; + m->buf = (gbuint8*)xmalloc(m->capacity); + m->data = m->buf + 2 + 8; } static void message_free(message_t* m) { - xfree(m->buf); - m->buf = NULL; - m->data = NULL; + xfree(m->buf); + m->buf = NULL; + m->data = NULL; } static void message_ensure_size(message_t* m, unsigned size) { - m->size = size; - if (m->capacity < 2 + 8 + size + 4) { - m->capacity = 2 + 8 + size + 4; - xfree(m->buf); - m->buf = xmalloc(m->capacity); - m->data = m->buf + 2 + 8; - } + m->size = size; + if (m->capacity < 2 + 8 + size + 4) { + m->capacity = 2 + 8 + size + 4; + xfree(m->buf); + m->buf = (gbuint8*)xmalloc(m->capacity); + m->data = m->buf + 2 + 8; + } } static unsigned message_get_id(const message_t* m) { - return le_readu16(m->buf + 4); + return le_readu16(m->buf + 4); } //----------------------------------------------------------------------------- @@ -605,85 +617,86 @@ message_get_id(const message_t* m) static void message_write(unsigned msg_id, message_t* m) { - unsigned chksum; - unsigned count; - unsigned n; - gbuint8* p = m->buf; - - // header (2 start bytes filled in later) - p[2] = 0xdb; - p[3] = 0xfe; - le_write16(p + 4, msg_id); - // "data size" includes 4 trailer bytes - le_write16(p + 6, m->size + 4); - chksum = checksum(p + 2, 6); - le_write16(p + 8, chksum); - // message data (filled in by caller) - chksum = checksum(m->data, m->size); - n = 2 + 8 + m->size; - // trailer (checksum and marker bytes) - le_write16(p + n, chksum); - p[n + 2] = 0xad; - p[n + 3] = 0xbc; - // size of message not counting packet start bytes - count = 8 + m->size + 4; - do { - const gbuint8 save0 = p[0]; - const gbuint8 save1 = p[1]; - n = delbin_os_packet_size - 2; - if (n > count) { - n = count; - } - // doc. says 0x20, device sends 0, probably ignored - p[0] = 0x20; - // valid bytes in packet after first 2 - p[1] = n; - packet_write(p, 2 + n); - p[0] = save0; - p[1] = save1; - p += n; - count -= n; - } while (count != 0); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": sent %x\n", msg_id); + unsigned chksum; + unsigned count; + unsigned n; + gbuint8* p = m->buf; + + // header (2 start bytes filled in later) + p[2] = 0xdb; + p[3] = 0xfe; + le_write16(p + 4, msg_id); + // "data size" includes 4 trailer bytes + le_write16(p + 6, m->size + 4); + chksum = checksum(p + 2, 6); + le_write16(p + 8, chksum); + // message data (filled in by caller) + chksum = checksum((gbuint8*) m->data, m->size); + n = 2 + 8 + m->size; + // trailer (checksum and marker bytes) + le_write16(p + n, chksum); + p[n + 2] = 0xad; + p[n + 3] = 0xbc; + // size of message not counting packet start bytes + count = 8 + m->size + 4; + do { + const gbuint8 save0 = p[0]; + const gbuint8 save1 = p[1]; + n = delbin_os_packet_size - 2; + if (n > count) { + n = count; + } + // doc. says 0x20, device sends 0, probably ignored + p[0] = 0x20; + // valid bytes in packet after first 2 + p[1] = n; + packet_write(p, 2 + n); + p[0] = save0; + p[1] = save1; + p += n; + count -= n; + } while (count != 0); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": sent %x\n", msg_id); + } } // read from the payload of a single packet static unsigned read_depacketize_1(gbuint8** p, unsigned n, int new_packet) { - static gbuint8 buf[256]; - static unsigned buf_i, buf_n; - if (new_packet) { - buf_n = 0; - } - while (buf_n == 0) { - packet_read(buf); - if (buf[1] <= delbin_os_packet_size - 2) { - buf_n = buf[1]; - buf_i = 2; - } - } - *p = buf + buf_i; - if (n > buf_n) { - n = buf_n; - } - buf_n -= n; - buf_i += n; - return n; + static gbuint8 buf[256]; + static unsigned buf_i, buf_n; + if (new_packet) { + buf_n = 0; + } + while (buf_n == 0) { + packet_read(buf); + if (buf[1] <= delbin_os_packet_size - 2) { + buf_n = buf[1]; + buf_i = 2; + } + } + *p = buf + buf_i; + if (n > buf_n) { + n = buf_n; + } + buf_n -= n; + buf_i += n; + return n; } // read from packet payloads until request is fulfilled static void read_depacketize(gbuint8* buf, unsigned n) { - while (n) { - gbuint8* p; - unsigned nn = read_depacketize_1(&p, n, FALSE); - memcpy(buf, p, nn); - n -= nn; - buf += nn; - } + while (n) { + gbuint8* p; + unsigned nn = read_depacketize_1(&p, n, FALSE); + memcpy(buf, p, nn); + n -= nn; + buf += nn; + } } // Get one valid message. @@ -691,71 +704,72 @@ read_depacketize(gbuint8* buf, unsigned n) static unsigned message_read_1(unsigned msg_id, message_t* m) { - unsigned id; - for (;;) { - unsigned total; - unsigned n; - gbuint8 buf[8]; - gbuint8* p; - - n = read_depacketize_1(&p, 8, FALSE); - memset(buf, 0, 8); - memcpy(buf, p, n); - while (buf[0] != 0xdb || buf[1] != 0xfe || checksum(buf, 6) != le_readu16(buf + 6)) { - // try for a message start at the beginning of next packet - n = read_depacketize_1(&p, 8, TRUE); - memset(buf, 0, 8); - memcpy(buf, p, n); - } - id = le_readu16(buf + 2); - total = le_readu16(buf + 4); - message_ensure_size(m, total - 4); - // copy in message head, really only need id field, do the rest for debugging - m->buf[0] = m->buf[1] = 0; - memcpy(m->buf + 2, buf, 8); - // read message body and trailer - read_depacketize(m->data, total); - p = (gbuint8*)m->data + m->size; - if (checksum(m->data, m->size) == le_readu16(p) && - p[2] == 0xad && p[3] == 0xbc) - { - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": received %x\n", id); - break; - } - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": corrupted message %x\n", id); - if (id == msg_id) { - id = 0; - break; - } - } - return id; + unsigned id; + for (;;) { + unsigned total; + unsigned n; + gbuint8 buf[8]; + gbuint8* p; + + n = read_depacketize_1(&p, 8, FALSE); + memset(buf, 0, 8); + memcpy(buf, p, n); + while (buf[0] != 0xdb || buf[1] != 0xfe || checksum(buf, 6) != le_readu16(buf + 6)) { + // try for a message start at the beginning of next packet + n = read_depacketize_1(&p, 8, TRUE); + memset(buf, 0, 8); + memcpy(buf, p, n); + } + id = le_readu16(buf + 2); + total = le_readu16(buf + 4); + message_ensure_size(m, total - 4); + // copy in message head, really only need id field, do the rest for debugging + m->buf[0] = m->buf[1] = 0; + memcpy(m->buf + 2, buf, 8); + // read message body and trailer + read_depacketize((gbuint8*) m->data, total); + p = (gbuint8*)m->data + m->size; + if (checksum((gbuint8*) m->data, m->size) == le_readu16(p) && + p[2] == 0xad && p[3] == 0xbc) { + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": received %x\n", id); + } + break; + } + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": corrupted message %x\n", id); + } + if (id == msg_id) { + id = 0; + break; + } + } + return id; } // Send MSG_ACK for given message static void message_ack(unsigned id, const message_t* m) { - message_t ack; - char* p1; - const char* p2 = m->data; - switch (id) { - case MSG_ACK: - case MSG_NACK: - case MSG_NAVIGATION: - case MSG_SATELLITE_INFO: - // don't ack these - return; - } - message_init_size(&ack, 4); - p1 = ack.data; - // ack payload is id and body checksum of acked message - le_write16(p1, id); - p1[2] = p2[m->size]; - p1[3] = p2[m->size + 1]; - message_write(MSG_ACK, &ack); - message_free(&ack); + message_t ack; + char* p1; + const char* p2 = (const char*) m->data; + switch (id) { + case MSG_ACK: + case MSG_NACK: + case MSG_NAVIGATION: + case MSG_SATELLITE_INFO: + // don't ack these + return; + } + message_init_size(&ack, 4); + p1 = (char*) ack.data; + // ack payload is id and body checksum of acked message + le_write16(p1, id); + p1[2] = p2[m->size]; + p1[3] = p2[m->size + 1]; + message_write(MSG_ACK, &ack); + message_free(&ack); } // Get specific message, ignoring others. Sends ACK for non-interval messages. @@ -763,91 +777,98 @@ message_ack(unsigned id, const message_t* m) static int message_read(unsigned msg_id, message_t* m) { - unsigned id; - time_t time_start = time(NULL); - - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": looking for %x\n", msg_id); - for (;;) { - id = message_read_1(msg_id, m); - if (id == 0) { - break; - } - if (id == MSG_ERROR) { - const gbuint8* p = m->data; - fatal(MYNAME ": device error %u: \"%s\"\n", *p, p + 1); - } - message_ack(id, m); - if (id == msg_id || time(NULL) - time_start >= READ_TIMEOUT) { - break; - } - } - return id == msg_id; + unsigned id; + time_t time_start = time(NULL); + + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": looking for %x\n", msg_id); + } + for (;;) { + id = message_read_1(msg_id, m); + if (id == 0) { + break; + } + if (id == MSG_ERROR) { + const gbuint8* p = (const gbuint8*) m->data; + fatal(MYNAME ": device error %u: \"%s\"\n", *p, p + 1); + } + message_ack(id, m); + if (id == msg_id || time(NULL) - time_start >= READ_TIMEOUT) { + break; + } + } + return id == msg_id; } // Read a sequence of messages, up to a MSG_TRANSFER_COMPLETE static int get_batch(message_t** array, unsigned* n) { - int success = 1; - unsigned array_max = 100; - message_t* a = xmalloc(array_max * sizeof(message_t)); - unsigned i = 0; - unsigned id; - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": begin get_batch\n"); - do { - time_t time_start = time(NULL); - if (i == array_max) { - message_t* old_a = a; - array_max += array_max; - a = xmalloc(array_max * sizeof(message_t)); - memcpy(a, old_a, i * sizeof(message_t)); - xfree(old_a); - } - message_init(&a[i]); - for (;;) { - id = message_read_1(0, &a[i]); - switch (id) { - case MSG_NAVIGATION: - if (time(NULL) - time_start >= READ_TIMEOUT) { - success = 0; - break; - } - // fall through - case MSG_ACK: - case MSG_NACK: - case MSG_SATELLITE_INFO: - continue; - } - break; - } - message_ack(id, &a[i]); - i++; - } while (success && id != MSG_TRANSFER_COMPLETE); - if (success) { - *array = a; - *n = i - 1; - message_free(&a[*n]); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": end get_batch, %u messages\n", *n); - } else { - while (i--) { - message_free(&a[i]); - } - xfree(a); - *array = NULL; - *n = 0; - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": end get_batch, failed\n"); - } - return success; + int success = 1; + unsigned array_max = 100; + message_t* a = (message_t*) xmalloc(array_max * sizeof(message_t)); + unsigned i = 0; + unsigned id; + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": begin get_batch\n"); + } + do { + time_t time_start = time(NULL); + if (i == array_max) { + message_t* old_a = a; + array_max += array_max; + a = (message_t*) xmalloc(array_max * sizeof(message_t)); + memcpy(a, old_a, i * sizeof(message_t)); + xfree(old_a); + } + message_init(&a[i]); + for (;;) { + id = message_read_1(0, &a[i]); + switch (id) { + case MSG_NAVIGATION: + if (time(NULL) - time_start >= READ_TIMEOUT) { + success = 0; + break; + } + // fall through + case MSG_ACK: + case MSG_NACK: + case MSG_SATELLITE_INFO: + continue; + } + break; + } + message_ack(id, &a[i]); + i++; + } while (success && id != MSG_TRANSFER_COMPLETE); + if (success) { + *array = a; + *n = i - 1; + message_free(&a[*n]); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": end get_batch, %u messages\n", *n); + } + } else { + while (i--) { + message_free(&a[i]); + } + xfree(a); + *array = NULL; + *n = 0; + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": end get_batch, failed\n"); + } + } + return success; } -static struct { - unsigned msg_id; - message_t msg; -} *batch_array; +typedef struct { + unsigned msg_id; + message_t msg; +} batch_array_t; + +static batch_array_t* batch_array; + static unsigned batch_array_max; static unsigned batch_array_i; @@ -855,84 +876,87 @@ static unsigned batch_array_i; static void add_to_batch(unsigned id, message_t* m) { - if (batch_array_i == batch_array_max) { - void* old = batch_array; - if (batch_array_max == 0) { - batch_array_max = 50; - } - batch_array_max += batch_array_max; - batch_array = xmalloc(batch_array_max * sizeof(*batch_array)); - if (batch_array_i) { - memcpy(batch_array, old, batch_array_i * sizeof(*batch_array)); - xfree(old); - } - } - batch_array[batch_array_i].msg_id = id; - batch_array[batch_array_i].msg = *m; - batch_array_i++; - memset(m, 0, sizeof(*m)); + if (batch_array_i == batch_array_max) { + char* old = (char*) batch_array; + if (batch_array_max == 0) { + batch_array_max = 50; + } + batch_array_max += batch_array_max; + batch_array = (batch_array_t*) xmalloc(batch_array_max * sizeof(*batch_array)); + if (batch_array_i) { + memcpy(batch_array, old, batch_array_i * sizeof(*batch_array)); + xfree(old); + } + } + batch_array[batch_array_i].msg_id = id; + batch_array[batch_array_i].msg = *m; + batch_array_i++; + memset(m, 0, sizeof(*m)); } // send an accumulated sequence of messages static void send_batch(void) { - message_t m; - const unsigned n = batch_array_i; - unsigned i; - unsigned progress = 0; - - message_init(&m); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": begin send_batch, %u messages\n", n); - for (i = 0; i < n; i++) { - unsigned timeout_count = 0; - time_t time_start = time(NULL); - - // Can't really trigger this off either i or n as we don't - // know how the various packets map to actual waypts. - if (global_opts.verbose_status && - (batch_array[i].msg_id == MSG_WAYPOINT_IN)) { - waypt_status_disp(waypoint_n, ++progress); - } - - message_write(batch_array[i].msg_id, &batch_array[i].msg); - for (;;) { - unsigned id = message_read_1(0, &m); - switch (id) { - case MSG_ACK: - break; - case MSG_NAVIGATION: - if (time(NULL) - time_start >= 2) { - if (timeout_count) { - fatal(MYNAME ": send_batch timed out\n"); - } - timeout_count++; - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": re-sending %x\n", batch_array[i].msg_id); - message_write(batch_array[i].msg_id, &batch_array[i].msg); - time_start = time(NULL); - } - // fall through - case MSG_NACK: - case MSG_SATELLITE_INFO: - continue; - default: - warning(MYNAME ": unexpected response message %x during send_batch\n", id); - continue; - } - break; - } - } - message_read(MSG_TRANSFER_COMPLETE, &m); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": end send_batch\n"); - for (i = n; i--;) { - message_free(&batch_array[i].msg); - } - xfree(batch_array); - message_free(&m); - batch_array_i = batch_array_max = 0; + message_t m; + const unsigned n = batch_array_i; + unsigned i; + unsigned progress = 0; + + message_init(&m); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": begin send_batch, %u messages\n", n); + } + for (i = 0; i < n; i++) { + unsigned timeout_count = 0; + time_t time_start = time(NULL); + + // Can't really trigger this off either i or n as we don't + // know how the various packets map to actual waypts. + if (global_opts.verbose_status && + (batch_array[i].msg_id == MSG_WAYPOINT_IN)) { + waypt_status_disp(waypoint_n, ++progress); + } + + message_write(batch_array[i].msg_id, &batch_array[i].msg); + for (;;) { + unsigned id = message_read_1(0, &m); + switch (id) { + case MSG_ACK: + break; + case MSG_NAVIGATION: + if (time(NULL) - time_start >= 2) { + if (timeout_count) { + fatal(MYNAME ": send_batch timed out\n"); + } + timeout_count++; + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": re-sending %x\n", batch_array[i].msg_id); + } + message_write(batch_array[i].msg_id, &batch_array[i].msg); + time_start = time(NULL); + } + // fall through + case MSG_NACK: + case MSG_SATELLITE_INFO: + continue; + default: + warning(MYNAME ": unexpected response message %x during send_batch\n", id); + continue; + } + break; + } + } + message_read(MSG_TRANSFER_COMPLETE, &m); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": end send_batch\n"); + } + for (i = n; i--;) { + message_free(&batch_array[i].msg); + } + xfree(batch_array); + message_free(&m); + batch_array_i = batch_array_max = 0; } //----------------------------------------------------------------------------- @@ -941,13 +965,13 @@ send_batch(void) static double delbin_rad2deg(gbint32 x) { - return x * ((180 / M_PI) / 100000000); + return x * ((180 / M_PI) / 100000000); } static gbint32 delbin_deg2rad(double x) { - return (gbint32)(x * ((M_PI / 180) * 100000000)); + return (gbint32)(x * ((M_PI / 180) * 100000000)); } //----------------------------------------------------------------------------- @@ -956,137 +980,144 @@ delbin_deg2rad(double x) static time_t decode_time(const gbuint8* p) { - struct tm t; - t.tm_year = p[0]; - t.tm_mon = p[1] - 1; - t.tm_mday = p[2]; - t.tm_hour = p[3]; - t.tm_min = p[4]; - t.tm_sec = p[5]; - return mkgmtime(&t); + struct tm t; + t.tm_year = p[0]; + t.tm_mon = p[1] - 1; + t.tm_mday = p[2]; + t.tm_hour = p[3]; + t.tm_min = p[4]; + t.tm_sec = p[5]; + return mkgmtime(&t); } static waypoint* decode_waypoint(const void* data) { - waypoint* wp = waypt_new(); - const msg_waypoint_t* p = data; - const char* s; - float f; - - wp->creation_time = decode_time(&p->year); - wp->latitude = delbin_rad2deg(le_read32(p->latitude)); - wp->longitude = delbin_rad2deg(le_read32(p->longitude)); - f = le_read_float(p->elevation); - if (f > UNKNOWN_ELEV) { - wp->altitude = f; - } - wp->icon_descr = waypoint_symbol(p->symbol); - if (wp->icon_descr) { - wp->icon_descr = xstrdup(wp->icon_descr); - } - if (p->name_size && p->name[0]) { - wp->description = xstrdup(p->name); - } - s = p->name + p->name_size; - if (le_readu16(s) && s[2]) { - wp->notes = xstrdup(s + 2); - } - return wp; + waypoint* wp = waypt_new(); + const msg_waypoint_t* p = (const msg_waypoint_t*)data; + const char* s; + float f; + + wp->creation_time = decode_time(&p->year); + wp->latitude = delbin_rad2deg(le_read32(p->latitude)); + wp->longitude = delbin_rad2deg(le_read32(p->longitude)); + f = le_read_float(p->elevation); + if (f > UNKNOWN_ELEV) { + wp->altitude = f; + } + wp->icon_descr = waypoint_symbol(p->symbol); + if (wp->icon_descr) { + wp->icon_descr = xstrdup(wp->icon_descr); + } + if (p->name_size && p->name[0]) { + wp->description = xstrdup(p->name); + } + s = p->name + p->name_size; + if (le_readu16(s) && s[2]) { + wp->notes = xstrdup(s + 2); + } + return wp; } static void read_waypoints(void) { - message_t m; - message_t* msg_array; - unsigned msg_array_n; - waypoint* wp = NULL; - unsigned n_point; - unsigned notes_i = 0; - unsigned notes_max = 0; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - // get number of waypoints - for (;;) { - m.size = 0; - message_write(MSG_WAYPOINT_COUNT, &m); - if (message_read(MSG_WAYPOINT_COUNT, &m)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading waypoint count failed\n"); - } - n_point = le_readu32(m.data); - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": %u waypoints\n", n_point); - if (n_point == 0) { - message_free(&m); - return; - } - // get waypoint messages - attempt = ATTEMPT_MAX; - for (;;) { - m.size = MSG_REQUEST_WAYPOINTS_SIZE; - memset(m.data, 0, m.size); - // This byte is documented as reserved. Setting it to 3 is required to get - // extended notes (message 0xb015) with PN-40 firmware 2.5. - // Whether it has any effect with earlier firmware or the PN-20 is unknown. - ((char*)m.data)[1] = 3; - message_write(MSG_REQUEST_WAYPOINTS, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading waypoints failed\n"); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading waypoints, retrying\n"); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - // process waypoint messages - for (i = 0; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_WAYPOINT_OUT) { - wp = decode_waypoint(msg_array[i].data); - waypt_add(wp); - notes_i = 0; - notes_max = 0; - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": read waypoint '%s'\n", wp->description); - } else if (wp && id == MSG_WAYPOINT_NOTE_OUT) { - const msg_waypoint_note_t* p = msg_array[i].data; - const char* s = p->name + p->name_size; - unsigned nn = le_readu16(s); - if (notes_max < notes_i + nn) { - char* old = wp->notes; - if (notes_max == 0) { - notes_max = nn; - } - do { - notes_max += notes_max; - } while (notes_max < notes_i + nn); - wp->notes = xmalloc(notes_max); - if (old) { - memcpy(wp->notes, old, notes_i); - xfree(old); - } - } - if (nn) { - memcpy(wp->notes + notes_i, s + 2, nn); - notes_i += nn; - if (wp->notes[notes_i - 1] == 0) { - notes_i--; - } - } - } else { - fatal(MYNAME ": unexpected message %x while reading waypoints\n", id); - } - message_free(&msg_array[i]); - } - xfree(msg_array); + message_t m; + message_t* msg_array; + unsigned msg_array_n; + waypoint* wp = NULL; + unsigned n_point; + unsigned notes_i = 0; + unsigned notes_max = 0; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + // get number of waypoints + for (;;) { + m.size = 0; + message_write(MSG_WAYPOINT_COUNT, &m); + if (message_read(MSG_WAYPOINT_COUNT, &m)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading waypoint count failed\n"); + } + } + n_point = le_readu32(m.data); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": %u waypoints\n", n_point); + } + if (n_point == 0) { + message_free(&m); + return; + } + // get waypoint messages + attempt = ATTEMPT_MAX; + for (;;) { + m.size = MSG_REQUEST_WAYPOINTS_SIZE; + memset(m.data, 0, m.size); + // This byte is documented as reserved. Setting it to 3 is required to get + // extended notes (message 0xb015) with PN-40 firmware 2.5. + // Whether it has any effect with earlier firmware or the PN-20 is unknown. + ((char*)m.data)[1] = 3; + message_write(MSG_REQUEST_WAYPOINTS, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading waypoints failed\n"); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading waypoints, retrying\n"); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + // process waypoint messages + for (i = 0; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_WAYPOINT_OUT) { + wp = decode_waypoint(msg_array[i].data); + waypt_add(wp); + notes_i = 0; + notes_max = 0; + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": read waypoint '%s'\n", wp->description); + } + } else if (wp && id == MSG_WAYPOINT_NOTE_OUT) { + const msg_waypoint_note_t* p = (const msg_waypoint_note_t*) msg_array[i].data; + const char* s = p->name + p->name_size; + unsigned nn = le_readu16(s); + if (notes_max < notes_i + nn) { + char* old = wp->notes; + if (notes_max == 0) { + notes_max = nn; + } + do { + notes_max += notes_max; + } while (notes_max < notes_i + nn); + wp->notes = (char*) xmalloc(notes_max); + if (old) { + memcpy(wp->notes, old, notes_i); + xfree(old); + } + } + if (nn) { + memcpy(wp->notes + notes_i, s + 2, nn); + notes_i += nn; + if (wp->notes[notes_i - 1] == 0) { + notes_i--; + } + } + } else { + fatal(MYNAME ": unexpected message %x while reading waypoints\n", id); + } + message_free(&msg_array[i]); + } + xfree(msg_array); } //----------------------------------------------------------------------------- @@ -1095,331 +1126,370 @@ read_waypoints(void) static void encode_time(time_t time_, gbuint8* p) { - const struct tm* t = gmtime(&time_); - p[0] = t->tm_year; - p[1] = t->tm_mon + 1; - p[2] = t->tm_mday; - p[3] = t->tm_hour; - p[4] = t->tm_min; - p[5] = t->tm_sec; + const struct tm* t = gmtime(&time_); + p[0] = t->tm_year; + p[1] = t->tm_mon + 1; + p[2] = t->tm_mday; + p[3] = t->tm_hour; + p[4] = t->tm_min; + p[5] = t->tm_sec; } static void get_gc_notes(const waypoint* wp, int* symbol, char** notes, unsigned* notes_size) { - fs_xml* fs_gpx; - xml_tag* root = NULL; - gbfile* fd = gbfopen(NULL, "w", MYNAME); - const char* size = NULL; - int gc_sym = 0; - - switch (wp->gc_data->type) { - case gt_traditional: gc_sym = 160; break; - case gt_multi: gc_sym = 161; break; - case gt_virtual: gc_sym = 169; break; - case gt_letterbox: gc_sym = 163; break; - case gt_event: gc_sym = 165; break; - case gt_suprise: gc_sym = 162; break; - case gt_webcam: gc_sym = 170; break; - case gt_earth: gc_sym = 168; break; - case gt_benchmark: gc_sym = 172; break; - case gt_cito: gc_sym = 167; break; - case gt_mega: gc_sym = 166; break; - case gt_wherigo: gc_sym = 164; break; - case gt_unknown: - case gt_locationless: - case gt_ape: - break; - } - if (0 == strcmp(wp->icon_descr, "Geocache Found")) - gc_sym = 124; - if (wp->description) { - gbfputs(wp->description, fd); - if (wp->gc_data->placer) { - gbfprintf(fd, " by %s", wp->gc_data->placer); - } - gbfputc('\n', fd); - } - - gbfprintf(fd, "Cache ID: %s\n", wp->shortname); - if (gc_sym && opt_gcsym && atoi(opt_gcsym)) { - gbfprintf(fd, "%s\n", waypoint_symbol(gc_sym)); - *symbol = gc_sym; - } else if (wp->icon_descr) { - gbfprintf(fd, "%s\n", wp->icon_descr); - } - switch (wp->gc_data->container) { - case gc_micro: size = "Micro"; break; - case gc_small: size = "Small"; break; - case gc_regular: size = "Regular"; break; - case gc_large: size = "Large"; break; - case gc_unknown: size = "Not Chosen" ; break; - case gc_other: size = "Other"; break; - // Device has no symbol for this, but this is what Topo sends. - case gc_virtual: size = "Virtual"; break; - default: - break; - } - if (size) { - gbfprintf(fd, "SIZE: %s\n", size); - } - if (wp->gc_data->diff % 10) { - gbfprintf(fd, "D%.1f", wp->gc_data->diff / 10.0); - } else { - gbfprintf(fd, "D%u", wp->gc_data->diff / 10); - } - if (wp->gc_data->terr % 10) { - gbfprintf(fd, "/T%.1f\n", wp->gc_data->terr / 10.0); - } else { - gbfprintf(fd, "/T%u\n", wp->gc_data->terr / 10); - } - if (wp->gc_data->hint && !opt_hint_at_end) { - gbfprintf(fd, "HINT: %s\n", wp->gc_data->hint); - } - if (wp->gc_data->desc_short.utfstring || wp->gc_data->desc_long.utfstring) { - gbfputs("DESC: ", fd); - if (wp->gc_data->desc_short.utfstring) { - char* s1 = strip_html(&wp->gc_data->desc_short); - char* s2 = cet_str_utf8_to_any(s1, global_opts.charset); - gbfprintf(fd, "%s\n", s2); - xfree(s2); - xfree(s1); - } - if (wp->gc_data->desc_long.utfstring) { - char* s1 = strip_html(&wp->gc_data->desc_long); - char* s2 = cet_str_utf8_to_any(s1, global_opts.charset); - gbfputs(s2, fd); - xfree(s2); - xfree(s1); - } - } - fs_gpx = (fs_xml*)fs_chain_find(wp->fs, FS_GPX); - if (opt_logs && fs_gpx && fs_gpx->tag) { - root = xml_findfirst(fs_gpx->tag, "groundspeak:logs"); - } - if (root) { - xml_tag* curlog = xml_findfirst(root, "groundspeak:log"); - if (curlog) { - gbfputs("\nLOG:\n", fd); - } - for (; curlog; curlog = xml_findnext(root, curlog, "groundspeak:log")) { - xml_tag* logpart = xml_findfirst(curlog, "groundspeak:type"); - if (logpart) { - gbfprintf(fd, "%s\n", logpart->cdata); - } - logpart = xml_findfirst(curlog, "groundspeak:date"); - if (logpart) { - time_t logtime = xml_parse_time(logpart->cdata, NULL); - const struct tm* logtm = gmtime(&logtime); - gbfprintf(fd, "%d-%02d-%02d ", logtm->tm_year + 1900, logtm->tm_mon + 1, logtm->tm_mday); - } - logpart = xml_findfirst(curlog, "groundspeak:finder"); - if (logpart) { - char* s = cet_str_utf8_to_any(logpart->cdata, global_opts.charset); - gbfputs(s, fd); - xfree(s); - } - logpart = xml_findfirst(curlog, "groundspeak:text"); - if (logpart) { - char* s = cet_str_utf8_to_any(logpart->cdata, global_opts.charset); - gbfprintf(fd, ", %s", s); - xfree(s); - } - gbfputc('\n', fd); - } - } - if (wp->gc_data->hint && opt_hint_at_end) { - gbfprintf(fd, "\nHINT: %s\n", wp->gc_data->hint); - } - gbfputc(0, fd); - *notes_size = fd->memlen; - *notes = xmalloc(*notes_size); - memcpy(*notes, fd->handle.mem, *notes_size); - gbfclose(fd); + fs_xml* fs_gpx; + xml_tag* root = NULL; + gbfile* fd = gbfopen(NULL, "w", MYNAME); + const char* size = NULL; + int gc_sym = 0; + + switch (wp->gc_data->type) { + case gt_traditional: + gc_sym = 160; + break; + case gt_multi: + gc_sym = 161; + break; + case gt_virtual: + gc_sym = 169; + break; + case gt_letterbox: + gc_sym = 163; + break; + case gt_event: + gc_sym = 165; + break; + case gt_suprise: + gc_sym = 162; + break; + case gt_webcam: + gc_sym = 170; + break; + case gt_earth: + gc_sym = 168; + break; + case gt_benchmark: + gc_sym = 172; + break; + case gt_cito: + gc_sym = 167; + break; + case gt_mega: + gc_sym = 166; + break; + case gt_wherigo: + gc_sym = 164; + break; + case gt_unknown: + case gt_locationless: + case gt_ape: + break; + } + if (0 == strcmp(wp->icon_descr, "Geocache Found")) { + gc_sym = 124; + } + if (wp->description) { + gbfputs(wp->description, fd); + if (wp->gc_data->placer) { + gbfprintf(fd, " by %s", wp->gc_data->placer); + } + gbfputc('\n', fd); + } + + gbfprintf(fd, "Cache ID: %s\n", wp->shortname); + if (gc_sym && opt_gcsym && atoi(opt_gcsym)) { + gbfprintf(fd, "%s\n", waypoint_symbol(gc_sym)); + *symbol = gc_sym; + } else if (wp->icon_descr) { + gbfprintf(fd, "%s\n", wp->icon_descr); + } + switch (wp->gc_data->container) { + case gc_micro: + size = "Micro"; + break; + case gc_small: + size = "Small"; + break; + case gc_regular: + size = "Regular"; + break; + case gc_large: + size = "Large"; + break; + case gc_unknown: + size = "Not Chosen" ; + break; + case gc_other: + size = "Other"; + break; + // Device has no symbol for this, but this is what Topo sends. + case gc_virtual: + size = "Virtual"; + break; + default: + break; + } + if (size) { + gbfprintf(fd, "SIZE: %s\n", size); + } + if (wp->gc_data->diff % 10) { + gbfprintf(fd, "D%.1f", wp->gc_data->diff / 10.0); + } else { + gbfprintf(fd, "D%u", wp->gc_data->diff / 10); + } + if (wp->gc_data->terr % 10) { + gbfprintf(fd, "/T%.1f\n", wp->gc_data->terr / 10.0); + } else { + gbfprintf(fd, "/T%u\n", wp->gc_data->terr / 10); + } + if (wp->gc_data->hint && !opt_hint_at_end) { + gbfprintf(fd, "HINT: %s\n", wp->gc_data->hint); + } + if (wp->gc_data->desc_short.utfstring || wp->gc_data->desc_long.utfstring) { + gbfputs("DESC: ", fd); + if (wp->gc_data->desc_short.utfstring) { + char* s1 = strip_html(&wp->gc_data->desc_short); + char* s2 = cet_str_utf8_to_any(s1, global_opts.charset); + gbfprintf(fd, "%s\n", s2); + xfree(s2); + xfree(s1); + } + if (wp->gc_data->desc_long.utfstring) { + char* s1 = strip_html(&wp->gc_data->desc_long); + char* s2 = cet_str_utf8_to_any(s1, global_opts.charset); + gbfputs(s2, fd); + xfree(s2); + xfree(s1); + } + } + fs_gpx = (fs_xml*)fs_chain_find(wp->fs, FS_GPX); + if (opt_logs && fs_gpx && fs_gpx->tag) { + root = xml_findfirst(fs_gpx->tag, "groundspeak:logs"); + } + if (root) { + xml_tag* curlog = xml_findfirst(root, "groundspeak:log"); + if (curlog) { + gbfputs("\nLOG:\n", fd); + } + for (; curlog; curlog = xml_findnext(root, curlog, "groundspeak:log")) { + xml_tag* logpart = xml_findfirst(curlog, "groundspeak:type"); + if (logpart) { + gbfprintf(fd, "%s\n", logpart->cdata); + } + logpart = xml_findfirst(curlog, "groundspeak:date"); + if (logpart) { + time_t logtime = xml_parse_time(logpart->cdata, NULL); + const struct tm* logtm = gmtime(&logtime); + gbfprintf(fd, "%d-%02d-%02d ", logtm->tm_year + 1900, logtm->tm_mon + 1, logtm->tm_mday); + } + logpart = xml_findfirst(curlog, "groundspeak:finder"); + if (logpart) { + char* s = cet_str_utf8_to_any(logpart->cdata, global_opts.charset); + gbfputs(s, fd); + xfree(s); + } + logpart = xml_findfirst(curlog, "groundspeak:text"); + if (logpart) { + char* s = cet_str_utf8_to_any(logpart->cdata, global_opts.charset); + gbfprintf(fd, ", %s", s); + xfree(s); + } + gbfputc('\n', fd); + } + } + if (wp->gc_data->hint && opt_hint_at_end) { + gbfprintf(fd, "\nHINT: %s\n", wp->gc_data->hint); + } + gbfputc(0, fd); + *notes_size = fd->memlen; + *notes = (char*) xmalloc(*notes_size); + memcpy(*notes, fd->handle.mem, *notes_size); + gbfclose(fd); } static void write_waypoint_notes(const char* notes, unsigned size, const char* name) { - message_t m; - const unsigned name_size = strlen(name) + 1; - const unsigned bytes_per_msg = (10 * (delbin_os_packet_size - 2)) - name_size - 20; - const unsigned msg_count = (size + (bytes_per_msg - 1)) / bytes_per_msg; - unsigned i = 1; - - do { - char* pp; - unsigned n = bytes_per_msg; - msg_waypoint_note_t* p; - message_init_size(&m, 2 + 2 + 1 + name_size + 2 + bytes_per_msg); - p = m.data; - le_write16(p->index, i++); - le_write16(p->total, msg_count); - p->name_size = name_size; - memcpy(p->name, name, p->name_size); - pp = p->name + p->name_size; - if (n > size) { - n = size; - } - le_write16(pp, n); - pp += 2; - memcpy(pp, notes, n); - pp += n; - if (*(pp - 1)) { - *pp++ = 0; - } - notes += n; - size -= n; - m.size = pp - (char*)p; - add_to_batch(MSG_WAYPOINT_NOTE_IN, &m); - } while (size != 0); + message_t m; + const unsigned name_size = strlen(name) + 1; + const unsigned bytes_per_msg = (10 * (delbin_os_packet_size - 2)) - name_size - 20; + const unsigned msg_count = (size + (bytes_per_msg - 1)) / bytes_per_msg; + unsigned i = 1; + + do { + char* pp; + unsigned n = bytes_per_msg; + msg_waypoint_note_t* p; + message_init_size(&m, 2 + 2 + 1 + name_size + 2 + bytes_per_msg); + p = (msg_waypoint_note_t*) m.data; + le_write16(p->index, i++); + le_write16(p->total, msg_count); + p->name_size = name_size; + memcpy(p->name, name, p->name_size); + pp = p->name + p->name_size; + if (n > size) { + n = size; + } + le_write16(pp, n); + pp += 2; + memcpy(pp, notes, n); + pp += n; + if (*(pp - 1)) { + *pp++ = 0; + } + notes += n; + size -= n; + m.size = pp - (char*)p; + add_to_batch(MSG_WAYPOINT_NOTE_IN, &m); + } while (size != 0); } static void add_nuke(nuke_type type) { - message_t m; - msg_delete_t* p; + message_t m; + msg_delete_t* p; - message_init_size(&m, MSG_DELETE_SIZE); - p = m.data; - p->type = type; - p->mode = nuke_mode_all; - p->location = nuke_dest_internal; - memset(p->object_name, 0, sizeof(p->object_name)); + message_init_size(&m, MSG_DELETE_SIZE); + p = (msg_delete_t*) m.data; + p->type = type; + p->mode = nuke_mode_all; + p->location = nuke_dest_internal; + memset(p->object_name, 0, sizeof(p->object_name)); - // MSG_DELETE generates a MSG_TRANSFER_COMPLETE, - // so use the batch facility to wait for it - add_to_batch(MSG_DELETE, &m); - send_batch(); + // MSG_DELETE generates a MSG_TRANSFER_COMPLETE, + // so use the batch facility to wait for it + add_to_batch(MSG_DELETE, &m); + send_batch(); } static void write_waypoint(const waypoint* wp) { - message_t m; - msg_waypoint_t* p; - const char* name = wp->shortname; - unsigned name_size; - char* notes; - unsigned notes_size = 0; - unsigned extended_notes_size = 0; - char* notes_freeable = NULL; - int symbol = -1; - float elev = UNKNOWN_ELEV; - char* pp; - - if (waypt_empty_gc_data(wp)) { - notes = wp->notes; - if (notes == NULL && wp->description && strcmp(wp->shortname, wp->description)) { - notes = wp->description; - } - if (notes) { - notes_size = strlen(notes) + 1; - } - } else { - get_gc_notes(wp, &symbol, ¬es, ¬es_size); - notes_freeable = notes; - if (wp->description) { - name = mkshort(mkshort_handle, wp->description); - } - } - - if (notes_size > 800) { - if (use_extended_notes) { - extended_notes_size = notes_size; - notes_size = 1; - } else { - notes_size = 800; - } - } - - name_size = strlen(name) + 1; - if (name_size > 255) { - name_size = 255; - } - message_init_size(&m, 31 + name_size + notes_size); - p = m.data; - - waypoint_i++; - le_write32(p->total, waypoint_n); - le_write32(p->index, waypoint_i); - encode_time(wp->creation_time, &p->year); - le_write32(p->latitude, delbin_deg2rad(wp->latitude)); - le_write32(p->longitude, delbin_deg2rad(wp->longitude)); - if (wp->altitude > unknown_alt) { - elev = wp->altitude; - } - le_write_float(p->elevation, elev); - if (symbol < 0) { - symbol = 0; - if (wp->icon_descr) { - symbol = waypoint_symbol_index(wp->icon_descr); - } - } - p->symbol = symbol; - p->name_size = name_size; - memcpy(p->name, name, name_size - 1); - p->name[name_size - 1] = 0; - pp = p->name + name_size; - m.size = (pp + 2 + notes_size) - (char*)p; - if (extended_notes_size) { - le_write16(pp, 0xffff); - pp[2] = 0; - } else { - le_write16(pp, notes_size); - if (notes) { - memcpy(pp + 2, notes, notes_size - 1); - pp[2 + notes_size - 1] = 0; - } - } - - add_to_batch(MSG_WAYPOINT_IN, &m); - - if (extended_notes_size) { - write_waypoint_notes(notes, extended_notes_size, name); - } - if (notes_freeable) { - xfree(notes_freeable); - } - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": wrote waypoint %u '%s'\n", waypoint_i, name); + message_t m; + msg_waypoint_t* p; + const char* name = wp->shortname; + unsigned name_size; + char* notes; + unsigned notes_size = 0; + unsigned extended_notes_size = 0; + char* notes_freeable = NULL; + int symbol = -1; + float elev = UNKNOWN_ELEV; + char* pp; + + if (waypt_empty_gc_data(wp)) { + notes = wp->notes; + if (notes == NULL && wp->description && strcmp(wp->shortname, wp->description)) { + notes = wp->description; + } + if (notes) { + notes_size = strlen(notes) + 1; + } + } else { + get_gc_notes(wp, &symbol, ¬es, ¬es_size); + notes_freeable = notes; + if (wp->description) { + name = mkshort(mkshort_handle, wp->description); + } + } + + if (notes_size > 800) { + if (use_extended_notes) { + extended_notes_size = notes_size; + notes_size = 1; + } else { + notes_size = 800; + } + } + + name_size = strlen(name) + 1; + if (name_size > 255) { + name_size = 255; + } + message_init_size(&m, 31 + name_size + notes_size); + p = (msg_waypoint_t*) m.data; + + waypoint_i++; + le_write32(p->total, waypoint_n); + le_write32(p->index, waypoint_i); + encode_time(wp->creation_time, &p->year); + le_write32(p->latitude, delbin_deg2rad(wp->latitude)); + le_write32(p->longitude, delbin_deg2rad(wp->longitude)); + if (wp->altitude > unknown_alt) { + elev = wp->altitude; + } + le_write_float(p->elevation, elev); + if (symbol < 0) { + symbol = 0; + if (wp->icon_descr) { + symbol = waypoint_symbol_index(wp->icon_descr); + } + } + p->symbol = symbol; + p->name_size = name_size; + memcpy(p->name, name, name_size - 1); + p->name[name_size - 1] = 0; + pp = p->name + name_size; + m.size = (pp + 2 + notes_size) - (char*)p; + if (extended_notes_size) { + le_write16(pp, 0xffff); + pp[2] = 0; + } else { + le_write16(pp, notes_size); + if (notes) { + memcpy(pp + 2, notes, notes_size - 1); + pp[2 + notes_size - 1] = 0; + } + } + + add_to_batch(MSG_WAYPOINT_IN, &m); + + if (extended_notes_size) { + write_waypoint_notes(notes, extended_notes_size, name); + } + if (notes_freeable) { + xfree(notes_freeable); + } + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": wrote waypoint %u '%s'\n", waypoint_i, name); + } } static void write_waypoints(void) { - message_t m; - unsigned device_n = 0; - - waypoint_i = 0; - waypoint_n = waypt_count(); - if (waypoint_n > device_max_waypoint) { - fatal(MYNAME ": waypoint count (%u) exceeds device limit (%u)\n", - waypoint_n, device_max_waypoint); - } - - message_init_size(&m, 0); - message_write(MSG_WAYPOINT_COUNT, &m); - if (message_read(MSG_WAYPOINT_COUNT, &m)) { - device_n = le_readu32(m.data); - } - - waypt_disp_all(write_waypoint); - send_batch(); - - if (device_n + waypoint_n > device_max_waypoint) { - m.size = 0; - message_write(MSG_WAYPOINT_COUNT, &m); - if (message_read(MSG_WAYPOINT_COUNT, &m) && - le_readu32(m.data) == device_max_waypoint) - { - warning(MYNAME ": waypoint count (%u already on device + %u added = %u)" - " exceeds device limit (%u), some may have been discarded\n", - device_n, waypoint_n, device_n + waypoint_n, device_max_waypoint); - } - } - message_free(&m); + message_t m; + unsigned device_n = 0; + + waypoint_i = 0; + waypoint_n = waypt_count(); + if (waypoint_n > device_max_waypoint) { + fatal(MYNAME ": waypoint count (%u) exceeds device limit (%u)\n", + waypoint_n, device_max_waypoint); + } + + message_init_size(&m, 0); + message_write(MSG_WAYPOINT_COUNT, &m); + if (message_read(MSG_WAYPOINT_COUNT, &m)) { + device_n = le_readu32(m.data); + } + + waypt_disp_all(write_waypoint); + send_batch(); + + if (device_n + waypoint_n > device_max_waypoint) { + m.size = 0; + message_write(MSG_WAYPOINT_COUNT, &m); + if (message_read(MSG_WAYPOINT_COUNT, &m) && + le_readu32(m.data) == device_max_waypoint) { + warning(MYNAME ": waypoint count (%u already on device + %u added = %u)" + " exceeds device limit (%u), some may have been discarded\n", + device_n, waypoint_n, device_n + waypoint_n, device_max_waypoint); + } + } + message_free(&m); } //----------------------------------------------------------------------------- @@ -1428,182 +1498,196 @@ write_waypoints(void) static void decode_sat_fix(waypoint* wp, const gbuint8 status) { - switch (status & 3) { - case 1: wp->fix = fix_none; break; - case 2: wp->fix = fix_2d; break; - case 3: - wp->fix = fix_3d; - if (status & 4) { - wp->fix = fix_dgps; - } - break; - } + switch (status & 3) { + case 1: + wp->fix = fix_none; + break; + case 2: + wp->fix = fix_2d; + break; + case 3: + wp->fix = fix_3d; + if (status & 4) { + wp->fix = fix_dgps; + } + break; + } } static void decode_track_point(const void* data, unsigned* wp_array_i, unsigned max_point) { - const msg_track_point_t* p = data; - const unsigned n = p->number; - unsigned i; - unsigned j = *wp_array_i; - - if (j + n > max_point) { - fatal(MYNAME ": read too many track points\n"); - } - for (i = 0; i < n; i++, j++) { - waypoint* wp = waypt_new(); - float elev = le_read_float(p->point[i].elevation); - wp_array[j] = wp; - wp->creation_time = decode_time(&p->point[i].year); - wp->latitude = delbin_rad2deg(le_read32(p->point[i].latitude)); - wp->longitude = delbin_rad2deg(le_read32(p->point[i].longitude)); - if (elev > UNKNOWN_ELEV) { - wp->altitude = elev; - } - wp->speed = le_readu16(p->point[i].speed); - wp->speed *= (100.0f / (60 * 60)); - wp->wpt_flags.speed = 1; - decode_sat_fix(wp, p->point[i].status); - wp->wpt_flags.new_trkseg = (p->point[i].status & 0x10) != 0; - } - *wp_array_i = j; + const msg_track_point_t* p = (const msg_track_point_t*) data; + const unsigned n = p->number; + unsigned i; + unsigned j = *wp_array_i; + + if (j + n > max_point) { + fatal(MYNAME ": read too many track points\n"); + } + for (i = 0; i < n; i++, j++) { + waypoint* wp = waypt_new(); + float elev = le_read_float(p->point[i].elevation); + wp_array[j] = wp; + wp->creation_time = decode_time(&p->point[i].year); + wp->latitude = delbin_rad2deg(le_read32(p->point[i].latitude)); + wp->longitude = delbin_rad2deg(le_read32(p->point[i].longitude)); + if (elev > UNKNOWN_ELEV) { + wp->altitude = elev; + } + wp->speed = le_readu16(p->point[i].speed); + wp->speed *= (100.0f / (60 * 60)); + wp->wpt_flags.speed = 1; + decode_sat_fix(wp, p->point[i].status); + wp->wpt_flags.new_trkseg = (p->point[i].status & 0x10) != 0; + } + *wp_array_i = j; } static void read_track(route_head* track) { - message_t m; - message_t* msg_array; - const msg_track_header_t* p; - unsigned msg_array_n; - unsigned wp_array_i = 0; - unsigned n_point; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - // read track messages - for (;;) { - m.size = MSG_REQUEST_TRACKS_SIZE; - memset(m.data, 0, m.size); - ((char*)m.data)[0] = 1; // Download single track - strcpy((char*)m.data + 1, track->rte_name); - message_write(MSG_REQUEST_TRACKS, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading track '%s' failed\n", track->rte_name); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading track '%s', retrying\n", track->rte_name); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - if (msg_array_n == 0 || message_get_id(&msg_array[0]) != MSG_TRACK_HEADER_OUT) { - fatal(MYNAME ": reading track '%s' failed (missing track header)\n", track->rte_name); - } - // process track messages - p = msg_array[0].data; - if (le_readu16(p->comment_size)) { - track->rte_desc = xstrdup(p->comment); - } - track->line_color.bbggrr = track_color(p->color[0]); - n_point = le_readu32(p->total_points); - wp_array = xcalloc(n_point, sizeof(*wp_array)); - message_free(&msg_array[0]); - for (i = 1; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_TRACK_POINT_OUT) { - decode_track_point(msg_array[i].data, &wp_array_i, n_point); - } else { - fatal(MYNAME ": unexpected message %x while reading track '%s'\n", id, track->rte_name); - } - message_free(&msg_array[i]); - } - xfree(msg_array); - if (n_point != wp_array_i) { - fatal(MYNAME ": track point count mismatch, expected %u, got %u\n", n_point, wp_array_i); - } - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": read track '%s' %u points\n", track->rte_name, n_point); - for (i = 0; i < n_point; i++) { - track_add_wpt(track, wp_array[i]); - } - track_add_head(track); - xfree(wp_array); + message_t m; + message_t* msg_array; + const msg_track_header_t* p; + unsigned msg_array_n; + unsigned wp_array_i = 0; + unsigned n_point; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + // read track messages + for (;;) { + m.size = MSG_REQUEST_TRACKS_SIZE; + memset(m.data, 0, m.size); + ((char*)m.data)[0] = 1; // Download single track + strcpy((char*)m.data + 1, track->rte_name); + message_write(MSG_REQUEST_TRACKS, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading track '%s' failed\n", track->rte_name); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading track '%s', retrying\n", track->rte_name); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + if (msg_array_n == 0 || message_get_id(&msg_array[0]) != MSG_TRACK_HEADER_OUT) { + fatal(MYNAME ": reading track '%s' failed (missing track header)\n", track->rte_name); + } + // process track messages + p = (const msg_track_header_t*) msg_array[0].data; + if (le_readu16(p->comment_size)) { + track->rte_desc = xstrdup(p->comment); + } + track->line_color.bbggrr = track_color(p->color[0]); + n_point = le_readu32(p->total_points); + wp_array = (waypoint**) xcalloc(n_point, sizeof(*wp_array)); + message_free(&msg_array[0]); + for (i = 1; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_TRACK_POINT_OUT) { + decode_track_point(msg_array[i].data, &wp_array_i, n_point); + } else { + fatal(MYNAME ": unexpected message %x while reading track '%s'\n", id, track->rte_name); + } + message_free(&msg_array[i]); + } + xfree(msg_array); + if (n_point != wp_array_i) { + fatal(MYNAME ": track point count mismatch, expected %u, got %u\n", n_point, wp_array_i); + } + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": read track '%s' %u points\n", track->rte_name, n_point); + } + for (i = 0; i < n_point; i++) { + track_add_wpt(track, wp_array[i]); + } + track_add_head(track); + xfree(wp_array); } static void read_tracks(void) { - message_t m; - message_t* msg_array; - unsigned msg_array_n; - route_head** track_array; - unsigned total; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - // get number of tracks - for (;;) { - m.size = 0; - message_write(MSG_TRACK_COUNT, &m); - if (message_read(MSG_TRACK_COUNT, &m)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading track count failed\n"); - } - total = le_readu32(m.data); - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": %u tracks\n", total); - if (total == 0) { - message_free(&m); - return; - } - - // First get track headers, then request each track with non-zero number of points - attempt = ATTEMPT_MAX; - for (;;) { - m.size = MSG_REQUEST_TRACKS_SIZE; - memset(m.data, 0, m.size); - ((char*)m.data)[0] = 2; // Download all track headers - message_write(MSG_REQUEST_TRACKS, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading track headers failed\n"); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading track headers, retrying\n"); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - track_array = xcalloc(total, sizeof(*track_array)); - for (i = 0; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_TRACK_HEADER_OUT) { - const msg_track_header_t* p = msg_array[i].data; - if (le_readu32(p->total_points)) { - track_array[i] = route_head_alloc(); - track_array[i]->rte_name = xstrdup(p->name); - } - } else { - fatal(MYNAME ": unexpected message %x while reading track headers\n", id); - } - message_free(&msg_array[i]); - } - xfree(msg_array); - // get each track - for (i = 0; i < total; i++) { - if (track_array[i]) { - read_track(track_array[i]); - } - } - xfree(track_array); + message_t m; + message_t* msg_array; + unsigned msg_array_n; + route_head** track_array; + unsigned total; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + // get number of tracks + for (;;) { + m.size = 0; + message_write(MSG_TRACK_COUNT, &m); + if (message_read(MSG_TRACK_COUNT, &m)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading track count failed\n"); + } + } + total = le_readu32(m.data); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": %u tracks\n", total); + } + if (total == 0) { + message_free(&m); + return; + } + + // First get track headers, then request each track with non-zero number of points + attempt = ATTEMPT_MAX; + for (;;) { + m.size = MSG_REQUEST_TRACKS_SIZE; + memset(m.data, 0, m.size); + ((char*)m.data)[0] = 2; // Download all track headers + message_write(MSG_REQUEST_TRACKS, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading track headers failed\n"); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading track headers, retrying\n"); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + track_array = (route_head**) xcalloc(total, sizeof(*track_array)); + for (i = 0; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_TRACK_HEADER_OUT) { + const msg_track_header_t* p = (msg_track_header_t*) msg_array[i].data; + if (le_readu32(p->total_points)) { + track_array[i] = route_head_alloc(); + track_array[i]->rte_name = xstrdup(p->name); + } + } else { + fatal(MYNAME ": unexpected message %x while reading track headers\n", id); + } + message_free(&msg_array[i]); + } + xfree(msg_array); + // get each track + for (i = 0; i < total; i++) { + if (track_array[i]) { + read_track(track_array[i]); + } + } + xfree(track_array); } //----------------------------------------------------------------------------- @@ -1612,112 +1696,122 @@ read_tracks(void) static void write_track_points(void) { - message_t m; - const unsigned pt_per_msg = 10; - msg_track_point_t* p = NULL; - unsigned i = 0; - unsigned j = 0; - - do { - const waypoint* wp = wp_array[i]; - float f; - - if (j == 0) { - message_init_size(&m, 9 + 23 * pt_per_msg); - p = m.data; - le_write32(p->total, waypoint_n); - le_write32(p->index, i + 1); - } - assert(p); - encode_time(wp->creation_time, &p->point[j].year); - le_write32(p->point[j].latitude, delbin_deg2rad(wp->latitude)); - le_write32(p->point[j].longitude, delbin_deg2rad(wp->longitude)); - f = UNKNOWN_ELEV; - if (wp->altitude > unknown_alt) { - f = wp->altitude; - } - le_write_float(p->point[j].elevation, f); - f = WAYPT_GET(wp, speed, 0); - f *= (60 * 60) / 100; - le_write16(p->point[j].speed, (gbuint16)f); - f = WAYPT_GET(wp, course, 0); - f *= 100; - le_write16(p->point[j].heading, (gbuint16)f); - switch (wp->fix) { - default: p->point[j].status = 0; break; - case fix_none: p->point[j].status = 1; break; - case fix_2d: p->point[j].status = 2; break; - case fix_3d: p->point[j].status = 3; break; - case fix_dgps: p->point[j].status = 4 | 3; break; - } - if (wp->wpt_flags.new_trkseg) { - p->point[j].status |= 0x10; - } - i++; - j++; - if (j == pt_per_msg || i == waypoint_n) { - p->number = j; - m.size = 9 + 23 * j; - add_to_batch(MSG_TRACK_POINT_IN, &m); - j = 0; - } - } while (i < waypoint_n); + message_t m; + const unsigned pt_per_msg = 10; + msg_track_point_t* p = NULL; + unsigned i = 0; + unsigned j = 0; + + do { + const waypoint* wp = wp_array[i]; + float f; + + if (j == 0) { + message_init_size(&m, 9 + 23 * pt_per_msg); + p =(msg_track_point_t*) m.data; + le_write32(p->total, waypoint_n); + le_write32(p->index, i + 1); + } + assert(p); + encode_time(wp->creation_time, &p->point[j].year); + le_write32(p->point[j].latitude, delbin_deg2rad(wp->latitude)); + le_write32(p->point[j].longitude, delbin_deg2rad(wp->longitude)); + f = UNKNOWN_ELEV; + if (wp->altitude > unknown_alt) { + f = wp->altitude; + } + le_write_float(p->point[j].elevation, f); + f = WAYPT_GET(wp, speed, 0); + f *= (60 * 60) / 100; + le_write16(p->point[j].speed, (gbuint16)f); + f = WAYPT_GET(wp, course, 0); + f *= 100; + le_write16(p->point[j].heading, (gbuint16)f); + switch (wp->fix) { + default: + p->point[j].status = 0; + break; + case fix_none: + p->point[j].status = 1; + break; + case fix_2d: + p->point[j].status = 2; + break; + case fix_3d: + p->point[j].status = 3; + break; + case fix_dgps: + p->point[j].status = 4 | 3; + break; + } + if (wp->wpt_flags.new_trkseg) { + p->point[j].status |= 0x10; + } + i++; + j++; + if (j == pt_per_msg || i == waypoint_n) { + p->number = j; + m.size = 9 + 23 * j; + add_to_batch(MSG_TRACK_POINT_IN, &m); + j = 0; + } + } while (i < waypoint_n); } static void write_track_begin(const route_head* track) { - waypoint_i = 0; - waypoint_n = track->rte_waypt_ct; - if (waypoint_n) { - wp_array = xmalloc(waypoint_n * sizeof(*wp_array)); - } + waypoint_i = 0; + waypoint_n = track->rte_waypt_ct; + if (waypoint_n) { + wp_array = (waypoint**) xmalloc(waypoint_n * sizeof(*wp_array)); + } } static void write_track_point(const waypoint* wp) { - wp_array[waypoint_i++] = (waypoint*)wp; + wp_array[waypoint_i++] = (waypoint*)wp; } static void write_track_end(const route_head* track) { - message_t m; - msg_track_header_in_t* p; - unsigned comment_size = 0; - - if (waypoint_n == 0) { - return; - } - if (track->rte_desc) { - comment_size = strlen(track->rte_desc) + 1; - } - message_init_size(&m, sizeof(msg_track_header_in_t) - 1 + comment_size); - p = m.data; - memset(p->name, 0, sizeof(p->name)); - if (track->rte_name) { - strncpy(p->name, track->rte_name, sizeof(p->name) - 1); - } else { - sprintf(p->name, "%lu", (long)wp_array[0]->creation_time); - } - le_write32(p->total_points, waypoint_n); - encode_time(current_time(), &p->year); - le_write16(p->color, track_color_index(track->line_color.bbggrr)); - le_write16(p->comment_size, comment_size); - if (comment_size) { - memcpy(p->comment, track->rte_desc, comment_size); - } - add_to_batch(MSG_TRACK_HEADER_IN, &m); - write_track_points(); - send_batch(); - xfree(wp_array); + message_t m; + msg_track_header_in_t* p; + unsigned comment_size = 0; + + if (waypoint_n == 0) { + return; + } + if (track->rte_desc) { + comment_size = strlen(track->rte_desc) + 1; + } + message_init_size(&m, sizeof(msg_track_header_in_t) - 1 + comment_size); + p = (msg_track_header_in_t*) m.data; + memset(p->name, 0, sizeof(p->name)); + if (track->rte_name) { + strncpy(p->name, track->rte_name, sizeof(p->name) - 1); + } else { + sprintf(p->name, "%lu", (long)wp_array[0]->creation_time); + } + le_write32(p->total_points, waypoint_n); + encode_time(current_time(), &p->year); + le_write16(p->color, track_color_index(track->line_color.bbggrr)); + le_write16(p->comment_size, comment_size); + if (comment_size) { + memcpy(p->comment, track->rte_desc, comment_size); + } + add_to_batch(MSG_TRACK_HEADER_IN, &m); + write_track_points(); + send_batch(); + xfree(wp_array); } static void write_tracks(void) { - track_disp_all(write_track_begin, write_track_end, write_track_point); + track_disp_all(write_track_begin, write_track_end, write_track_point); } //----------------------------------------------------------------------------- @@ -1726,208 +1820,246 @@ write_tracks(void) static void decode_route_shape(const void* data, unsigned* wp_array_i) { - const msg_route_shape_t* p = data; - const unsigned n = p->number; - unsigned i; - unsigned j = *wp_array_i; + const msg_route_shape_t* p = (msg_route_shape_t*) data; + const unsigned n = p->number; + unsigned i; + unsigned j = *wp_array_i; - for (i = 0; i < n; i++, j++) { - char buf[32]; - waypoint* wp = waypt_new(); - wp_array[j] = wp; - wp->latitude = delbin_rad2deg(le_read32(p->point[i].latitude)); - wp->longitude = delbin_rad2deg(le_read32(p->point[i].longitude)); - sprintf(buf, "SHP%03u", j); - wp->shortname = xstrdup(buf); - } - *wp_array_i = j; + for (i = 0; i < n; i++, j++) { + char buf[32]; + waypoint* wp = waypt_new(); + wp_array[j] = wp; + wp->latitude = delbin_rad2deg(le_read32(p->point[i].latitude)); + wp->longitude = delbin_rad2deg(le_read32(p->point[i].longitude)); + sprintf(buf, "SHP%03u", j); + wp->shortname = xstrdup(buf); + } + *wp_array_i = j; } static waypoint* decode_route_point(const void* data) { - const msg_route_point_t* p = data; - const char* s = NULL; - gbfile* fd = gbfopen(NULL, "w", MYNAME); - waypoint* wp = waypt_new(); - if (p->name[0]) { - wp->shortname = xstrdup(p->name); - } - // give these a higher priority than the shape points - wp->route_priority = 1; - wp->latitude = delbin_rad2deg(le_read32(p->latitude)); - wp->longitude = delbin_rad2deg(le_read32(p->longitude)); - switch (p->itinerary_type) { - case 1: s = "Start"; break; - case 2: s = "Stop"; break; - case 3: s = "Finish"; break; - case 4: s = "Via"; break; - case 5: s = "Via Hidden"; break; - case 6: - switch (p->turn_type) { - case 1: s = "Turn, Straight"; break; - case 2: s = "Turn, Right"; break; - case 3: s = "Turn, Bear Right"; break; - case 4: s = "Turn, Keep Right"; break; - case 5: s = "Turn, Left"; break; - case 6: s = "Turn, Bear Left"; break; - case 7: s = "Turn, Keep Left"; break; - case 8: s = "Turn, Reverse Direction"; break; - case 9: s = "Turn, Street Name Change"; break; - } - break; - } - if (s) { - gbfprintf(fd, "Type: %s", s); - } - if (p->exit_label_size && p->exit_label[0]) { - gbfprintf(fd, "\nExit: %s", p->exit_label); - } - s = p->exit_label + p->exit_label_size; - if (s[0] && s[1]) { - gbfprintf(fd, "\n%s", s + 1); - } - if (fd->memlen) { - gbfputc(0, fd); - wp->notes = xmalloc(fd->memlen); - memcpy(wp->notes, fd->handle.mem, fd->memlen); - } - gbfclose(fd); - return wp; + const msg_route_point_t* p = (const msg_route_point_t*) data; + const char* s = NULL; + gbfile* fd = gbfopen(NULL, "w", MYNAME); + waypoint* wp = waypt_new(); + if (p->name[0]) { + wp->shortname = xstrdup(p->name); + } + // give these a higher priority than the shape points + wp->route_priority = 1; + wp->latitude = delbin_rad2deg(le_read32(p->latitude)); + wp->longitude = delbin_rad2deg(le_read32(p->longitude)); + switch (p->itinerary_type) { + case 1: + s = "Start"; + break; + case 2: + s = "Stop"; + break; + case 3: + s = "Finish"; + break; + case 4: + s = "Via"; + break; + case 5: + s = "Via Hidden"; + break; + case 6: + switch (p->turn_type) { + case 1: + s = "Turn, Straight"; + break; + case 2: + s = "Turn, Right"; + break; + case 3: + s = "Turn, Bear Right"; + break; + case 4: + s = "Turn, Keep Right"; + break; + case 5: + s = "Turn, Left"; + break; + case 6: + s = "Turn, Bear Left"; + break; + case 7: + s = "Turn, Keep Left"; + break; + case 8: + s = "Turn, Reverse Direction"; + break; + case 9: + s = "Turn, Street Name Change"; + break; + } + break; + } + if (s) { + gbfprintf(fd, "Type: %s", s); + } + if (p->exit_label_size && p->exit_label[0]) { + gbfprintf(fd, "\nExit: %s", p->exit_label); + } + s = p->exit_label + p->exit_label_size; + if (s[0] && s[1]) { + gbfprintf(fd, "\n%s", s + 1); + } + if (fd->memlen) { + gbfputc(0, fd); + wp->notes = (char*) xmalloc(fd->memlen); + memcpy(wp->notes, fd->handle.mem, fd->memlen); + } + gbfclose(fd); + return wp; } static void read_route(route_head* route) { - message_t m; - message_t* msg_array; - const msg_route_header_t* p; - unsigned msg_array_n; - unsigned wp_array_i = 0; - unsigned route_total, shape_total, total; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - for (;;) { - m.size = MSG_REQUEST_ROUTES_SIZE; - memset(m.data, 0, m.size); - ((char*)m.data)[0] = 1; // Download single route - strcpy((char*)m.data + 1, route->rte_name); - message_write(MSG_REQUEST_ROUTES, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading route '%s' failed (timed out)\n", route->rte_name); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading route route '%s', retrying\n", route->rte_name); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - if (msg_array_n == 0 || message_get_id(&msg_array[0]) != MSG_ROUTE_HEADER_OUT) { - fatal(MYNAME ": missing route header\n"); - } - p = msg_array[0].data; - route_total = le_readu32(p->total_route_point); - shape_total = le_readu32(p->total_shape_point); - total = route_total + shape_total; - wp_array = xcalloc(total, sizeof(*wp_array)); - if (global_opts.debug_level >= DBGLVL_L) { - warning(MYNAME ": route '%s' %u points, %u shape points\n", - route->rte_name, route_total, shape_total); - } - message_free(&msg_array[0]); - for (i = 1; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_ROUTE_POINT_OUT) { - wp_array[wp_array_i] = decode_route_point(msg_array[i].data); - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": route point '%s'\n", wp_array[wp_array_i]->shortname); - wp_array_i++; - } else if (id == MSG_ROUTE_SHAPE_OUT) { - decode_route_shape(msg_array[i].data, &wp_array_i); - } else { - fatal(MYNAME ": unexpected message %x while reading route '%s'\n", id, route->rte_name); - } - message_free(&msg_array[i]); - } - xfree(msg_array); - if (total != wp_array_i) { - fatal(MYNAME ": route point count mismatch, expected %u, got %u\n", total, wp_array_i); - } - for (i = 0; i < total; i++) { - route_add_wpt(route, wp_array[i]); - } - xfree(wp_array); - route_add_head(route); + message_t m; + message_t* msg_array; + const msg_route_header_t* p; + unsigned msg_array_n; + unsigned wp_array_i = 0; + unsigned route_total, shape_total, total; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + for (;;) { + m.size = MSG_REQUEST_ROUTES_SIZE; + memset(m.data, 0, m.size); + ((char*)m.data)[0] = 1; // Download single route + strcpy((char*)m.data + 1, route->rte_name); + message_write(MSG_REQUEST_ROUTES, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading route '%s' failed (timed out)\n", route->rte_name); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading route route '%s', retrying\n", route->rte_name); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + if (msg_array_n == 0 || message_get_id(&msg_array[0]) != MSG_ROUTE_HEADER_OUT) { + fatal(MYNAME ": missing route header\n"); + } + p = (const msg_route_header_t*) msg_array[0].data; + route_total = le_readu32(p->total_route_point); + shape_total = le_readu32(p->total_shape_point); + total = route_total + shape_total; + wp_array = (waypoint**) xcalloc(total, sizeof(*wp_array)); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": route '%s' %u points, %u shape points\n", + route->rte_name, route_total, shape_total); + } + message_free(&msg_array[0]); + for (i = 1; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_ROUTE_POINT_OUT) { + wp_array[wp_array_i] = decode_route_point(msg_array[i].data); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": route point '%s'\n", wp_array[wp_array_i]->shortname); + } + wp_array_i++; + } else if (id == MSG_ROUTE_SHAPE_OUT) { + decode_route_shape(msg_array[i].data, &wp_array_i); + } else { + fatal(MYNAME ": unexpected message %x while reading route '%s'\n", id, route->rte_name); + } + message_free(&msg_array[i]); + } + xfree(msg_array); + if (total != wp_array_i) { + fatal(MYNAME ": route point count mismatch, expected %u, got %u\n", total, wp_array_i); + } + for (i = 0; i < total; i++) { + route_add_wpt(route, wp_array[i]); + } + xfree(wp_array); + route_add_head(route); } static void read_routes(void) { - message_t m; - message_t* msg_array; - unsigned msg_array_n; - route_head** route_array; - unsigned total; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - // get number of routes - for (;;) { - m.size = 0; - message_write(MSG_ROUTE_COUNT, &m); - if (message_read(MSG_ROUTE_COUNT, &m)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading route count failed\n"); - } - total = le_readu32(m.data); - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": %u routes\n", total); - if (total == 0) { - message_free(&m); - return; - } - - // First get route headers, then request each route - attempt = ATTEMPT_MAX; - for (;;) { - m.size = MSG_REQUEST_ROUTES_SIZE; - memset(m.data, 0, m.size); - ((char*)m.data)[0] = 2; // Download all route headers - message_write(MSG_REQUEST_ROUTES, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading route headers failed\n"); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading route headers, retrying\n"); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - route_array = xcalloc(total, sizeof(*route_array)); - for (i = 0; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_ROUTE_HEADER_OUT) { - route_array[i] = route_head_alloc(); - route_array[i]->rte_name = xstrdup(((msg_route_header_t*)msg_array[i].data)->name); - } else { - fatal(MYNAME ": unexpected message %x while reading route headers\n", id); - } - message_free(&msg_array[i]); - } - xfree(msg_array); - // get each route - for (i = 0; i < total; i++) { - read_route(route_array[i]); - } - xfree(route_array); + message_t m; + message_t* msg_array; + unsigned msg_array_n; + route_head** route_array; + unsigned total; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + // get number of routes + for (;;) { + m.size = 0; + message_write(MSG_ROUTE_COUNT, &m); + if (message_read(MSG_ROUTE_COUNT, &m)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading route count failed\n"); + } + } + total = le_readu32(m.data); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": %u routes\n", total); + } + if (total == 0) { + message_free(&m); + return; + } + + // First get route headers, then request each route + attempt = ATTEMPT_MAX; + for (;;) { + m.size = MSG_REQUEST_ROUTES_SIZE; + memset(m.data, 0, m.size); + ((char*)m.data)[0] = 2; // Download all route headers + message_write(MSG_REQUEST_ROUTES, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading route headers failed\n"); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading route headers, retrying\n"); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + route_array = (route_head**) xcalloc(total, sizeof(*route_array)); + for (i = 0; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_ROUTE_HEADER_OUT) { + route_array[i] = route_head_alloc(); + route_array[i]->rte_name = xstrdup(((msg_route_header_t*)msg_array[i].data)->name); + } else { + fatal(MYNAME ": unexpected message %x while reading route headers\n", id); + } + message_free(&msg_array[i]); + } + xfree(msg_array); + // get each route + for (i = 0; i < total; i++) { + read_route(route_array[i]); + } + xfree(route_array); } //----------------------------------------------------------------------------- @@ -1940,138 +2072,138 @@ static unsigned* shape_point_counts; static void write_route_shape_points(waypoint** array, unsigned n) { - message_t m; - const unsigned pt_per_msg = 25; - msg_route_shape_t* p = NULL; - unsigned i = 0; - unsigned j = 0; - - do { - if (j == 0) { - message_init_size(&m, 10 + 8 * pt_per_msg); - p = m.data; - le_write32(p->total, n); - le_write32(p->index, i + 1); - p->reserved = 0; - } - assert(p); - le_write32(p->point[j].latitude, delbin_deg2rad(array[i]->latitude)); - le_write32(p->point[j].longitude, delbin_deg2rad(array[i]->longitude)); - i++; - j++; - if (j == pt_per_msg || i == n) { - p->number = j; - m.size = 10 + 8 * j; - add_to_batch(MSG_ROUTE_SHAPE_IN, &m); - j = 0; - } - } while (i < n); + message_t m; + const unsigned pt_per_msg = 25; + msg_route_shape_t* p = NULL; + unsigned i = 0; + unsigned j = 0; + + do { + if (j == 0) { + message_init_size(&m, 10 + 8 * pt_per_msg); + p = (msg_route_shape_t*) m.data; + le_write32(p->total, n); + le_write32(p->index, i + 1); + p->reserved = 0; + } + assert(p); + le_write32(p->point[j].latitude, delbin_deg2rad(array[i]->latitude)); + le_write32(p->point[j].longitude, delbin_deg2rad(array[i]->longitude)); + i++; + j++; + if (j == pt_per_msg || i == n) { + p->number = j; + m.size = 10 + 8 * j; + add_to_batch(MSG_ROUTE_SHAPE_IN, &m); + j = 0; + } + } while (i < n); } static void write_route_points(void) { - unsigned route_point_i = 0; - unsigned i = 0; - - while (i < waypoint_n) { - message_t m; - unsigned shape_n; - const waypoint* wp = wp_array[i]; - msg_route_point_t* p; - char* s; - - message_init_size(&m, sizeof(msg_route_point_t) + 1 + 1 + 4); - p = m.data; - memset(m.data, 0, m.size); - route_point_i++; - shape_n = shape_point_counts[route_point_i]; - le_write32(p->total, route_point_n); - le_write32(p->index, route_point_i); - if (wp->shortname) { - strncpy(p->name, wp->shortname, sizeof(p->name) - 1); - } else { - sprintf(p->name, "RPT%u", route_point_i); - } - le_write32(p->latitude, delbin_deg2rad(wp->latitude)); - le_write32(p->longitude, delbin_deg2rad(wp->longitude)); - p->exit_label_size = 1; - s = p->exit_label + p->exit_label_size; - s[0] = 1; // comment size - le_write32(s + 2, shape_n); - if (route_point_i == 1) { - p->itinerary_type = 1; // start - } else if (route_point_i == route_point_n) { - p->itinerary_type = 3; // finish - } - add_to_batch(MSG_ROUTE_POINT_IN, &m); - i++; - if (shape_n) { - write_route_shape_points(&wp_array[i], shape_n); - i += shape_n; - } - } + unsigned route_point_i = 0; + unsigned i = 0; + + while (i < waypoint_n) { + message_t m; + unsigned shape_n; + const waypoint* wp = wp_array[i]; + msg_route_point_t* p; + char* s; + + message_init_size(&m, sizeof(msg_route_point_t) + 1 + 1 + 4); + p = (msg_route_point_t*) m.data; + memset(m.data, 0, m.size); + route_point_i++; + shape_n = shape_point_counts[route_point_i]; + le_write32(p->total, route_point_n); + le_write32(p->index, route_point_i); + if (wp->shortname) { + strncpy(p->name, wp->shortname, sizeof(p->name) - 1); + } else { + sprintf(p->name, "RPT%u", route_point_i); + } + le_write32(p->latitude, delbin_deg2rad(wp->latitude)); + le_write32(p->longitude, delbin_deg2rad(wp->longitude)); + p->exit_label_size = 1; + s = p->exit_label + p->exit_label_size; + s[0] = 1; // comment size + le_write32(s + 2, shape_n); + if (route_point_i == 1) { + p->itinerary_type = 1; // start + } else if (route_point_i == route_point_n) { + p->itinerary_type = 3; // finish + } + add_to_batch(MSG_ROUTE_POINT_IN, &m); + i++; + if (shape_n) { + write_route_shape_points(&wp_array[i], shape_n); + i += shape_n; + } + } } static void write_route_begin(const route_head* track) { - waypoint_i = 0; - route_point_n = 0; - shape_point_n = 0; - waypoint_n = track->rte_waypt_ct; - if (waypoint_n) { - wp_array = xmalloc(waypoint_n * sizeof(*wp_array)); - shape_point_counts = xcalloc(waypoint_n, sizeof(*shape_point_counts)); - } + waypoint_i = 0; + route_point_n = 0; + shape_point_n = 0; + waypoint_n = track->rte_waypt_ct; + if (waypoint_n) { + wp_array = (waypoint**) xmalloc(waypoint_n * sizeof(*wp_array)); + shape_point_counts = (unsigned int*) xcalloc(waypoint_n, sizeof(*shape_point_counts)); + } } static void write_route_point(const waypoint* wp) { - const char* s = wp->shortname; - wp_array[waypoint_i++] = (waypoint*)wp; - if (s && s[0] == 'S' && s[1] == 'H' && s[2] == 'P' && s[3] >= '0' && s[3] <= '9') { - shape_point_n++; - shape_point_counts[route_point_n]++; - } else { - route_point_n++; - } + const char* s = wp->shortname; + wp_array[waypoint_i++] = (waypoint*)wp; + if (s && s[0] == 'S' && s[1] == 'H' && s[2] == 'P' && s[3] >= '0' && s[3] <= '9') { + shape_point_n++; + shape_point_counts[route_point_n]++; + } else { + route_point_n++; + } } static void write_route_end(const route_head* route) { - message_t m; - msg_route_header_in_t* p; - - if (waypoint_n == 0) { - return; - } - message_init_size(&m, sizeof(msg_route_header_in_t)); - p = m.data; - memset(p->name, 0, sizeof(p->name)); - if (route->rte_name) { - strncpy(p->name, route->rte_name, sizeof(p->name) - 1); - } else { - sprintf(p->name, "%lu", (long)wp_array[0]->creation_time); - } - p->type = 0; - le_write32(p->total_route_point, route_point_n); - le_write32(p->total_shape_point, shape_point_n); - add_to_batch(MSG_ROUTE_HEADER_IN, &m); - write_route_points(); - send_batch(); - if (wp_array) { - xfree(wp_array); - xfree(shape_point_counts); - } + message_t m; + msg_route_header_in_t* p; + + if (waypoint_n == 0) { + return; + } + message_init_size(&m, sizeof(msg_route_header_in_t)); + p = (msg_route_header_in_t*) m.data; + memset(p->name, 0, sizeof(p->name)); + if (route->rte_name) { + strncpy(p->name, route->rte_name, sizeof(p->name) - 1); + } else { + sprintf(p->name, "%lu", (long)wp_array[0]->creation_time); + } + p->type = 0; + le_write32(p->total_route_point, route_point_n); + le_write32(p->total_shape_point, shape_point_n); + add_to_batch(MSG_ROUTE_HEADER_IN, &m); + write_route_points(); + send_batch(); + if (wp_array) { + xfree(wp_array); + xfree(shape_point_counts); + } } static void write_routes(void) { - route_disp_all(write_route_begin, write_route_end, write_route_point); + route_disp_all(write_route_begin, write_route_end, write_route_point); } //----------------------------------------------------------------------------- @@ -2080,54 +2212,53 @@ write_routes(void) static waypoint* decode_navmsg(const void* data) { - waypoint* wp = waypt_new(); - const msg_navigation_t* p = data; - struct tm t; - - t.tm_year = le_readu16(p->year) - 1900; - t.tm_mon = p->month - 1; - t.tm_mday = p->day; - t.tm_hour = p->hour; - t.tm_min = p->minute; - t.tm_sec = p->second; - wp->creation_time = mkgmtime(&t); - wp->sat = p->satellites; - wp->latitude = le_read_double(p->latitude); - wp->longitude = le_read_double(p->longitude); - wp->altitude = le_read_double(p->elevation); - wp->speed = le_read_float(p->speed); - wp->speed *= (1000.0f / (60 * 60)); - wp->wpt_flags.speed = 1; - wp->course = le_readu16(p->heading); - wp->course /= 100; - wp->wpt_flags.course = 1; - decode_sat_fix(wp, p->fix_status); - wp->shortname = xstrdup("Position"); - return wp; + waypoint* wp = waypt_new(); + const msg_navigation_t* p = (const msg_navigation_t*) data; + struct tm t; + + t.tm_year = le_readu16(p->year) - 1900; + t.tm_mon = p->month - 1; + t.tm_mday = p->day; + t.tm_hour = p->hour; + t.tm_min = p->minute; + t.tm_sec = p->second; + wp->creation_time = mkgmtime(&t); + wp->sat = p->satellites; + wp->latitude = le_read_double(p->latitude); + wp->longitude = le_read_double(p->longitude); + wp->altitude = le_read_double(p->elevation); + wp->speed = le_read_float(p->speed); + wp->speed *= (1000.0f / (60 * 60)); + wp->wpt_flags.speed = 1; + wp->course = le_readu16(p->heading); + wp->course /= 100; + wp->wpt_flags.course = 1; + decode_sat_fix(wp, p->fix_status); + wp->shortname = xstrdup("Position"); + return wp; } static waypoint* read_position(void) { - waypoint* wp; - message_t m; - - message_init(&m); - message_read(MSG_NAVIGATION, &m); - wp = decode_navmsg(m.data); - if (wp->fix > fix_none && - message_read_1(MSG_SATELLITE_INFO, &m) == MSG_SATELLITE_INFO) - { - const msg_satellite_t* p = m.data; - wp->hdop = le_readu16(p->hdop); - wp->hdop /= 100; - wp->vdop = le_readu16(p->vdop); - wp->vdop /= 100; - wp->pdop = le_readu16(p->pdop); - wp->pdop /= 100; - } - message_free(&m); - return wp; + waypoint* wp; + message_t m; + + message_init(&m); + message_read(MSG_NAVIGATION, &m); + wp = decode_navmsg(m.data); + if (wp->fix > fix_none && + message_read_1(MSG_SATELLITE_INFO, &m) == MSG_SATELLITE_INFO) { + const msg_satellite_t* p = (const msg_satellite_t*) m.data; + wp->hdop = le_readu16(p->hdop); + wp->hdop /= 100; + wp->vdop = le_readu16(p->vdop); + wp->vdop /= 100; + wp->pdop = le_readu16(p->pdop); + wp->pdop /= 100; + } + message_free(&m); + return wp; } //----------------------------------------------------------------------------- @@ -2135,147 +2266,155 @@ read_position(void) static void delbin_list_units() { - int i; - for (i = 0; i < n_delbin_units; i++) { - printf("%u %s %s\n", - delbin_unit_info[i].unit_number, - delbin_unit_info[i].unit_serial_number, - delbin_unit_info[i].unit_name ); - } + int i; + for (i = 0; i < n_delbin_units; i++) { + printf("%u %s %s\n", + delbin_unit_info[i].unit_number, + delbin_unit_info[i].unit_serial_number, + delbin_unit_info[i].unit_name); + } } static void -delbin_rw_init(const char *fname) -{ - message_t m; - char buf[256]; - - if (!mkshort_handle) - mkshort_handle = mkshort_new_handle(); - // Contrary to doc, it looks like there's a limit of 32 bytes - // and a null terminator is required, at least in F/W 2.6.210726 - // on a PN-40. - setshort_length(mkshort_handle, 31); - setshort_whitespace_ok(mkshort_handle, 1); - setshort_badchars(mkshort_handle, ""); - setshort_mustuniq(mkshort_handle, 1); - - delbin_os_ops.init(fname); - - // Often the first packet is part of an old message, sometimes it can - // confuse the first message read if we don't get rid of it - packet_read(buf); - // Send a break to clear any state from a previous failure - message_init_size(&m, MSG_BREAK_SIZE); - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - // get version info - m.size = 0; - message_write(MSG_VERSION, &m); - if (message_read(MSG_VERSION, &m)) { - const msg_version_t* p = m.data; - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": device %s %s\n", p->product, p->firmware); - if (opt_long_notes) { - use_extended_notes = TRUE; - } else if (strstr(p->product, "PN-20")) { - use_extended_notes = p->firmware[0] > '1' || - (p->firmware[0] == '1' && p->firmware[2] >= '6'); - } else if (strstr(p->product, "PN-30") || strstr(p->product, "PN-40")) { - use_extended_notes = p->firmware[0] > '2' || - (p->firmware[0] == '2' && p->firmware[2] >= '5'); - } else { - // assume PN-60 or later - use_extended_notes = TRUE; - } - delbin_unit_info[n_delbin_units].unit_number = n_delbin_units; - delbin_unit_info[n_delbin_units].unit_serial_number = xstrndup(p->serial, sizeof(p->serial)); - delbin_unit_info[n_delbin_units].unit_name = xstrndup(p->product, sizeof(p->product)); - n_delbin_units++; - } - message_free(&m); - - if (strlen(fname) > 4) { - if (0 == strcmp(fname+4, "list")) { - delbin_list_units(); - exit(1); - } - } +delbin_rw_init(const char* fname) +{ + message_t m; + char buf[256]; + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + // Contrary to doc, it looks like there's a limit of 32 bytes + // and a null terminator is required, at least in F/W 2.6.210726 + // on a PN-40. + setshort_length(mkshort_handle, 31); + setshort_whitespace_ok(mkshort_handle, 1); + setshort_badchars(mkshort_handle, ""); + setshort_mustuniq(mkshort_handle, 1); + + delbin_os_ops.init(fname); + + // Often the first packet is part of an old message, sometimes it can + // confuse the first message read if we don't get rid of it + packet_read(buf); + // Send a break to clear any state from a previous failure + message_init_size(&m, MSG_BREAK_SIZE); + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + // get version info + m.size = 0; + message_write(MSG_VERSION, &m); + if (message_read(MSG_VERSION, &m)) { + const msg_version_t* p = (const msg_version_t*) m.data; + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": device %s %s\n", p->product, p->firmware); + } + if (opt_long_notes) { + use_extended_notes = TRUE; + } else if (strstr(p->product, "PN-20")) { + use_extended_notes = p->firmware[0] > '1' || + (p->firmware[0] == '1' && p->firmware[2] >= '6'); + } else if (strstr(p->product, "PN-30") || strstr(p->product, "PN-40")) { + use_extended_notes = p->firmware[0] > '2' || + (p->firmware[0] == '2' && p->firmware[2] >= '5'); + } else { + // assume PN-60 or later + use_extended_notes = TRUE; + } + delbin_unit_info[n_delbin_units].unit_number = n_delbin_units; + delbin_unit_info[n_delbin_units].unit_serial_number = xstrndup(p->serial, sizeof(p->serial)); + delbin_unit_info[n_delbin_units].unit_name = xstrndup(p->product, sizeof(p->product)); + n_delbin_units++; + } + message_free(&m); + + if (strlen(fname) > 4) { + if (0 == strcmp(fname+4, "list")) { + delbin_list_units(); + exit(1); + } + } } static void delbin_rw_deinit(void) { - if (mkshort_handle) { - mkshort_del_handle(&mkshort_handle); - } - delbin_os_ops.deinit(); + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } + delbin_os_ops.deinit(); } static void delbin_read(void) { - if (doing_wpts) { - if (opt_getposn) { - waypt_add(read_position()); - } else { - read_waypoints(); - } - } - if (doing_trks) { - read_tracks(); - } - if (doing_rtes) { - read_routes(); - } + if (doing_wpts) { + if (opt_getposn) { + waypt_add(read_position()); + } else { + read_waypoints(); + } + } + if (doing_trks) { + read_tracks(); + } + if (doing_rtes) { + read_routes(); + } } static void delbin_write(void) { - if (doing_wpts) { - message_t m; - device_max_waypoint = 1000; - message_init_size(&m, 0); - message_write(MSG_CAPABILITIES, &m); - if (message_read(MSG_CAPABILITIES, &m)) { - const msg_capabilities_t* p = m.data; - device_max_waypoint = le_readu32(p->max_waypoints); - } - message_free(&m); - - if (opt_nuke_wpt) add_nuke(nuke_type_wpt); - write_waypoints(); - } - if (doing_trks) { - if (opt_nuke_trk) add_nuke(nuke_type_trk); - write_tracks(); - } - if (doing_rtes) { - if (opt_nuke_rte) add_nuke(nuke_type_rte); - write_routes(); - } + if (doing_wpts) { + message_t m; + device_max_waypoint = 1000; + message_init_size(&m, 0); + message_write(MSG_CAPABILITIES, &m); + if (message_read(MSG_CAPABILITIES, &m)) { + const msg_capabilities_t* p = (const msg_capabilities_t*) m.data; + device_max_waypoint = le_readu32(p->max_waypoints); + } + message_free(&m); + + if (opt_nuke_wpt) { + add_nuke(nuke_type_wpt); + } + write_waypoints(); + } + if (doing_trks) { + if (opt_nuke_trk) { + add_nuke(nuke_type_trk); + } + write_tracks(); + } + if (doing_rtes) { + if (opt_nuke_rte) { + add_nuke(nuke_type_rte); + } + write_routes(); + } } static waypoint* delbin_rd_position(posn_status* status) { - return read_position(); + return read_position(); } ff_vecs_t delbin_vecs = { - ff_type_serial, - FF_CAP_RW_ALL, - delbin_rw_init, - delbin_rw_init, - delbin_rw_deinit, - delbin_rw_deinit, - delbin_read, - delbin_write, - NULL, - delbin_args, - CET_CHARSET_LATIN1, 1, - { delbin_rw_init, delbin_rd_position, delbin_rw_deinit } + ff_type_serial, + FF_CAP_RW_ALL, + delbin_rw_init, + delbin_rw_init, + delbin_rw_deinit, + delbin_rw_deinit, + delbin_read, + delbin_write, + NULL, + delbin_args, + CET_CHARSET_LATIN1, 1, + { delbin_rw_init, delbin_rd_position, delbin_rw_deinit } }; //============================================================================= @@ -2286,14 +2425,14 @@ ff_vecs_t delbin_vecs = { //----------------------------------------------------------------------------- // Windows -#if _WIN32 +#ifdef HAVE_WDK #undef HAVE_LIBUSB #define WIN32_LEAN_AND_MEAN #include #include -// If hidsdi.h is not found, you need to download the Windows Driver Kit, +// If hidsdi.h is not found, you need to download the Windows Driver Kit, // from http://www.microsoft.com/whdc/Devtools/wdk/default.mspx // You need to install 'build environments' and 'tools' from the SDK and // follow the instructions in the Install.html to get MSVC to find the right @@ -2306,115 +2445,112 @@ static HANDLE hid_handle; static void win_os_init(const char* fname) { - GUID hid_guid; - HDEVINFO dev_info; - SP_DEVICE_INTERFACE_DATA dev_int_data; - PHIDP_PREPARSED_DATA hid_ppd; - HIDP_CAPS hid_caps; - const char* busy = ""; - unsigned i; - - hid_handle = INVALID_HANDLE_VALUE; - HidD_GetHidGuid(&hid_guid); - dev_info = SetupDiGetClassDevs(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); - if (dev_info == INVALID_HANDLE_VALUE) { - fatal(MYNAME ": SetupDiGetClassDevs failed %u\n", GetLastError()); - } - dev_int_data.cbSize = sizeof(dev_int_data); - for (i = 0; SetupDiEnumDeviceInterfaces(dev_info, NULL, &hid_guid, i, &dev_int_data); i++) { - union { - SP_DEVICE_INTERFACE_DETAIL_DATA detail_data; - char buf[300]; - } u; - u.detail_data.cbSize = sizeof(u.detail_data); - if (SetupDiGetDeviceInterfaceDetail(dev_info, - &dev_int_data, &u.detail_data, sizeof(u.buf), NULL, NULL)) - { - HANDLE h = CreateFile(u.detail_data.DevicePath, - FILE_READ_DATA | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, 0, NULL); - if (h != INVALID_HANDLE_VALUE) { - HIDD_ATTRIBUTES hid_attr; - hid_attr.Size = sizeof(hid_attr); - if (HidD_GetAttributes(h, &hid_attr) && - hid_attr.VendorID == VENDOR_ID && hid_attr.ProductID == PRODUCT_ID) - { - hid_handle = h; - break; - } - CloseHandle(h); - } else if (GetLastError() == ERROR_SHARING_VIOLATION && - strstr(u.detail_data.DevicePath, "1163") && - strstr(u.detail_data.DevicePath, "2020")) - { - busy = " (device busy?)"; - } - } - } - SetupDiDestroyDeviceInfoList(dev_info); - if (hid_handle == INVALID_HANDLE_VALUE) { - fatal(MYNAME ": no DeLorme PN found%s\n", busy); - } - if (!HidD_GetPreparsedData(hid_handle, &hid_ppd)) { - fatal(MYNAME ": HidD_GetPreparsedData failed %u\n", GetLastError()); - } - if (!HidP_GetCaps(hid_ppd, &hid_caps)) { - fatal(MYNAME ": HidP_GetCaps failed %u\n", GetLastError()); - } - // report length includes report id - delbin_os_packet_size = hid_caps.InputReportByteLength - 1; - HidD_FreePreparsedData(hid_ppd); + GUID hid_guid; + HDEVINFO dev_info; + SP_DEVICE_INTERFACE_DATA dev_int_data; + PHIDP_PREPARSED_DATA hid_ppd; + HIDP_CAPS hid_caps; + const char* busy = ""; + unsigned i; + + hid_handle = INVALID_HANDLE_VALUE; + HidD_GetHidGuid(&hid_guid); + dev_info = SetupDiGetClassDevs(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + if (dev_info == INVALID_HANDLE_VALUE) { + fatal(MYNAME ": SetupDiGetClassDevs failed %u\n", GetLastError()); + } + dev_int_data.cbSize = sizeof(dev_int_data); + for (i = 0; SetupDiEnumDeviceInterfaces(dev_info, NULL, &hid_guid, i, &dev_int_data); i++) { + union { + SP_DEVICE_INTERFACE_DETAIL_DATA detail_data; + char buf[300]; + } u; + u.detail_data.cbSize = sizeof(u.detail_data); + if (SetupDiGetDeviceInterfaceDetail(dev_info, + &dev_int_data, &u.detail_data, sizeof(u.buf), NULL, NULL)) { + HANDLE h = CreateFile(u.detail_data.DevicePath, + FILE_READ_DATA | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, 0, NULL); + if (h != INVALID_HANDLE_VALUE) { + HIDD_ATTRIBUTES hid_attr; + hid_attr.Size = sizeof(hid_attr); + if (HidD_GetAttributes(h, &hid_attr) && + hid_attr.VendorID == VENDOR_ID && hid_attr.ProductID == PRODUCT_ID) { + hid_handle = h; + break; + } + CloseHandle(h); + } else if (GetLastError() == ERROR_SHARING_VIOLATION && + strstr(u.detail_data.DevicePath, "1163") && + strstr(u.detail_data.DevicePath, "2020")) { + busy = " (device busy?)"; + } + } + } + SetupDiDestroyDeviceInfoList(dev_info); + if (hid_handle == INVALID_HANDLE_VALUE) { + fatal(MYNAME ": no DeLorme PN found%s\n", busy); + } + if (!HidD_GetPreparsedData(hid_handle, &hid_ppd)) { + fatal(MYNAME ": HidD_GetPreparsedData failed %u\n", GetLastError()); + } + if (!HidP_GetCaps(hid_ppd, &hid_caps)) { + fatal(MYNAME ": HidP_GetCaps failed %u\n", GetLastError()); + } + // report length includes report id + delbin_os_packet_size = hid_caps.InputReportByteLength - 1; + HidD_FreePreparsedData(hid_ppd); } static void win_os_deinit(void) { - CloseHandle(hid_handle); + CloseHandle(hid_handle); } static unsigned win_os_packet_read(void* buf) { - DWORD n; - char buf1[257]; - // first byte is report id - if (ReadFile(hid_handle, buf1, delbin_os_packet_size + 1, &n, NULL) == 0) { - unsigned err = GetLastError(); - fatal(MYNAME ": ReadFile failed %u\n", err); - } - if (n > 0) { - n--; - } - memcpy(buf, buf1 + 1, n); - return n; + DWORD n; + char buf1[257]; + // first byte is report id + if (ReadFile(hid_handle, buf1, delbin_os_packet_size + 1, &n, NULL) == 0) { + unsigned err = GetLastError(); + fatal(MYNAME ": ReadFile failed %u\n", err); + } + if (n > 0) { + n--; + } + memcpy(buf, buf1 + 1, n); + return n; } static unsigned win_os_packet_write(const void* buf, unsigned size) { - DWORD n; - char buf1[257]; - // first byte is report id - buf1[0] = 0; - memcpy(buf1 + 1, buf, size); - if (WriteFile(hid_handle, buf1, delbin_os_packet_size + 1, &n, NULL) == 0) { - unsigned err = GetLastError(); - fatal(MYNAME ": WriteFile of %u bytes failed with %u. Size: %u Wrote: %d\n", - delbin_os_packet_size + 1, err, size, (int) n); - } - if (n > size) { - n = size; - } - return n; + DWORD n; + char buf1[257]; + // first byte is report id + buf1[0] = 0; + memcpy(buf1 + 1, buf, size); + if (WriteFile(hid_handle, buf1, delbin_os_packet_size + 1, &n, NULL) == 0) { + unsigned err = GetLastError(); + fatal(MYNAME ": WriteFile of %u bytes failed with %u. Size: %u Wrote: %d\n", + delbin_os_packet_size + 1, err, size, (int) n); + } + if (n > size) { + n = size; + } + return n; } delbin_os_ops_t delbin_os_ops = { - win_os_init, - win_os_deinit, - win_os_packet_read, - win_os_packet_write + win_os_init, + win_os_deinit, + win_os_packet_read, + win_os_packet_write }; -#endif // _WIN32 +#endif // HAVE_WDK //----------------------------------------------------------------------------- // MacOS X @@ -2445,125 +2581,136 @@ static CFRunLoopRef run_loop; static void* thread_func(void* run_loop_source) { - run_loop = CFRunLoopGetCurrent(); - CFRunLoopAddSource(run_loop, run_loop_source, kCFRunLoopDefaultMode); - CFRunLoopRun(); - return NULL; + run_loop = CFRunLoopGetCurrent(); +#if __cplusplus + CFRunLoopAddSource(run_loop, (__CFRunLoopSource*) run_loop_source, kCFRunLoopDefaultMode); +#else + CFRunLoopAddSource(run_loop, run_loop_source, kCFRunLoopDefaultMode); +#endif + CFRunLoopRun(); + return NULL; } static void interrupt_report_cb(void* target, IOReturn result, void* refcon, void* sender, UInt32 bufferSize) { - memcpy(packet_array[packet_array_head], report_buf, delbin_os_packet_size); - pthread_mutex_lock(&mutex); - if (packet_array_head == packet_array_tail) { - pthread_cond_signal(&cond); - } - packet_array_head++; - packet_array_head &= sizeofarray(packet_array) - 1; - if (packet_array_head == packet_array_tail && global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": packet_array overrun, packets lost\n"); - pthread_mutex_unlock(&mutex); + memcpy(packet_array[packet_array_head], report_buf, delbin_os_packet_size); + pthread_mutex_lock(&mutex); + if (packet_array_head == packet_array_tail) { + pthread_cond_signal(&cond); + } + packet_array_head++; + packet_array_head &= sizeofarray(packet_array) - 1; + if (packet_array_head == packet_array_tail && global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": packet_array overrun, packets lost\n"); + } + pthread_mutex_unlock(&mutex); } static void mac_os_init(const char* fname) { - CFMutableDictionaryRef dict = IOServiceMatching(kIOHIDDeviceKey); - io_service_t service; - IOCFPlugInInterface** plugin; - CFNumberRef cf_num; - CFRunLoopSourceRef run_loop_source; - int i; - kern_return_t kr; - HRESULT hr; - IOReturn ir; - SInt32 unused; - - i = VENDOR_ID; - cf_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); - CFDictionaryAddValue(dict, CFSTR(kIOHIDVendorIDKey), cf_num); - CFRelease(cf_num); - i = PRODUCT_ID; - cf_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); - CFDictionaryAddValue(dict, CFSTR(kIOHIDProductIDKey), cf_num); - CFRelease(cf_num); - service = IOServiceGetMatchingService(kIOMasterPortDefault, dict); - if (service == 0) { - fatal(MYNAME ": no DeLorme PN found\n"); - } - kr = IOCreatePlugInInterfaceForService( - service, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &unused); - if (kr) - fatal(MYNAME ": IOCreatePlugInInterfaceForService failed 0x%x\n", (int)kr); - IOObjectRelease(service); - hr = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), (void*)&device); - if (hr) - fatal(MYNAME ": QueryInterface failed 0x%x\n", (int)hr); - (*plugin)->Release(plugin); - ir = (*device)->open(device, kIOHIDOptionsTypeSeizeDevice); - if (ir) - fatal(MYNAME ": device open failed 0x%x - %s\n", (int)ir, - mach_error_string(ir)); - ir = (*device)->createAsyncEventSource(device, &run_loop_source); - if (ir) - fatal(MYNAME ": createAsyncEventSource failed 0x%x\n", (int)ir); - delbin_os_packet_size = 64; - report_buf = xmalloc(delbin_os_packet_size); - for (i = sizeofarray(packet_array); i--;) { - packet_array[i] = xmalloc(delbin_os_packet_size); - } - ir = (*device)->setInterruptReportHandlerCallback( - device, report_buf, delbin_os_packet_size, interrupt_report_cb, NULL, NULL); - if (ir) - fatal(MYNAME ": setInterruptReportHandlerCallback failed 0x%x\n", (int)ir); - i = pthread_create(&thread, NULL, thread_func, run_loop_source); - if (i) - fatal(MYNAME ": pthread_create failed %d\n", i); + CFMutableDictionaryRef dict = IOServiceMatching(kIOHIDDeviceKey); + io_service_t service; + IOCFPlugInInterface** plugin; + CFNumberRef cf_num; + CFRunLoopSourceRef run_loop_source; + int i; + kern_return_t kr; + HRESULT hr; + IOReturn ir; + SInt32 unused; + + i = VENDOR_ID; + cf_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); + CFDictionaryAddValue(dict, CFSTR(kIOHIDVendorIDKey), cf_num); + CFRelease(cf_num); + i = PRODUCT_ID; + cf_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); + CFDictionaryAddValue(dict, CFSTR(kIOHIDProductIDKey), cf_num); + CFRelease(cf_num); + service = IOServiceGetMatchingService(kIOMasterPortDefault, dict); + if (service == 0) { + fatal(MYNAME ": no DeLorme PN found\n"); + } + kr = IOCreatePlugInInterfaceForService( + service, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &unused); + if (kr) { + fatal(MYNAME ": IOCreatePlugInInterfaceForService failed 0x%x\n", (int)kr); + } + IOObjectRelease(service); + hr = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), (void**)&device); + if (hr) { + fatal(MYNAME ": QueryInterface failed 0x%x\n", (int)hr); + } + (*plugin)->Release(plugin); + ir = (*device)->open(device, kIOHIDOptionsTypeSeizeDevice); + if (ir) + fatal(MYNAME ": device open failed 0x%x - %s\n", (int)ir, + mach_error_string(ir)); + ir = (*device)->createAsyncEventSource(device, &run_loop_source); + if (ir) { + fatal(MYNAME ": createAsyncEventSource failed 0x%x\n", (int)ir); + } + delbin_os_packet_size = 64; + report_buf = (char*)xmalloc(delbin_os_packet_size); + for (i = sizeofarray(packet_array); i--;) { + packet_array[i] = (char*)xmalloc(delbin_os_packet_size); + } + ir = (*device)->setInterruptReportHandlerCallback( + device, report_buf, delbin_os_packet_size, interrupt_report_cb, NULL, NULL); + if (ir) { + fatal(MYNAME ": setInterruptReportHandlerCallback failed 0x%x\n", (int)ir); + } + i = pthread_create(&thread, NULL, thread_func, run_loop_source); + if (i) { + fatal(MYNAME ": pthread_create failed %d\n", i); + } } static void mac_os_deinit(void) { - void* unused; - unsigned i; - CFRunLoopStop(run_loop); - pthread_join(thread, &unused); - (*device)->Release(device); - xfree(report_buf); - for (i = sizeofarray(packet_array); i--;) { - xfree(packet_array[i]); - } + void* unused; + unsigned i; + CFRunLoopStop(run_loop); + pthread_join(thread, &unused); + (*device)->Release(device); + xfree(report_buf); + for (i = sizeofarray(packet_array); i--;) { + xfree(packet_array[i]); + } } static unsigned mac_os_packet_read(void* buf) { - pthread_mutex_lock(&mutex); - while (packet_array_head == packet_array_tail) { - pthread_cond_wait(&cond, &mutex); - } - memcpy(buf, packet_array[packet_array_tail++], delbin_os_packet_size); - packet_array_tail &= sizeofarray(packet_array) - 1; - pthread_mutex_unlock(&mutex); - return delbin_os_packet_size; + pthread_mutex_lock(&mutex); + while (packet_array_head == packet_array_tail) { + pthread_cond_wait(&cond, &mutex); + } + memcpy(buf, packet_array[packet_array_tail++], delbin_os_packet_size); + packet_array_tail &= sizeofarray(packet_array) - 1; + pthread_mutex_unlock(&mutex); + return delbin_os_packet_size; } static unsigned mac_os_packet_write(const void* buf, unsigned size) { - IOReturn r = (*device)->setReport( - device, kIOHIDReportTypeOutput, 0, (void*)buf, size, 2000, NULL, NULL, NULL); - if (r) - fatal("setReport failed 0x%x\n", (int)r); - return size; + IOReturn r = (*device)->setReport( + device, kIOHIDReportTypeOutput, 0, (void*)buf, size, 2000, NULL, NULL, NULL); + if (r) { + fatal("setReport failed 0x%x\n", (int)r); + } + return size; } delbin_os_ops_t delbin_os_ops = { - mac_os_init, - mac_os_deinit, - mac_os_packet_read, - mac_os_packet_write + mac_os_init, + mac_os_deinit, + mac_os_packet_read, + mac_os_packet_write }; #endif // __APPLE__ @@ -2582,79 +2729,79 @@ static int endpoint_out; static void libusb_os_init(const char* fname) { - struct usb_bus* bus; - const struct usb_endpoint_descriptor* endpoint_desc; - - usb_init(); - usb_find_busses(); - usb_find_devices(); - for (bus = usb_busses; usb_dev == NULL && bus; bus = bus->next) { - struct usb_device* d; - for (d = bus->devices; d; d = d->next) { - if (d->descriptor.idVendor == VENDOR_ID && d->descriptor.idProduct == PRODUCT_ID) { - usb_dev = d; - break; - } - } - } - if (usb_dev == NULL) { - fatal(MYNAME ": no DeLorme PN found\n"); - } - usb_handle = usb_open(usb_dev); - if (usb_handle == NULL) { - fatal(MYNAME ": %s\n", usb_strerror()); - } - - // Device has 1 configuration, 1 interface, 2 interrupt endpoints - if (usb_claim_interface(usb_handle, 0) < 0) { + struct usb_bus* bus; + const struct usb_endpoint_descriptor* endpoint_desc; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + for (bus = usb_busses; usb_dev == NULL && bus; bus = bus->next) { + struct usb_device* d; + for (d = bus->devices; d; d = d->next) { + if (d->descriptor.idVendor == VENDOR_ID && d->descriptor.idProduct == PRODUCT_ID) { + usb_dev = d; + break; + } + } + } + if (usb_dev == NULL) { + fatal(MYNAME ": no DeLorme PN found\n"); + } + usb_handle = usb_open(usb_dev); + if (usb_handle == NULL) { + fatal(MYNAME ": %s\n", usb_strerror()); + } + + // Device has 1 configuration, 1 interface, 2 interrupt endpoints + if (usb_claim_interface(usb_handle, 0) < 0) { #if LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP - if (usb_detach_kernel_driver_np(usb_handle, 0) < 0) { - warning(MYNAME ": %s\n", usb_strerror()); - } - if (usb_claim_interface(usb_handle, 0) < 0) + if (usb_detach_kernel_driver_np(usb_handle, 0) < 0) { + warning(MYNAME ": %s\n", usb_strerror()); + } + if (usb_claim_interface(usb_handle, 0) < 0) #endif - { - const char* s = usb_strerror(); - usb_close(usb_handle); - fatal(MYNAME ": %s\n", s); - } - } - endpoint_desc = usb_dev->config[0].interface[0].altsetting[0].endpoint; - delbin_os_packet_size = endpoint_desc[0].wMaxPacketSize; - endpoint_in = endpoint_desc[0].bEndpointAddress; - endpoint_out = endpoint_desc[1].bEndpointAddress; - if ((endpoint_in & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT) { - int t = endpoint_in; - endpoint_in = endpoint_out; - endpoint_out = t; - } + { + const char* s = usb_strerror(); + usb_close(usb_handle); + fatal(MYNAME ": %s\n", s); + } + } + endpoint_desc = usb_dev->config[0].interface[0].altsetting[0].endpoint; + delbin_os_packet_size = endpoint_desc[0].wMaxPacketSize; + endpoint_in = endpoint_desc[0].bEndpointAddress; + endpoint_out = endpoint_desc[1].bEndpointAddress; + if ((endpoint_in & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT) { + int t = endpoint_in; + endpoint_in = endpoint_out; + endpoint_out = t; + } } static void libusb_os_deinit(void) { - usb_release_interface(usb_handle, 0); - usb_close(usb_handle); + usb_release_interface(usb_handle, 0); + usb_close(usb_handle); } static unsigned libusb_os_packet_read(void* buf) { - int n = usb_interrupt_read(usb_handle, endpoint_in, buf, delbin_os_packet_size, 2000); - if (n < 0) { - fatal(MYNAME ": %s\n", usb_strerror()); - } - return n; + int n = usb_interrupt_read(usb_handle, endpoint_in, buf, delbin_os_packet_size, 2000); + if (n < 0) { + fatal(MYNAME ": %s\n", usb_strerror()); + } + return n; } static unsigned libusb_os_packet_write(const void* buf, unsigned size) { - int n = usb_interrupt_write(usb_handle, endpoint_out, (char*)buf, size, 2000); - if (n < 0) { - fatal(MYNAME ": %s\n", usb_strerror()); - } - return n; + int n = usb_interrupt_write(usb_handle, endpoint_out, (char*)buf, size, 2000); + if (n < 0) { + fatal(MYNAME ": %s\n", usb_strerror()); + } + return n; } #if HAVE_LINUX_HID @@ -2663,10 +2810,10 @@ static const delbin_os_ops_t libusb_os_ops = delbin_os_ops_t delbin_os_ops = #endif { - libusb_os_init, - libusb_os_deinit, - libusb_os_packet_read, - libusb_os_packet_write + libusb_os_init, + libusb_os_deinit, + libusb_os_packet_read, + libusb_os_packet_write }; #endif // HAVE_LIBUSB @@ -2694,172 +2841,176 @@ static int linuxhid_os_init_status; static void linuxhid_os_init(const char* fname) { - struct hidraw_devinfo info; - struct hiddev_field_info finfo; - DIR* dir = NULL; - struct dirent* d; - - fd_hidraw = fd_hiddev = -1; - if (fname && memcmp(fname, "hid:", 4) == 0) { - char* raw_name = xstrdup(fname + 4); - char* dev_name = strchr(raw_name, ','); - if (dev_name == NULL) { - fatal(MYNAME ": missing hiddev path\n"); - } - *dev_name++ = 0; - fd_hidraw = open(raw_name, O_RDONLY); - if (fd_hidraw < 0) { - fatal(MYNAME ": %s: %s\n", raw_name, strerror(errno)); - } - fd_hiddev = open(dev_name, O_WRONLY); - if (fd_hiddev < 0) { - fatal(MYNAME ": %s: %s\n", dev_name, strerror(errno)); - } - xfree(raw_name); - } else { - dir = opendir("/dev"); - } - while (dir && (d = readdir(dir)) != NULL) { - if (strncmp(d->d_name, "hidraw", 6) == 0) { - int fd1, fd2; - char raw_name[32]; - char dev_name[32]; - sprintf(raw_name, "/dev/%s", d->d_name); - fd1 = open(raw_name, O_RDONLY); - if (fd1 < 0) { - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": %s: %s\n", raw_name, strerror(errno)); - continue; - } - sprintf(dev_name, "/dev/usb/hiddev%s", raw_name + sizeof("/dev/hidraw") - 1); - fd2 = open(dev_name, O_WRONLY); - if (fd2 < 0 && errno == ENOENT) { - sprintf(dev_name, "/dev/hiddev%s", raw_name + sizeof("/dev/hidraw") - 1); - fd2 = open(dev_name, O_WRONLY); - } - if (fd2 < 0) { - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": %s: %s\n", dev_name, strerror(errno)); - close(fd1); - continue; - } - if (ioctl(fd1, HIDIOCGRAWINFO, &info) == 0 && - info.vendor == VENDOR_ID && info.product == PRODUCT_ID) - { - fd_hidraw = fd1; - fd_hiddev = fd2; - break; - } - close(fd1); - close(fd2); - } - } - if (dir) { - closedir(dir); - } - if (fd_hidraw < 0) { - if (linuxhid_os_init_status == 0) - fatal(MYNAME ": no DeLorme PN found\n"); - return; - } - finfo.report_type = HID_REPORT_TYPE_INPUT; - finfo.report_id = 0; - finfo.field_index = 0; - if (ioctl(fd_hiddev, HIDIOCGFIELDINFO, &finfo) < 0) { - warning(MYNAME ": HIDIOCGFIELDINFO: %s\n", strerror(errno)); - if (linuxhid_os_init_status == 0) - exit(1); - return; - } - delbin_os_packet_size = finfo.maxusage; - linuxhid_os_init_status = 0; + struct hidraw_devinfo info; + struct hiddev_field_info finfo; + DIR* dir = NULL; + struct dirent* d; + + fd_hidraw = fd_hiddev = -1; + if (fname && memcmp(fname, "hid:", 4) == 0) { + char* raw_name = xstrdup(fname + 4); + char* dev_name = strchr(raw_name, ','); + if (dev_name == NULL) { + fatal(MYNAME ": missing hiddev path\n"); + } + *dev_name++ = 0; + fd_hidraw = open(raw_name, O_RDONLY); + if (fd_hidraw < 0) { + fatal(MYNAME ": %s: %s\n", raw_name, strerror(errno)); + } + fd_hiddev = open(dev_name, O_WRONLY); + if (fd_hiddev < 0) { + fatal(MYNAME ": %s: %s\n", dev_name, strerror(errno)); + } + xfree(raw_name); + } else { + dir = opendir("/dev"); + } + while (dir && (d = readdir(dir)) != NULL) { + if (strncmp(d->d_name, "hidraw", 6) == 0) { + int fd1, fd2; + char raw_name[32]; + char dev_name[32]; + sprintf(raw_name, "/dev/%s", d->d_name); + fd1 = open(raw_name, O_RDONLY); + if (fd1 < 0) { + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": %s: %s\n", raw_name, strerror(errno)); + } + continue; + } + sprintf(dev_name, "/dev/usb/hiddev%s", raw_name + sizeof("/dev/hidraw") - 1); + fd2 = open(dev_name, O_WRONLY); + if (fd2 < 0 && errno == ENOENT) { + sprintf(dev_name, "/dev/hiddev%s", raw_name + sizeof("/dev/hidraw") - 1); + fd2 = open(dev_name, O_WRONLY); + } + if (fd2 < 0) { + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": %s: %s\n", dev_name, strerror(errno)); + } + close(fd1); + continue; + } + if (ioctl(fd1, HIDIOCGRAWINFO, &info) == 0 && + info.vendor == VENDOR_ID && info.product == PRODUCT_ID) { + fd_hidraw = fd1; + fd_hiddev = fd2; + break; + } + close(fd1); + close(fd2); + } + } + if (dir) { + closedir(dir); + } + if (fd_hidraw < 0) { + if (linuxhid_os_init_status == 0) { + fatal(MYNAME ": no DeLorme PN found\n"); + } + return; + } + finfo.report_type = HID_REPORT_TYPE_INPUT; + finfo.report_id = 0; + finfo.field_index = 0; + if (ioctl(fd_hiddev, HIDIOCGFIELDINFO, &finfo) < 0) { + warning(MYNAME ": HIDIOCGFIELDINFO: %s\n", strerror(errno)); + if (linuxhid_os_init_status == 0) { + exit(1); + } + return; + } + delbin_os_packet_size = finfo.maxusage; + linuxhid_os_init_status = 0; } static void linuxhid_os_deinit(void) { - close(fd_hidraw); - close(fd_hiddev); + close(fd_hidraw); + close(fd_hiddev); } static unsigned linuxhid_os_packet_read(void* buf) { - int n = read(fd_hidraw, buf, delbin_os_packet_size); - if (n < 0) { - fatal(MYNAME ": %s\n", strerror(errno)); - } - return n; + int n = read(fd_hidraw, buf, delbin_os_packet_size); + if (n < 0) { + fatal(MYNAME ": %s\n", strerror(errno)); + } + return n; } static unsigned linuxhid_os_packet_write(const void* buf, unsigned size) { - struct hiddev_usage_ref_multi urefm; - struct hiddev_report_info rinfo; - const gbuint8* p = buf; - unsigned i; - - for (i = 0; i < size; i++) { - urefm.values[i] = p[i]; - } - urefm.num_values = size; - memset(&urefm.uref, 0, sizeof(urefm.uref)); - urefm.uref.report_type = HID_REPORT_TYPE_OUTPUT; - if (ioctl(fd_hiddev, HIDIOCSUSAGES, &urefm)) { - fatal(MYNAME ": HIDIOCSUSAGES: %s\n", strerror(errno)); - } - memset(&rinfo, 0, sizeof(rinfo)); - rinfo.report_type = HID_REPORT_TYPE_OUTPUT; - if (ioctl(fd_hiddev, HIDIOCSREPORT, &rinfo)) { - fatal(MYNAME ": HIDIOCSREPORT: %s\n", strerror(errno)); - } - return size; + struct hiddev_usage_ref_multi urefm; + struct hiddev_report_info rinfo; + const gbuint8* p = buf; + unsigned i; + + for (i = 0; i < size; i++) { + urefm.values[i] = p[i]; + } + urefm.num_values = size; + memset(&urefm.uref, 0, sizeof(urefm.uref)); + urefm.uref.report_type = HID_REPORT_TYPE_OUTPUT; + if (ioctl(fd_hiddev, HIDIOCSUSAGES, &urefm)) { + fatal(MYNAME ": HIDIOCSUSAGES: %s\n", strerror(errno)); + } + memset(&rinfo, 0, sizeof(rinfo)); + rinfo.report_type = HID_REPORT_TYPE_OUTPUT; + if (ioctl(fd_hiddev, HIDIOCSREPORT, &rinfo)) { + fatal(MYNAME ": HIDIOCSREPORT: %s\n", strerror(errno)); + } + return size; } static const delbin_os_ops_t linuxhid_os_ops = { - linuxhid_os_init, - linuxhid_os_deinit, - linuxhid_os_packet_read, - linuxhid_os_packet_write + linuxhid_os_init, + linuxhid_os_deinit, + linuxhid_os_packet_read, + linuxhid_os_packet_write }; static void linux_os_init(const char* fname) { - // tell linuxhid_os_init not to exit - linuxhid_os_init_status = 1; - linuxhid_os_init(fname); - if (linuxhid_os_init_status == 0) { - delbin_os_ops = linuxhid_os_ops; - } else { + // tell linuxhid_os_init not to exit + linuxhid_os_init_status = 1; + linuxhid_os_init(fname); + if (linuxhid_os_init_status == 0) { + delbin_os_ops = linuxhid_os_ops; + } else { #if HAVE_LIBUSB - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": HID init failed, falling back to libusb\n"); - delbin_os_ops = libusb_os_ops; - delbin_os_ops.init(fname); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": HID init failed, falling back to libusb\n"); + } + delbin_os_ops = libusb_os_ops; + delbin_os_ops.init(fname); #else - fatal(MYNAME ": no DeLorme PN found\n"); + fatal(MYNAME ": no DeLorme PN found\n"); #endif - } + } } delbin_os_ops_t delbin_os_ops = { - linux_os_init, - NULL, - NULL, - NULL + linux_os_init, + NULL, + NULL, + NULL }; #endif // HAVE_LINUX_HID //----------------------------------------------------------------------------- // stubs -#if !(_WIN32 || __APPLE__ || HAVE_LIBUSB || HAVE_LINUX_HID) +#if !(HAVE_WDK || __APPLE__ || HAVE_LIBUSB || HAVE_LINUX_HID) static void stub_os_init(const char* fname) { - fatal(MYNAME ": OS not supported\n"); + fatal(MYNAME ": OS not supported\n"); } static void stub_os_deinit(void) @@ -2868,333 +3019,333 @@ stub_os_deinit(void) static unsigned stub_os_packet_read(void* buf) { - return 0; + return 0; } static unsigned stub_os_packet_write(const void* buf, unsigned size) { - return 0; + return 0; } delbin_os_ops_t delbin_os_ops = { - stub_os_init, - stub_os_deinit, - stub_os_packet_read, - stub_os_packet_write + stub_os_init, + stub_os_deinit, + stub_os_packet_read, + stub_os_packet_write }; #endif // end OS device I/O implementations section //============================================================================= static const int track_color_bgr[] = { - 0x0000ff, // red - 0x00ffff, // yellow - 0x008000, // green - 0xff0000, // blue - 0x808080, // gray - 0xffffff, // white - 0, // black - 0xffff00, // cyan - 0xff00ff, // magenta - 0x00a5ff, // orange - 0x82004b, // indigo - 0xeea5ee // violet + 0x0000ff, // red + 0x00ffff, // yellow + 0x008000, // green + 0xff0000, // blue + 0x808080, // gray + 0xffffff, // white + 0, // black + 0xffff00, // cyan + 0xff00ff, // magenta + 0x00a5ff, // orange + 0x82004b, // indigo + 0xeea5ee // violet }; static int track_color(unsigned i) { - int bgr = -1; - if (i < sizeofarray(track_color_bgr)) { - bgr = track_color_bgr[i]; - } - return bgr; + int bgr = -1; + if (i < sizeofarray(track_color_bgr)) { + bgr = track_color_bgr[i]; + } + return bgr; } static unsigned track_color_index(int bgr) { - unsigned i = sizeofarray(track_color_bgr); - do { - i--; - } while (i != 0 && track_color_bgr[i] != bgr); - return i; + unsigned i = sizeofarray(track_color_bgr); + do { + i--; + } while (i != 0 && track_color_bgr[i] != bgr); + return i; } static const char* const waypoint_symbol_name[] = { - // 0 - "Red Map Pin", - "Dark Red Map Pin", - "Yellow Map Pin", - "Dark Yellow Map Pin", - "Green Map Pin", - "Dark Green Map Pin", - "Turquoise Map Pin", - "Dark Turquoise Map Pin", - "Blue Map Pin", - "Dark Blue Map Pin", - // 10 - "Gray Map Pin", - "Dark Gray Map Pin", - "Red Flag", - "Dark Red Flag", - "Yellow Flag", - "Dark Yellow Flag", - "Green Flag", - "Dark Green Flag", - "Turquoise Flag", - "Dark Turquoise Flag", - // 20 - "Blue Flag", - "Dark Blue Flag", - "Gray Flag", - "Dark Gray Flag", - "Red Dot", - "Dark Red Dot", - "Yellow Dot", - "Dark Yellow Dot", - "Green Dot", - "Dark Green Dot", - // 30 - "Turquoise Dot", - "Dark Turquoise Dot", - "Blue Dot", - "Dark Blue Dot", - "Gray Dot", - "Dark Gray Dot", - "Small Red Dot", - "Small Dark Red Dot", - "Small Yellow Dot", - "Small Dark Yellow Dot", - // 40 - "Small Green Dot", - "Small Dark Green Dot", - "Small Turquoise Dot", - "Small Dark Turquoise Dot", - "Small Blue Dot", - "Small Dark Blue Dot", - "Small Gray Dot", - "Small Dark Gray Dot", - "Arrow Up", - "Arrow Down", - // 50 - "Arrow Left", - "Arrow Right", - "Arrow Up Left", - "Arrow Up Right", - "Arrow Down Left", - "Arrow Down Right", - "Green Star", - "Yellow Square", - "Red X", - "Turquoise Circle", - // 60 - "Purple Triangle", - "American Flag", - "Stop", - "Parking", - "First Aid", - "Dining", - "Railroad Crossing", - "Heliport", - "Restroom", - "Information", - // 70 - "Diver Down", - "Exit", - "Health Facility", - "Police", - "Post Office", - "Mining", - "Danger", - "Money", - "Exclamation", - "Car", - // 80 - "Jeep", - "Truck", - "Tow Truck", - "Motor Home", - "School Bus", - "Four-wheeler", - "Snowmobile", - "Sailboat", - "Powerboat", - "Boat Launch", - // 90 - "Anchor", - "Buoy", - "Shipwreck", - "Glider Area", - "Private Airport", - "Public Airport", - "Military Airport", - "Military Base", - "House", - "Church", - // 100 - "Building", - "School", - "Lighthouse", - "Bridge", - "Radio Tower", - "Dam", - "Tunnel", - "Toll Booth", - "Gas Station", - "Lodging", - // 110 - "Telephone", - "Traffic Light", - "Fire Hydrant", - "Cemetery", - "Picnic Table", - "Tent", - "Shelter", - "Camper", - "Fire", - "Shower", - // 120 - "Drinking Water", - "Binoculars", - "Camera", - "Geocache", - "Geocache Found", - "Fishing Pole", - "Ice Fishing Trap Set", - "Ice Fishing Trap Up", - "Moose", - "Deer", - // 130 - "Bear", - "Bird", - "Duck", - "Fish", - "Deer Tracks", - "Animal Tracks", - "Bird Tracks", - "Birch Tree", - "Evergreen Tree", - "Deciduous Tree", - // 140 - "Flower Garden", - "Mountain", - "Cave", - "Beach", - "Hiking", - "Swimming", - "Bicycling", - "Kayaking", - "Canoeing", - "Water Skiing", - // 150 - "Cross-country Skiing", - "Downhill Skiing", - "Ice Skating", - "Dogsledding", - "Shooting", - "Golf Course", - "Ballpark", - // 157-182 added in PN-40 2.5 firmware - "Cache Found", - "Didn't Find It", - "My Cache", - // 160 - "Traditional Cache", - "Multi-Cache", - "Unknown Cache", - "Letterbox Hybrid", - "Whereigo Cache", - "Event Cache", - "Mega-Event Cache", - "Cache In Trash Out Event", - "EarthCache", - "Virtual Cache", - // 170 - "Webcam Cache", - "Waymark", - "NGS Benchmark", - "Write Note", - "Needs Maintenance", - "Final Location", - "Parking Area", - "Question to Answer", - "Reference Point", - "Stages of a Multicache", - // 180 - "Trailhead", - "Temporarily Disable Listing", - "Enable Listing", - // 183-222 added in PN-40 2.7 firmware - "Crane Truck", - "Forest Fire", - "Oil Derrick", - "Wind Turbine", - "Letter A", - "Letter B", - "Letter C", - // 190 - "Letter D", - "Letter E", - "Letter F", - "Letter G", - "Letter H", - "Letter I", - "Letter J", - "Letter K", - "Letter L", - "Letter M", - // 200 - "Letter N", - "Letter O", - "Letter P", - "Letter Q", - "Letter R", - "Letter S", - "Letter T", - "Letter U", - "Letter V", - "Letter W", - // 210 - "Letter X", - "Letter Y", - "Letter Z", - "Numeral 0", - "Numeral 1", - "Numeral 2", - "Numeral 3", - "Numeral 4", - "Numeral 5", - "Numeral 6", - // 220 - "Numeral 7", - "Numeral 8", - "Numeral 9" + // 0 + "Red Map Pin", + "Dark Red Map Pin", + "Yellow Map Pin", + "Dark Yellow Map Pin", + "Green Map Pin", + "Dark Green Map Pin", + "Turquoise Map Pin", + "Dark Turquoise Map Pin", + "Blue Map Pin", + "Dark Blue Map Pin", + // 10 + "Gray Map Pin", + "Dark Gray Map Pin", + "Red Flag", + "Dark Red Flag", + "Yellow Flag", + "Dark Yellow Flag", + "Green Flag", + "Dark Green Flag", + "Turquoise Flag", + "Dark Turquoise Flag", + // 20 + "Blue Flag", + "Dark Blue Flag", + "Gray Flag", + "Dark Gray Flag", + "Red Dot", + "Dark Red Dot", + "Yellow Dot", + "Dark Yellow Dot", + "Green Dot", + "Dark Green Dot", + // 30 + "Turquoise Dot", + "Dark Turquoise Dot", + "Blue Dot", + "Dark Blue Dot", + "Gray Dot", + "Dark Gray Dot", + "Small Red Dot", + "Small Dark Red Dot", + "Small Yellow Dot", + "Small Dark Yellow Dot", + // 40 + "Small Green Dot", + "Small Dark Green Dot", + "Small Turquoise Dot", + "Small Dark Turquoise Dot", + "Small Blue Dot", + "Small Dark Blue Dot", + "Small Gray Dot", + "Small Dark Gray Dot", + "Arrow Up", + "Arrow Down", + // 50 + "Arrow Left", + "Arrow Right", + "Arrow Up Left", + "Arrow Up Right", + "Arrow Down Left", + "Arrow Down Right", + "Green Star", + "Yellow Square", + "Red X", + "Turquoise Circle", + // 60 + "Purple Triangle", + "American Flag", + "Stop", + "Parking", + "First Aid", + "Dining", + "Railroad Crossing", + "Heliport", + "Restroom", + "Information", + // 70 + "Diver Down", + "Exit", + "Health Facility", + "Police", + "Post Office", + "Mining", + "Danger", + "Money", + "Exclamation", + "Car", + // 80 + "Jeep", + "Truck", + "Tow Truck", + "Motor Home", + "School Bus", + "Four-wheeler", + "Snowmobile", + "Sailboat", + "Powerboat", + "Boat Launch", + // 90 + "Anchor", + "Buoy", + "Shipwreck", + "Glider Area", + "Private Airport", + "Public Airport", + "Military Airport", + "Military Base", + "House", + "Church", + // 100 + "Building", + "School", + "Lighthouse", + "Bridge", + "Radio Tower", + "Dam", + "Tunnel", + "Toll Booth", + "Gas Station", + "Lodging", + // 110 + "Telephone", + "Traffic Light", + "Fire Hydrant", + "Cemetery", + "Picnic Table", + "Tent", + "Shelter", + "Camper", + "Fire", + "Shower", + // 120 + "Drinking Water", + "Binoculars", + "Camera", + "Geocache", + "Geocache Found", + "Fishing Pole", + "Ice Fishing Trap Set", + "Ice Fishing Trap Up", + "Moose", + "Deer", + // 130 + "Bear", + "Bird", + "Duck", + "Fish", + "Deer Tracks", + "Animal Tracks", + "Bird Tracks", + "Birch Tree", + "Evergreen Tree", + "Deciduous Tree", + // 140 + "Flower Garden", + "Mountain", + "Cave", + "Beach", + "Hiking", + "Swimming", + "Bicycling", + "Kayaking", + "Canoeing", + "Water Skiing", + // 150 + "Cross-country Skiing", + "Downhill Skiing", + "Ice Skating", + "Dogsledding", + "Shooting", + "Golf Course", + "Ballpark", + // 157-182 added in PN-40 2.5 firmware + "Cache Found", + "Didn't Find It", + "My Cache", + // 160 + "Traditional Cache", + "Multi-Cache", + "Unknown Cache", + "Letterbox Hybrid", + "Whereigo Cache", + "Event Cache", + "Mega-Event Cache", + "Cache In Trash Out Event", + "EarthCache", + "Virtual Cache", + // 170 + "Webcam Cache", + "Waymark", + "NGS Benchmark", + "Write Note", + "Needs Maintenance", + "Final Location", + "Parking Area", + "Question to Answer", + "Reference Point", + "Stages of a Multicache", + // 180 + "Trailhead", + "Temporarily Disable Listing", + "Enable Listing", + // 183-222 added in PN-40 2.7 firmware + "Crane Truck", + "Forest Fire", + "Oil Derrick", + "Wind Turbine", + "Letter A", + "Letter B", + "Letter C", + // 190 + "Letter D", + "Letter E", + "Letter F", + "Letter G", + "Letter H", + "Letter I", + "Letter J", + "Letter K", + "Letter L", + "Letter M", + // 200 + "Letter N", + "Letter O", + "Letter P", + "Letter Q", + "Letter R", + "Letter S", + "Letter T", + "Letter U", + "Letter V", + "Letter W", + // 210 + "Letter X", + "Letter Y", + "Letter Z", + "Numeral 0", + "Numeral 1", + "Numeral 2", + "Numeral 3", + "Numeral 4", + "Numeral 5", + "Numeral 6", + // 220 + "Numeral 7", + "Numeral 8", + "Numeral 9" }; static const char* waypoint_symbol(unsigned i) { - const char* p = NULL; - if (i < sizeofarray(waypoint_symbol_name)) { - p = waypoint_symbol_name[i]; - } - return p; + const char* p = NULL; + if (i < sizeofarray(waypoint_symbol_name)) { + p = waypoint_symbol_name[i]; + } + return p; } static unsigned waypoint_symbol_index(const char* name) { - static unsigned last_result; - static char last_name[32]; - unsigned i = last_result; - - if (strncmp(name, last_name, sizeof(last_name)) != 0) { - i = sizeofarray(waypoint_symbol_name); - do { - i--; - } while (i != 0 && case_ignore_strcmp(name, waypoint_symbol_name[i]) != 0); - strncpy(last_name, name, sizeof(last_name)); - last_result = i; - } - return i; + static unsigned last_result; + static char last_name[32]; + unsigned i = last_result; + + if (strncmp(name, last_name, sizeof(last_name)) != 0) { + i = sizeofarray(waypoint_symbol_name); + do { + i--; + } while (i != 0 && case_ignore_strcmp(name, waypoint_symbol_name[i]) != 0); + strncpy(last_name, name, sizeof(last_name)); + last_result = i; + } + return i; } // vi: ts=4 sw=4 noexpandtab diff --git a/gpsbabel/delgpl.c b/gpsbabel/delgpl.c index a30b7d5b6..29006c7ff 100644 --- a/gpsbabel/delgpl.c +++ b/gpsbabel/delgpl.c @@ -27,135 +27,154 @@ #define MYNAME "GPL" typedef struct gpl_point { - unsigned int status; - unsigned int dummy1; - double lat; - double lon; - double alt; /* in feet */ - double heading; - double speed; /* mph */ - unsigned int tm; - unsigned int dummy3; + unsigned int status; + unsigned int dummy1; + double lat; + double lon; + double alt; /* in feet */ + double heading; + double speed; /* mph */ + unsigned int tm; + unsigned int dummy3; } gpl_point_t; -static gbfile *gplfile_in; -static gbfile *gplfile_out; +static gbfile* gplfile_in; +static gbfile* gplfile_out; static void -gpl_rd_init(const char *fname) +gpl_rd_init(const char* fname) { - gplfile_in = gbfopen_le(fname, "rb", MYNAME); - if (sizeof(struct gpl_point) != 56) { - fatal(MYNAME ": gpl_point is %lu instead of 56.\n", - (unsigned long) sizeof(struct gpl_point)); - } + gplfile_in = gbfopen_le(fname, "rb", MYNAME); + if (sizeof(struct gpl_point) != 56) { + fatal(MYNAME ": gpl_point is %lu instead of 56.\n", + (unsigned long) sizeof(struct gpl_point)); + } } static void gpl_read(void) { - waypoint *wpt_tmp; - route_head *track_head; - gpl_point_t gp; - double alt_feet; - - track_head = route_head_alloc(); - track_add_head(track_head); - - while (gbfread(&gp, sizeof(gp), 1, gplfile_in) > 0) { - wpt_tmp = waypt_new(); - wpt_tmp->latitude = le_read_double(&gp.lat); - wpt_tmp->longitude = le_read_double(&gp.lon); - alt_feet = le_read_double(&gp.alt); - wpt_tmp->altitude = FEET_TO_METERS(alt_feet); - if (wpt_tmp->altitude <= unknown_alt + 1) - wpt_tmp->altitude = unknown_alt; - wpt_tmp->creation_time = le_read32(&gp.tm); - - switch (le_read32(&gp.status)) { - case 1: wpt_tmp->fix = fix_none; break; - case 2: wpt_tmp->fix = fix_2d; break; - case 3: wpt_tmp->fix = fix_3d; break; - case 5: wpt_tmp->fix = fix_dgps; break; - } - - WAYPT_SET(wpt_tmp, course, le_read_double(&gp.heading)); - WAYPT_SET(wpt_tmp, speed, le_read_double(&gp.speed)); - WAYPT_SET(wpt_tmp, speed, MILES_TO_METERS(wpt_tmp->speed)/3600); - // 2008 and 2009 seem to throw track points in that go back - // in time. The only thing I see "special" about those - // trackpoints is that these fields are zeroed. Toss them. - if ((wpt_tmp->speed == 0.0) && (wpt_tmp->course == 0.0)) { - continue; - } - track_add_wpt(track_head, wpt_tmp); - } + waypoint* wpt_tmp; + route_head* track_head; + gpl_point_t gp; + double alt_feet; + + track_head = route_head_alloc(); + track_add_head(track_head); + + while (gbfread(&gp, sizeof(gp), 1, gplfile_in) > 0) { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = le_read_double(&gp.lat); + wpt_tmp->longitude = le_read_double(&gp.lon); + alt_feet = le_read_double(&gp.alt); + wpt_tmp->altitude = FEET_TO_METERS(alt_feet); + if (wpt_tmp->altitude <= unknown_alt + 1) { + wpt_tmp->altitude = unknown_alt; + } + wpt_tmp->creation_time = le_read32(&gp.tm); + + switch (le_read32(&gp.status)) { + case 1: + wpt_tmp->fix = fix_none; + break; + case 2: + wpt_tmp->fix = fix_2d; + break; + case 3: + wpt_tmp->fix = fix_3d; + break; + case 5: + wpt_tmp->fix = fix_dgps; + break; + } + + WAYPT_SET(wpt_tmp, course, le_read_double(&gp.heading)); + WAYPT_SET(wpt_tmp, speed, le_read_double(&gp.speed)); + WAYPT_SET(wpt_tmp, speed, MILES_TO_METERS(wpt_tmp->speed)/3600); + // 2008 and 2009 seem to throw track points in that go back + // in time. The only thing I see "special" about those + // trackpoints is that these fields are zeroed. Toss them. + if ((wpt_tmp->speed == 0.0) && (wpt_tmp->course == 0.0)) { + waypt_free(wpt_tmp); + continue; + } + track_add_wpt(track_head, wpt_tmp); + } } static void gpl_rd_deinit(void) { - gbfclose(gplfile_in); + gbfclose(gplfile_in); } static void -gpl_wr_init(const char *fname) +gpl_wr_init(const char* fname) { - gplfile_out = gbfopen_le(fname, "wb", MYNAME); + gplfile_out = gbfopen_le(fname, "wb", MYNAME); } static void gpl_wr_deinit(void) { - gbfclose(gplfile_out); + gbfclose(gplfile_out); } static void -gpl_trackpt(const waypoint *wpt) +gpl_trackpt(const waypoint* wpt) { - double alt_feet = METERS_TO_FEET(wpt->altitude); - int status = 3; - gpl_point_t gp; - double speed = 3600*METERS_TO_MILES(wpt->speed); - double heading = wpt->course; - - switch(wpt->fix) { - case fix_none: status = 1; break; - case fix_2d: status = 2; break; - case fix_3d: status = 3; break; - case fix_dgps: status = 5; break; - default: status = 3; // a strategic lie for fix_unknown. - } - - memset(&gp, 0, sizeof(gp)); - le_write32(&gp.status, status); - le_write_double(&gp.lat, wpt->latitude); - le_write_double(&gp.lon, wpt->longitude); - le_write_double(&gp.alt, alt_feet ); - le_write_double(&gp.speed, speed ); - le_write_double(&gp.heading, heading ); - le_write32(&gp.tm, wpt->creation_time); - - gbfwrite(&gp, sizeof(gp), 1, gplfile_out); + double alt_feet = METERS_TO_FEET(wpt->altitude); + int status = 3; + gpl_point_t gp; + double speed = 3600*METERS_TO_MILES(wpt->speed); + double heading = wpt->course; + + switch (wpt->fix) { + case fix_none: + status = 1; + break; + case fix_2d: + status = 2; + break; + case fix_3d: + status = 3; + break; + case fix_dgps: + status = 5; + break; + default: + status = 3; // a strategic lie for fix_unknown. + } + + memset(&gp, 0, sizeof(gp)); + le_write32(&gp.status, status); + le_write_double(&gp.lat, wpt->latitude); + le_write_double(&gp.lon, wpt->longitude); + le_write_double(&gp.alt, alt_feet); + le_write_double(&gp.speed, speed); + le_write_double(&gp.heading, heading); + le_write32(&gp.tm, wpt->creation_time); + + gbfwrite(&gp, sizeof(gp), 1, gplfile_out); } static void gpl_write(void) { - track_disp_all(NULL, NULL, gpl_trackpt); + track_disp_all(NULL, NULL, gpl_trackpt); } ff_vecs_t gpl_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, - gpl_rd_init, - gpl_wr_init, - gpl_rd_deinit, - gpl_wr_deinit, - gpl_read, - gpl_write, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* there is no need to convert anything | CET-REVIEW */ + ff_type_file, + { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none }, + gpl_rd_init, + gpl_wr_init, + gpl_rd_deinit, + gpl_wr_deinit, + gpl_read, + gpl_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* there is no need to convert anything | CET-REVIEW */ }; diff --git a/gpsbabel/destinator.c b/gpsbabel/destinator.c index 108955001..116c0c44e 100644 --- a/gpsbabel/destinator.c +++ b/gpsbabel/destinator.c @@ -2,7 +2,7 @@ Support for Destinator POI's, Itineraries and Tracklogs. ( as described at "http://mozoft.com/d3log.html" ) - + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org @@ -36,10 +36,10 @@ static arglist_t destinator_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; -static gbfile *fin, *fout; +static gbfile* fin, *fout; static gpsdata_type data_type; @@ -47,319 +47,340 @@ static gpsdata_type data_type; /* READER */ /*-----------------------------------------------------------------------------*/ -static garmin_fs_t * -gmsd_init(waypoint *wpt) +static garmin_fs_t* +gmsd_init(waypoint* wpt) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - return gmsd; + garmin_fs_t* gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data*) gmsd); + } + return gmsd; } -static char * +static char* read_wcstr(const int discard) { - gbint16 *buff = NULL, c; - int size = 0, pos = 0; - - while (gbfread(&c, sizeof(c), 1, fin) && (c != 0)) { - if (size == 0) { - size = 16; - buff = xmalloc(size * sizeof(*buff)); - } - else if (pos == size) { - size += 16; - buff = xrealloc(buff, size * sizeof(*buff)); - } - buff[pos] = c; - pos += 1; - } - - if (pos != 0) { - char *res; - if (discard) res = NULL; - else { - res = cet_str_uni_to_utf8(buff, pos); - res = lrtrim(res); - if (*res == '\0') { - xfree(res); - res = NULL; - } - } - xfree(buff); - return res; - } - else - return NULL; + gbint16* buff = NULL, c; + int size = 0, pos = 0; + + while (gbfread(&c, sizeof(c), 1, fin) && (c != 0)) { + if (size == 0) { + size = 16; + buff = (gbint16*) xmalloc(size * sizeof(*buff)); + } else if (pos == size) { + size += 16; + buff = (gbint16*) xrealloc(buff, size * sizeof(*buff)); + } + buff[pos] = c; + pos += 1; + } + + if (pos != 0) { + char* res; + if (discard) { + res = NULL; + } else { + res = cet_str_uni_to_utf8(buff, pos); + res = lrtrim(res); + if (*res == '\0') { + xfree(res); + res = NULL; + } + } + xfree(buff); + return res; + } else { + return NULL; + } } static void -write_wcstr(const char *str) +write_wcstr(const char* str) { - int len; - short *unicode; - - unicode = cet_str_utf8_to_uni(str, &len); - gbfwrite((void *)unicode, 2, len + 1, fout); - xfree(unicode); + int len; + short* unicode; + + unicode = cet_str_utf8_to_uni(str, &len); + gbfwrite((void*)unicode, 2, len + 1, fout); + xfree(unicode); } static int -read_until_wcstr(const char *str) +read_until_wcstr(const char* str) { - char *buff; - int len, sz; - int eos = 0, res = 0; - - len = strlen(str); - sz = (len + 1) * 2; - buff = xcalloc(sz, 1); - - while (! gbfeof(fin)) { - - char c = gbfgetc(fin); - memmove(buff, buff + 1, sz - 1); - buff[sz - 1] = c; - - if (c == 0) { - eos++; - if (eos >= 2) { /* two or more zero bytes => end of string */ - char *test = cet_str_uni_to_utf8((short *)buff, len); - if (test) { - res = (strcmp(str, test) == 0); - xfree(test); - if (res) break; - } - } - } - else eos = 0; - } - xfree(buff); - return res; + char* buff; + int len, sz; + int eos = 0, res = 0; + + len = strlen(str); + sz = (len + 1) * 2; + buff = (char*) xcalloc(sz, 1); + + while (! gbfeof(fin)) { + + char c = gbfgetc(fin); + memmove(buff, buff + 1, sz - 1); + buff[sz - 1] = c; + + if (c == 0) { + eos++; + if (eos >= 2) { /* two or more zero bytes => end of string */ + char* test = cet_str_uni_to_utf8((short*)buff, len); + if (test) { + res = (strcmp(str, test) == 0); + xfree(test); + if (res) { + break; + } + } + } + } else { + eos = 0; + } + } + xfree(buff); + return res; } static void destinator_read_poi(void) { - waypoint *wpt; - int count = 0; - - gbfrewind(fin); - - while (! (gbfeof(fin))) { - char *str, *hnum; - double ll; - garmin_fs_t *gmsd; - - if (count == 0) { - str = read_wcstr(0); - if ((str == NULL) || (strcmp(str, DST_DYN_POI) != 0)) - fatal(MYNAME "_poi: Invalid record header!\n"); - xfree(str); - } - else if (! read_until_wcstr(DST_DYN_POI)) break; - - count++; - - wpt = waypt_new(); - - wpt->shortname = read_wcstr(0); - wpt->notes = read_wcstr(0); /* comment */ - - hnum = read_wcstr(0); /* house number */ - - str = read_wcstr(0); /* street */ - if (!str) { - str = hnum; - hnum = NULL; - } - if (str) { - gmsd = gmsd_init(wpt); - if (hnum) { - str = xstrappend(str, " "); - str = xstrappend(str, hnum); - } - GMSD_SET(addr, str); - } - - if ((str = read_wcstr(0))) { /* city */ - gmsd = gmsd_init(wpt); - GMSD_SET(city, str); - } - - if (hnum) xfree(hnum); - - (void) read_wcstr(1); /* unknown */ - - if ((str = read_wcstr(0))) { /* postcode */ - gmsd = gmsd_init(wpt); - GMSD_SET(postal_code, str); - } - - (void) read_wcstr(1); /* unknown */ - - (void) gbfgetdbl(fin); - - wpt->longitude = gbfgetdbl(fin); - wpt->latitude = gbfgetdbl(fin); - ll = gbfgetdbl(fin); - if (ll != wpt->longitude) - fatal(MYNAME "_poi: Invalid file!\n"); - ll = gbfgetdbl(fin); - if (ll != wpt->latitude) - fatal(MYNAME "_poi: Invalid file!\n"); - - waypt_add(wpt); - } + waypoint* wpt; + int count = 0; + + gbfrewind(fin); + + while (!(gbfeof(fin))) { + char* str, *hnum; + double ll; + garmin_fs_t* gmsd; + + if (count == 0) { + str = read_wcstr(0); + if ((str == NULL) || (strcmp(str, DST_DYN_POI) != 0)) { + fatal(MYNAME "_poi: Invalid record header!\n"); + } + xfree(str); + } else if (! read_until_wcstr(DST_DYN_POI)) { + break; + } + + count++; + + wpt = waypt_new(); + + wpt->shortname = read_wcstr(0); + wpt->notes = read_wcstr(0); /* comment */ + + hnum = read_wcstr(0); /* house number */ + + str = read_wcstr(0); /* street */ + if (!str) { + str = hnum; + hnum = NULL; + } + if (str) { + gmsd = gmsd_init(wpt); + if (hnum) { + str = xstrappend(str, " "); + str = xstrappend(str, hnum); + } + GMSD_SET(addr, str); + } + + if ((str = read_wcstr(0))) { /* city */ + gmsd = gmsd_init(wpt); + GMSD_SET(city, str); + } + + if (hnum) { + xfree(hnum); + } + + (void) read_wcstr(1); /* unknown */ + + if ((str = read_wcstr(0))) { /* postcode */ + gmsd = gmsd_init(wpt); + GMSD_SET(postal_code, str); + } + + (void) read_wcstr(1); /* unknown */ + + (void) gbfgetdbl(fin); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + ll = gbfgetdbl(fin); + if (ll != wpt->longitude) { + fatal(MYNAME "_poi: Invalid file!\n"); + } + ll = gbfgetdbl(fin); + if (ll != wpt->latitude) { + fatal(MYNAME "_poi: Invalid file!\n"); + } + + waypt_add(wpt); + } } static void destinator_read_rte(void) { - int count = 0; - route_head *rte = NULL; - - gbfrewind(fin); - - while (! (gbfeof(fin))) { - char *str; - waypoint *wpt; - - if (count == 0) { - str = read_wcstr(0); - if ((str == NULL) || (strcmp(str, DST_ITINERARY) != 0)) - fatal(MYNAME "_itn: Invalid record header!\n"); - xfree(str); - } - else if (! read_until_wcstr(DST_ITINERARY)) break; - - count++; - - wpt = waypt_new(); - - wpt->shortname = read_wcstr(0); - wpt->notes = read_wcstr(0); - - (void) gbfgetint32(fin); - (void) gbfgetdbl(fin); - (void) gbfgetdbl(fin); - - wpt->longitude = gbfgetdbl(fin); - wpt->latitude = gbfgetdbl(fin); - if (gbfgetdbl(fin) != wpt->longitude) - fatal(MYNAME "_itn: Invalid file!\n"); - if (gbfgetdbl(fin) != wpt->latitude) - fatal(MYNAME "_itn: Invalid file!\n"); - - if (! rte) { - rte = route_head_alloc(); - route_add_head(rte); - } - route_add_wpt(rte, wpt); - - (void) gbfgetdbl(fin); - (void) gbfgetdbl(fin); - } + int count = 0; + route_head* rte = NULL; + + gbfrewind(fin); + + while (!(gbfeof(fin))) { + char* str; + waypoint* wpt; + + if (count == 0) { + str = read_wcstr(0); + if ((str == NULL) || (strcmp(str, DST_ITINERARY) != 0)) { + fatal(MYNAME "_itn: Invalid record header!\n"); + } + xfree(str); + } else if (! read_until_wcstr(DST_ITINERARY)) { + break; + } + + count++; + + wpt = waypt_new(); + + wpt->shortname = read_wcstr(0); + wpt->notes = read_wcstr(0); + + (void) gbfgetint32(fin); + (void) gbfgetdbl(fin); + (void) gbfgetdbl(fin); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + if (gbfgetdbl(fin) != wpt->longitude) { + fatal(MYNAME "_itn: Invalid file!\n"); + } + if (gbfgetdbl(fin) != wpt->latitude) { + fatal(MYNAME "_itn: Invalid file!\n"); + } + + if (! rte) { + rte = route_head_alloc(); + route_add_head(rte); + } + route_add_wpt(rte, wpt); + + (void) gbfgetdbl(fin); + (void) gbfgetdbl(fin); + } } static void destinator_read_trk(void) { - char TXT[4] = "TXT"; - int recno = -1; - route_head *trk = NULL; - - gbfrewind(fin); - - while (! (gbfeof(fin))) { - waypoint *wpt; - struct tm tm; - char buff[20]; - int date; - double time; - - recno++; - - if (gbfeof(fin)) break; - - wpt = waypt_new(); - - wpt->longitude = gbfgetdbl(fin); - wpt->latitude = gbfgetdbl(fin); - wpt->altitude = gbfgetdbl(fin); - - (void) gbfgetdbl(fin); /* unknown */ - (void) gbfgetdbl(fin); /* unknown */ - (void) gbfgetdbl(fin); /* unknown */ - - wpt->fix = gbfgetint32(fin); - wpt->sat = gbfgetint32(fin); - - gbfseek(fin, 12 * sizeof(gbint32), SEEK_CUR); /* SAT info */ - - date = gbfgetint32(fin); - time = gbfgetflt(fin); - - gbfseek(fin, 2 * 12, SEEK_CUR); /* SAT info */ - - gbfread(TXT, 1, 3, fin); - if (strcmp(TXT, "TXT") != 0) - fatal(MYNAME "_trk: No (or unknown) file!\n"); - - gbfseek(fin, 13, SEEK_CUR); /* unknown */ - - memset(&tm, 0, sizeof(tm)); - - snprintf(buff, sizeof(buff), "%06d%.f", date, time); - strptime(buff, "%d%m%y%H%M%S", &tm); - wpt->creation_time = mkgmtime(&tm); - wpt->microseconds = ((int)time % 1000) * 1000; - - if (wpt->fix > 0) wpt->fix++; - - if (! trk) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - } + char TXT[4] = "TXT"; + int recno = -1; + route_head* trk = NULL; + + gbfrewind(fin); + + while (!(gbfeof(fin))) { + waypoint* wpt; + struct tm tm; + char buff[20]; + int date; + double time; + + recno++; + + if (gbfeof(fin)) { + break; + } + + wpt = waypt_new(); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + (void) gbfgetdbl(fin); /* unknown */ + (void) gbfgetdbl(fin); /* unknown */ + (void) gbfgetdbl(fin); /* unknown */ + + wpt->fix = (fix_type) gbfgetint32(fin); + wpt->sat = gbfgetint32(fin); + + gbfseek(fin, 12 * sizeof(gbint32), SEEK_CUR); /* SAT info */ + + date = gbfgetint32(fin); + time = gbfgetflt(fin); + + gbfseek(fin, 2 * 12, SEEK_CUR); /* SAT info */ + + gbfread(TXT, 1, 3, fin); + if (strcmp(TXT, "TXT") != 0) { + fatal(MYNAME "_trk: No (or unknown) file!\n"); + } + + gbfseek(fin, 13, SEEK_CUR); /* unknown */ + + memset(&tm, 0, sizeof(tm)); + + snprintf(buff, sizeof(buff), "%06d%.f", date, time); + strptime(buff, "%d%m%y%H%M%S", &tm); + wpt->creation_time = mkgmtime(&tm); + wpt->microseconds = ((int)time % 1000) * 1000; + + if (wpt->fix > 0) { + wpt->fix = (fix_type)(wpt->fix + 1); + } + + if (! trk) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + } } static void destinator_read(void) { - int i0, i1; - double d0, d1; - char buff[16]; - - if (! gbfread(buff, 1, sizeof(buff), fin)) - fatal(MYNAME ": Unexpected EOF (end of file)!\n"); - - i0 = le_read32(&buff[0]); - i1 = le_read32(&buff[4]); - - if ((i0 == 0x690043) && (i1 == 0x790074)) { - if (data_type != rtedata) - warning(MYNAME ": Using Destinator Itinerary Format!\n"); - destinator_read_rte(); - } - else if ((i0 == 0x790044) && (i1 == 0x61006e)) { - if (data_type != wptdata) - warning(MYNAME ": Using Destinator POI Format!\n"); - destinator_read_poi(); - } - else { - if (data_type != trkdata) - warning(MYNAME ": Using Destinator Tracklog Format!\n"); - - le_read64(&d0, &buff[0]); - le_read64(&d1, &buff[8]); - if ((fabs(d0) > 180) || (fabs(d1) > 90)) - fatal(MYNAME ": No Destinator (.dat) file!\n"); - destinator_read_trk(); - } + int i0, i1; + double d0, d1; + char buff[16]; + + if (! gbfread(buff, 1, sizeof(buff), fin)) { + fatal(MYNAME ": Unexpected EOF (end of file)!\n"); + } + + i0 = le_read32(&buff[0]); + i1 = le_read32(&buff[4]); + + if ((i0 == 0x690043) && (i1 == 0x790074)) { + if (data_type != rtedata) { + warning(MYNAME ": Using Destinator Itinerary Format!\n"); + } + destinator_read_rte(); + } else if ((i0 == 0x790044) && (i1 == 0x61006e)) { + if (data_type != wptdata) { + warning(MYNAME ": Using Destinator POI Format!\n"); + } + destinator_read_poi(); + } else { + if (data_type != trkdata) { + warning(MYNAME ": Using Destinator Tracklog Format!\n"); + } + + le_read64(&d0, &buff[0]); + le_read64(&d1, &buff[8]); + if ((fabs(d0) > 180) || (fabs(d1) > 90)) { + fatal(MYNAME ": No Destinator (.dat) file!\n"); + } + destinator_read_trk(); + } } /*******************************************************************************/ @@ -367,91 +388,96 @@ destinator_read(void) /*-----------------------------------------------------------------------------*/ static void -destinator_wpt_disp(const waypoint *wpt) +destinator_wpt_disp(const waypoint* wpt) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); + garmin_fs_t* gmsd = GMSD_FIND(wpt); - write_wcstr(DST_DYN_POI); - write_wcstr((wpt->shortname) ? wpt->shortname : "WPT"); - write_wcstr((wpt->notes) ? wpt->notes : wpt->description); + write_wcstr(DST_DYN_POI); + write_wcstr((wpt->shortname) ? wpt->shortname : "WPT"); + write_wcstr((wpt->notes) ? wpt->notes : wpt->description); - write_wcstr(NULL); /* house number */ - write_wcstr(GMSD_GET(addr, NULL)); /* street */ - write_wcstr(GMSD_GET(city, NULL)); /* city */ - write_wcstr(NULL); /* unknown */ - write_wcstr(GMSD_GET(postal_code, NULL)); /* postcode */ - write_wcstr(NULL); /* unknown */ + write_wcstr(NULL); /* house number */ + write_wcstr(GMSD_GET(addr, NULL)); /* street */ + write_wcstr(GMSD_GET(city, NULL)); /* city */ + write_wcstr(NULL); /* unknown */ + write_wcstr(GMSD_GET(postal_code, NULL)); /* postcode */ + write_wcstr(NULL); /* unknown */ - gbfputint32(0, fout); - gbfputint32(0, fout); + gbfputint32(0, fout); + gbfputint32(0, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); } static void -destinator_trkpt_disp(const waypoint *wpt) +destinator_trkpt_disp(const waypoint* wpt) { - int i; - - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->altitude, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); - gbfputint32(wpt->fix > fix_unknown ? wpt->fix - 1 : 0, fout); - gbfputint32(wpt->sat, fout); - for (i = 0; i < 12; i++) gbfputint32(0, fout); - - if (wpt->creation_time) { - struct tm tm; - double time; - int date; - - tm = *gmtime(&wpt->creation_time); - tm.tm_mon += 1; - tm.tm_year -= 100; - date = ((int)tm.tm_mday * 10000) + ((int)tm.tm_mon * 100) + tm.tm_year; - gbfputint32(date, fout); - - time = ((int)tm.tm_hour * 10000) + ((int)tm.tm_min * 100) + tm.tm_sec; - time = (time * 1000) + (wpt->microseconds / 1000); - gbfputflt(time, fout); - } - else { - gbfputint32(0, fout); /* Is this invalid ? */ - gbfputflt(0, fout); - } - - for (i = 0; i < 12; i++) gbfputint16(0, fout); - gbfputcstr("TXT", fout); - for (i = 0; i < 12; i++) gbfputc(0, fout); + int i; + + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->altitude, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputint32(wpt->fix > fix_unknown ? wpt->fix - 1 : 0, fout); + gbfputint32(wpt->sat, fout); + for (i = 0; i < 12; i++) { + gbfputint32(0, fout); + } + + if (wpt->creation_time) { + struct tm tm; + double time; + int date; + + tm = *gmtime(&wpt->creation_time); + tm.tm_mon += 1; + tm.tm_year -= 100; + date = ((int)tm.tm_mday * 10000) + ((int)tm.tm_mon * 100) + tm.tm_year; + gbfputint32(date, fout); + + time = ((int)tm.tm_hour * 10000) + ((int)tm.tm_min * 100) + tm.tm_sec; + time = (time * 1000) + (wpt->microseconds / 1000); + gbfputflt(time, fout); + } else { + gbfputint32(0, fout); /* Is this invalid ? */ + gbfputflt(0, fout); + } + + for (i = 0; i < 12; i++) { + gbfputint16(0, fout); + } + gbfputcstr("TXT", fout); + for (i = 0; i < 12; i++) { + gbfputc(0, fout); + } } static void -destinator_rtept_disp(const waypoint *wpt) +destinator_rtept_disp(const waypoint* wpt) { - write_wcstr(DST_ITINERARY); - write_wcstr((wpt->shortname) ? wpt->shortname : "RTEPT"); - write_wcstr((wpt->notes) ? wpt->notes : wpt->description); + write_wcstr(DST_ITINERARY); + write_wcstr((wpt->shortname) ? wpt->shortname : "RTEPT"); + write_wcstr((wpt->notes) ? wpt->notes : wpt->description); - gbfputint32(0, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); + gbfputint32(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); } /******************************************************************************* @@ -459,122 +485,122 @@ destinator_rtept_disp(const waypoint *wpt) *******************************************************************************/ static void -destinator_rd_init(const char *fname) +destinator_rd_init(const char* fname) { - fin = gbfopen_le(fname, "rb", MYNAME); + fin = gbfopen_le(fname, "rb", MYNAME); } -static void +static void destinator_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void destinator_read_poi_wrapper(void) { - data_type = wptdata; - destinator_read(); + data_type = wptdata; + destinator_read(); } static void destinator_read_rte_wrapper(void) { - data_type = rtedata; - destinator_read(); + data_type = rtedata; + destinator_read(); } static void destinator_read_trk_wrapper(void) { - data_type = trkdata; - destinator_read(); + data_type = trkdata; + destinator_read(); } static void -destinator_wr_init(const char *fname) +destinator_wr_init(const char* fname) { - fout = gbfopen_le(fname, "wb", MYNAME); + fout = gbfopen_le(fname, "wb", MYNAME); } static void destinator_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void destinator_write_poi(void) { - waypt_disp_all(destinator_wpt_disp); + waypt_disp_all(destinator_wpt_disp); } static void destinator_write_rte(void) { - route_disp_all(NULL, NULL, destinator_rtept_disp); + route_disp_all(NULL, NULL, destinator_rtept_disp); } static void destinator_write_trk(void) { - track_disp_all(NULL, NULL, destinator_trkpt_disp); + track_disp_all(NULL, NULL, destinator_trkpt_disp); } /**************************************************************************/ ff_vecs_t destinator_poi_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - destinator_rd_init, - destinator_wr_init, - destinator_rd_deinit, - destinator_wr_deinit, - destinator_read_poi_wrapper, - destinator_write_poi, - NULL, - destinator_args, - CET_CHARSET_UTF8, 1 /* fixed */ + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_poi_wrapper, + destinator_write_poi, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ }; ff_vecs_t destinator_itn_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_read | ff_cap_write /* routes */ - }, - destinator_rd_init, - destinator_wr_init, - destinator_rd_deinit, - destinator_wr_deinit, - destinator_read_rte_wrapper, - destinator_write_rte, - NULL, - destinator_args, - CET_CHARSET_UTF8, 1 /* fixed */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_none /* tracks */, + (ff_cap)(ff_cap_read | ff_cap_write) /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_rte_wrapper, + destinator_write_rte, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ }; ff_vecs_t destinator_trl_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - destinator_rd_init, - destinator_wr_init, - destinator_rd_deinit, - destinator_wr_deinit, - destinator_read_trk_wrapper, - destinator_write_trk, - NULL, - destinator_args, - CET_CHARSET_UTF8, 1 /* fixed */ + ff_type_file, + { + ff_cap_none /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_trk_wrapper, + destinator_write_trk, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ }; /**************************************************************************/ diff --git a/gpsbabel/dg-100.c b/gpsbabel/dg-100.c index 5cc616ce1..b64d43868 100644 --- a/gpsbabel/dg-100.c +++ b/gpsbabel/dg-100.c @@ -4,6 +4,7 @@ Copyright (C) 2007 Mirko Parthey, mirko.parthey@informatik.tu-chemnitz.de Copyright (C) 2005-2008 Robert Lipe, robertlipe@gpsbabel.org + Copyright (C) 2012 Nicolas Boullis, nboullis@debian.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,7 +36,15 @@ #define MYNAME "DG-100" -static void *serial_handle; +typedef struct { + unsigned speed; + int has_trailing_bytes; + int has_payload_end_seq; +} model_t; + +static const model_t* model; + +static void* serial_handle; /* maximum frame size observed so far: 1817 bytes * (dg100cmd_getfileheader returning 150 entries) @@ -44,140 +53,140 @@ static void *serial_handle; #define FRAME_MAXLEN 4096 enum dg100_command_id { - dg100cmd_getconfig = 0xB7, - dg100cmd_setconfig = 0xB8, - dg100cmd_getfileheader = 0xBB, - dg100cmd_getfile = 0xB5, - dg100cmd_erase = 0xBA, - dg100cmd_getid = 0xBF, - dg100cmd_setid = 0xC0, - dg100cmd_gpsmouse = 0xBC + dg100cmd_getconfig = 0xB7, + dg100cmd_setconfig = 0xB8, + dg100cmd_getfileheader = 0xBB, + dg100cmd_getfile = 0xB5, + dg100cmd_erase = 0xBA, + dg100cmd_getid = 0xBF, + dg100cmd_setid = 0xC0, + dg100cmd_gpsmouse = 0xBC }; struct dg100_command { - int id; - int sendsize; - int recvsize; - int trailing_bytes; - const char *text; /* Textual description for debugging */ + int id; + int sendsize; + int recvsize; + int trailing_bytes; + const char* text; /* Textual description for debugging */ }; struct dg100_command dg100_commands[] = { - { dg100cmd_getconfig, 0, 44+2, 2, "getconfig" }, - { dg100cmd_setconfig, 41, 4+2, 2, "setconfig" }, - /* the getfileheader answer has variable length, -1 is a dummy value */ - { dg100cmd_getfileheader, 2, -1 , 2, "getfileheader" }, - { dg100cmd_getfile, 2, 1024+2, 2, "getfile" }, - { dg100cmd_erase, 2, 4+2, 2, "erase" }, - { dg100cmd_getid, 0, 8+2, 2, "getid" }, - { dg100cmd_setid, 8, 4+2, 2, "setid" }, - { dg100cmd_gpsmouse, 1, 0 , 0, "gpsmouse" } + { dg100cmd_getconfig, 0, 44, 2, "getconfig" }, + { dg100cmd_setconfig, 41, 4, 2, "setconfig" }, + /* the getfileheader answer has variable length, -1 is a dummy value */ + { dg100cmd_getfileheader, 2, -1, 2, "getfileheader" }, + { dg100cmd_getfile, 2, 1024, 2, "getfile" }, + { dg100cmd_erase, 2, 4, 2, "erase" }, + { dg100cmd_getid, 0, 8, 2, "getid" }, + { dg100cmd_setid, 8, 4, 2, "setid" }, + { dg100cmd_gpsmouse, 1, 0, 0, "gpsmouse" } }; const unsigned dg100_numcommands = sizeof(dg100_commands) / sizeof(dg100_commands[0]); struct dynarray16 { - unsigned count; /* number of elements used */ - unsigned limit; /* number of elements allocated */ - gbint16 *data; + unsigned count; /* number of elements used */ + unsigned limit; /* number of elements allocated */ + gbint16* data; }; /* helper functions */ -static struct dg100_command * -dg100_findcmd(int id) -{ - unsigned int i; - - /* linear search should be OK as long as dg100_numcommands is small */ - for (i = 0; i < dg100_numcommands; i++) { - if (dg100_commands[i].id == id) - return(&dg100_commands[i]); - } - - return NULL; +static struct dg100_command* +dg100_findcmd(int id) { + unsigned int i; + + /* linear search should be OK as long as dg100_numcommands is small */ + for (i = 0; i < dg100_numcommands; i++) { + if (dg100_commands[i].id == id) { + return(&dg100_commands[i]); + } + } + + return NULL; } static void -dynarray16_init(struct dynarray16 *a, unsigned limit) +dynarray16_init(struct dynarray16* a, unsigned limit) { - a->count = 0; - a->limit = limit; - a->data = xmalloc(sizeof(a->data[0]) * a->limit); + a->count = 0; + a->limit = limit; + a->data = (gbint16*) xmalloc(sizeof(a->data[0]) * a->limit); } -static gbint16 * -dynarray16_alloc(struct dynarray16 *a, unsigned n) +static gbint16* +dynarray16_alloc(struct dynarray16* a, unsigned n) { - unsigned oldcount, need; - const unsigned elements_per_chunk = 4096 / sizeof(a->data[0]); - - oldcount = a->count; - a->count += n; - - if (a->count > a->limit) { - need = a->count - a->limit; - need = (need > elements_per_chunk) ? need : elements_per_chunk; - a->limit += need; - a->data = xrealloc(a->data, sizeof(a->data[0]) * a->limit); - } - return(a->data + oldcount); + unsigned oldcount, need; + const unsigned elements_per_chunk = 4096 / sizeof(a->data[0]); + + oldcount = a->count; + a->count += n; + + if (a->count > a->limit) { + need = a->count - a->limit; + need = (need > elements_per_chunk) ? need : elements_per_chunk; + a->limit += need; + a->data = (gbint16*) xrealloc(a->data, sizeof(a->data[0]) * a->limit); + } + return(a->data + oldcount); } static time_t bintime2utc(int date, int time) { - struct tm gpstime; - - gpstime.tm_sec = time % 100; - time /= 100; - gpstime.tm_min = time % 100; - time /= 100; - gpstime.tm_hour = time; - - /* - * GPS year: 2000+; struct tm year: 1900+ - * GPS month: 1-12, struct tm month: 0-11 - */ - gpstime.tm_year = date % 100 + 100; - date /= 100; - gpstime.tm_mon = date % 100 - 1; - date /= 100; - gpstime.tm_mday = date; - - return(mkgmtime(&gpstime)); + struct tm gpstime; + + gpstime.tm_sec = time % 100; + time /= 100; + gpstime.tm_min = time % 100; + time /= 100; + gpstime.tm_hour = time; + + /* + * GPS year: 2000+; struct tm year: 1900+ + * GPS month: 1-12, struct tm month: 0-11 + */ + gpstime.tm_year = date % 100 + 100; + date /= 100; + gpstime.tm_mon = date % 100 - 1; + date /= 100; + gpstime.tm_mday = date; + + return(mkgmtime(&gpstime)); } -static void -dg100_debug(const char *hdr, int include_nl, size_t sz, unsigned char *buf) +static void +dg100_debug(const char* hdr, int include_nl, size_t sz, unsigned char* buf) { - unsigned int i; + unsigned int i; - /* Only give byte dumps for higher debug levels */ - if (global_opts.debug_level < 5) { - return; - } + /* Only give byte dumps for higher debug levels */ + if (global_opts.debug_level < 5) { + return; + } - fprintf(stderr, "%s", hdr); + fprintf(stderr, "%s", hdr); - for (i = 0; i < sz; i++) { - fprintf(stderr, "%02x ", buf[i]); - } + for (i = 0; i < sz; i++) { + fprintf(stderr, "%02x ", buf[i]); + } - if (include_nl) { - fprintf(stderr, "\n"); - } + if (include_nl) { + fprintf(stderr, "\n"); + } } static void -dg100_log(const char *fmt, ...) +dg100_log(const char* fmt, ...) { - va_list ap; - va_start (ap, fmt); - if (global_opts.debug_level < 1) { - return; - } - - vfprintf(stderr, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + if (global_opts.debug_level < 1) { + return; + } + + vfprintf(stderr, fmt, ap); + va_end(ap); } @@ -185,449 +194,490 @@ dg100_log(const char *fmt, ...) static float bin2deg(int val) { - /* Assume that val prints in decimal digits as [-]dddmmffff - * ddd: degrees - * mm: the integer part of minutes - * ffff: the fractional part of minutes (decimal fraction 0.ffff) - */ - - float deg; - int deg_int, min_scaled, isneg; - unsigned absval; - - /* avoid division of negative integers, - * which has platform-dependent results */ - absval = abs(val); - isneg = (val < 0); - - deg_int = absval / 1000000; /* extract ddd */ - min_scaled = absval % 1000000; /* extract mmffff (minutes * 10^4) */ - deg = deg_int + (double) min_scaled / (10000 * 60); - - /* restore the sign */ - deg = isneg ? -deg : deg; - return(deg); + /* Assume that val prints in decimal digits as [-]dddmmffff + * ddd: degrees + * mm: the integer part of minutes + * ffff: the fractional part of minutes (decimal fraction 0.ffff) + */ + + float deg; + int deg_int, min_scaled, isneg; + unsigned absval; + + /* avoid division of negative integers, + * which has platform-dependent results */ + absval = abs(val); + isneg = (val < 0); + + deg_int = absval / 1000000; /* extract ddd */ + min_scaled = absval % 1000000; /* extract mmffff (minutes * 10^4) */ + deg = deg_int + (double) min_scaled / (10000 * 60); + + /* restore the sign */ + deg = isneg ? -deg : deg; + return(deg); } static void -process_gpsfile(gbuint8 data[], route_head *track) +process_gpsfile(gbuint8 data[], route_head** track) { - const int recordsizes[3] = {8, 20, 32}; - int i, style, recsize; - int lat, lon, bintime, bindate; - waypoint *wpt; - - /* the first record of each file is always full-sized; its style field - * determines the format of all subsequent records in the file */ - style = be_read32(data + 28); - if (style > 2) { - fprintf(stderr, "unknown GPS record style %d", style); - return; - } - recsize = recordsizes[style]; - - for (i = 0; i <= 2048 - recsize; i += (i == 0) ? 32 : recsize) { - - lat = be_read32(data + i + 0); - lon = be_read32(data + i + 4); - - /* skip invalid trackpoints (blank records) */ - if (lat == -1 && lon == -1) { - continue; - } - - wpt = waypt_new(); - wpt->latitude = bin2deg(lat); - wpt->longitude = bin2deg(lon); - - if (style >= 1) { - bintime = be_read32(data + i + 8); - bindate = be_read32(data + i + 12); - wpt->creation_time = bintime2utc(bindate, bintime); - /* The device presents the speed as a fixed-point number - * with a scaling factor of 100, in km/h. - * The waypoint struct wants the speed as a - * floating-point number, in m/s. */ - wpt->speed = KPH_TO_MPS(be_read32(data + i + 16) / 100.0); - wpt->wpt_flags.speed = 1; - } - - if (style >= 2) { - wpt->altitude = be_read32(data + i + 20) / 10000.0; - } - - track_add_wpt(track, wpt); - } + const int recordsizes[3] = {8, 20, 32}; + int i, style, recsize; + int lat, lon, bintime, bindate; + waypoint* wpt; + + /* the first record of each file is always full-sized; its style field + * determines the format of all subsequent records in the file */ + style = be_read32(data + 28); + if (style > 2) { + fprintf(stderr, "unknown GPS record style %d", style); + return; + } + recsize = recordsizes[style]; + + for (i = 0; i <= 2048 - recsize; i += (i == 0) ? 32 : recsize) { + float latitude; + int manual_point = 0; + + lat = be_read32(data + i + 0); + lon = be_read32(data + i + 4); + + /* skip invalid trackpoints (blank records) */ + if (lat == -1 && lon == -1) { + continue; + } + + if ((i == 0) && (be_read32(data + i + 8) & 0x80000000)) { + /* This is the first point recorded after power-on; start a new track */ + *track = NULL; + } + + if (*track == NULL) { + time_t creation_time; + char buf[1024]; + bintime = be_read32(data + i + 8) & 0x7FFFFFFF; + bindate = be_read32(data + i + 12); + creation_time = bintime2utc(bindate, bintime); + strftime(buf, 4096, "DG-100 tracklog (%Y/%m/%d %H:%M:%S)", + gmtime(&creation_time)); + *track = route_head_alloc(); + (*track)->rte_name = xstrdup(buf); + (*track)->rte_desc = xstrdup("DG-100 GPS tracklog data"); + track_add_head(*track); + } + + wpt = waypt_new(); + latitude = bin2deg(lat); + if (latitude >= 100) { + manual_point = 1; + latitude -= 100; + } + else if (latitude <= -100) { + manual_point = 1; + latitude += 100; + } + wpt->latitude = latitude; + wpt->longitude = bin2deg(lon); + + if (style >= 1) { + bintime = be_read32(data + i + 8) & 0x7FFFFFFF; + bindate = be_read32(data + i + 12); + wpt->creation_time = bintime2utc(bindate, bintime); + /* The device presents the speed as a fixed-point number + * with a scaling factor of 100, in km/h. + * The waypoint struct wants the speed as a + * floating-point number, in m/s. */ + wpt->speed = KPH_TO_MPS(be_read32(data + i + 16) / 100.0); + wpt->wpt_flags.speed = 1; + } + + if (style >= 2) { + wpt->altitude = be_read32(data + i + 20) / 10000.0; + } + + if (manual_point) { + waypt_add(wpt); + } + else { + track_add_wpt(*track, wpt); + } + } } static gbuint16 dg100_checksum(gbuint8 buf[], int count) { - gbuint16 sum = 0; - int i; + gbuint16 sum = 0; + int i; - for (i = 0; i < count; i++) { - sum += buf[i]; - } - sum &= (1<<15) - 1; + for (i = 0; i < count; i++) { + sum += buf[i]; + } + sum &= (1<<15) - 1; - return(sum); + return(sum); } /* communication functions */ static size_t -dg100_send(gbuint8 cmd, const void *payload, size_t count) +dg100_send(gbuint8 cmd, const void* payload, size_t count) { - gbuint8 frame[FRAME_MAXLEN]; - gbuint16 checksum, payload_len; - size_t framelen, param_len; - int n; - - param_len = count; - payload_len = 1 + count; - /* Frame length calculation: - * frame start sequence(2), payload length field(2), command id(1), - * param(variable length), - * checksum(2), frame end sequence(2) */ - framelen = 2 + 2 + 1 + count + 2 + 2; - assert(framelen <= FRAME_MAXLEN); - - /* create frame head + command */ - be_write16(frame + 0, 0xA0A2); - be_write16(frame + 2, payload_len); - frame[4] = cmd; - - /* copy payload */ - memcpy(frame + 5, payload, count); - - /* create frame tail */ - checksum = dg100_checksum(frame + 4, framelen - 8); - be_write16(frame + framelen - 4, checksum); - be_write16(frame + framelen - 2, 0xB0B3); - - n = gbser_write(serial_handle, frame, framelen); - - if (global_opts.debug_level) { - struct dg100_command *cmdp = dg100_findcmd(cmd); - - dg100_debug(n == 0 ? "Sent: " : "Error Sending:", - 1, framelen, frame); - dg100_log("TX: Frame Start %02x %02x Payload_Len %04x Cmd: %s\n", - frame[0], frame[1], payload_len, cmdp->text); - } - - if (n == gbser_ERROR) { - fatal("dg_100_send: write failed\n"); - } - return (n); + gbuint8 frame[FRAME_MAXLEN]; + gbuint16 checksum, payload_len; + size_t framelen, param_len; + int n; + + param_len = count; + payload_len = 1 + count; + /* Frame length calculation: + * frame start sequence(2), payload length field(2), command id(1), + * param(variable length), + * checksum(2), frame end sequence(2) */ + framelen = 2 + 2 + 1 + count + 2 + 2; + assert(framelen <= FRAME_MAXLEN); + + /* create frame head + command */ + be_write16(frame + 0, 0xA0A2); + be_write16(frame + 2, payload_len); + frame[4] = cmd; + + /* copy payload */ + memcpy(frame + 5, payload, count); + + /* create frame tail */ + checksum = dg100_checksum(frame + 4, framelen - 8); + be_write16(frame + framelen - 4, checksum); + be_write16(frame + framelen - 2, 0xB0B3); + + n = gbser_write(serial_handle, frame, framelen); + + if (global_opts.debug_level) { + struct dg100_command* cmdp = dg100_findcmd(cmd); + + dg100_debug(n == 0 ? "Sent: " : "Error Sending:", + 1, framelen, frame); + dg100_log("TX: Frame Start %02x %02x Payload_Len %04x Cmd: %s\n", + frame[0], frame[1], payload_len, cmdp->text); + } + + if (n == gbser_ERROR) { + fatal("dg_100_send: write failed\n"); + } + return (n); } static int dg100_recv_byte() { - int result; - - /* allow for a delay of 40s; - * erasing the whole DG-100 memory takes about 21s */ - result = gbser_readc_wait(serial_handle, 40000); - switch(result){ - case gbser_ERROR: - fatal("dg100_recv_byte(): error reading one byte\n"); - case gbser_NOTHING: - fatal("dg100_recv_byte(): read timeout\n"); - } - return result; + int result; + + /* allow for a delay of 40s; + * erasing the whole DG-100 memory takes about 21s */ + result = gbser_readc_wait(serial_handle, 40000); + switch (result) { + case gbser_ERROR: + fatal("dg100_recv_byte(): error reading one byte\n"); + case gbser_NOTHING: + fatal("dg100_recv_byte(): read timeout\n"); + } + return result; } /* payload returns a pointer into a static buffer (which also contains the * framing around the data), so the caller must copy the data before calling * this function again */ static int -dg100_recv_frame(struct dg100_command **cmdinfo_result, gbuint8 **payload) +dg100_recv_frame(struct dg100_command** cmdinfo_result, gbuint8** payload) { - static gbuint8 buf[FRAME_MAXLEN]; - gbuint16 frame_start_seq, payload_len_field; - gbuint16 payload_end_seq, payload_checksum, frame_end_seq; - gbuint16 frame_head, numheaders, sum; - gbuint8 c, cmd; - int i, param_len, frame_len; - struct dg100_command *cmdinfo; - - /* consume input until frame head sequence 0xA0A2 was received */ - frame_head = 0; - dg100_debug("Receiving ", 0, 0, NULL); - do { - c = dg100_recv_byte(); - dg100_debug("", 0, 1, &c); - frame_head <<= 8; - frame_head |= c; - - } while (frame_head != 0xA0A2); - - be_write16(buf + 0, frame_head); - - /* To read the remaining data, we need to know how long the frame is. - * - * The obvious source of this information would be the payload length - * field, but the spec says that this field should be ignored in answers. - * Indeed, its value differs from the actual payload length. - * - * We could scan for the frame end sequences, - * but there is no guarantee that they do not appear within valid data. - * - * This means we can only calculate the length using information from - * the beginning of the frame, other than the payload length. - * - * The solution implemented here is to derive the frame length from the - * Command ID field, which is more of an answer ID. This is possible - * since for each answer ID, the frame length is either constant or it - * can be derived from the first two bytes of payload data. - */ - - /* read Payload Length, Command ID, and two further bytes */ - i = gbser_read_wait(serial_handle, &buf[2], 5, 1000); - if (i < 5) { - fatal("Expected to read 5 bytes, but got %d\n", i); - } - dg100_debug("", 0, 5, &buf[2]); - - payload_len_field = be_read16(buf + 2); - cmd = buf[4]; - - /* - * getconfig/setconfig have the same answer ID - - * this seems to be a firmware bug we must work around. - * Distinguish them by the (otherwise ignored) Payload Len field, - * which was observed as 53 for getconfig and 5 for setconfig. - */ - if (cmd == dg100cmd_getconfig && payload_len_field <= 20) { - cmd = dg100cmd_setconfig; - } - - cmdinfo = dg100_findcmd(cmd); - if (!cmdinfo) { - /* TODO: consume data until frame end signature, - * then report failure to the caller? */ - fatal("unknown answer ID %02x\n", cmd); - } - - param_len = cmdinfo->recvsize; - - /* - * the getfileheader answer has a varying param_len, - * we need to calculate it - */ - if (cmd == dg100cmd_getfileheader) { - numheaders = be_read16(buf + 5); - param_len = 2 + 2 + 12 * numheaders + 2; - } - - /* Frame length calculation: - * frame start sequence(2), payload length field(2), command id(1), - * param(variable length), - * payload end seqence(2), checksum(2), frame end sequence(2) */ - frame_len = 2 + 2 + 1 + param_len + 2 + 2 + 2; - - if (frame_len > FRAME_MAXLEN) { - fatal("frame too large (frame_len=%d, FRAME_MAXLEN=%d)\n", - frame_len, FRAME_MAXLEN); - } - - i = gbser_read_wait(serial_handle, &buf[7], frame_len - 7, 1000); - if (i < frame_len - 7) { - fatal("Expected to read %d bytes, but got %d\n", - frame_len - 7, i); - } - dg100_debug("", 0, frame_len - 7, &buf[7]); - - frame_start_seq = be_read16(buf + 0); - payload_len_field = be_read16(buf + 2); - payload_end_seq = be_read16(buf + frame_len - 6); - payload_checksum = be_read16(buf + frame_len - 4); - frame_end_seq = be_read16(buf + frame_len - 2); - - dg100_log("RX: Start %04x Len %04x Cmd: %s\n", - frame_start_seq, payload_len_field, cmdinfo->text); - - /* calculate checksum */ - sum = dg100_checksum(buf + 4, frame_len - 8); - if (sum != payload_checksum) { - fatal("checksum mismatch: data sum is 0x%04x, checksum received is 0x%04x\n", - sum, payload_checksum); - } - - /* - * TODO: check signatures; - * on failure, flush input or scan for end sequence - */ - - *cmdinfo_result = cmdinfo; - *payload = buf + 5; - dg100_debug("\n", 0, 0, &buf[i]); - return(param_len); + static gbuint8 buf[FRAME_MAXLEN]; + gbuint16 frame_start_seq, payload_len_field; + gbuint16 payload_end_seq, payload_checksum, frame_end_seq; + gbuint16 frame_head, numheaders, sum; + gbuint8 c, cmd; + int i, param_len, frame_len; + struct dg100_command* cmdinfo; + + /* consume input until frame head sequence 0xA0A2 was received */ + frame_head = 0; + dg100_debug("Receiving ", 0, 0, NULL); + do { + c = dg100_recv_byte(); + dg100_debug("", 0, 1, &c); + frame_head <<= 8; + frame_head |= c; + + } while (frame_head != 0xA0A2); + + be_write16(buf + 0, frame_head); + + /* To read the remaining data, we need to know how long the frame is. + * + * The obvious source of this information would be the payload length + * field, but the spec says that this field should be ignored in answers. + * Indeed, its value differs from the actual payload length. + * + * We could scan for the frame end sequences, + * but there is no guarantee that they do not appear within valid data. + * + * This means we can only calculate the length using information from + * the beginning of the frame, other than the payload length. + * + * The solution implemented here is to derive the frame length from the + * Command ID field, which is more of an answer ID. This is possible + * since for each answer ID, the frame length is either constant or it + * can be derived from the first two bytes of payload data. + */ + + /* read Payload Length, Command ID, and two further bytes */ + i = gbser_read_wait(serial_handle, &buf[2], 5, 1000); + if (i < 5) { + fatal("Expected to read 5 bytes, but got %d\n", i); + } + dg100_debug("", 0, 5, &buf[2]); + + payload_len_field = be_read16(buf + 2); + cmd = buf[4]; + + /* + * getconfig/setconfig have the same answer ID - + * this seems to be a firmware bug we must work around. + * Distinguish them by the (otherwise ignored) Payload Len field, + * which was observed as 53 for getconfig and 5 for setconfig. + */ + if (cmd == dg100cmd_getconfig && payload_len_field <= 20) { + cmd = dg100cmd_setconfig; + } + + cmdinfo = dg100_findcmd(cmd); + if (!cmdinfo) { + /* TODO: consume data until frame end signature, + * then report failure to the caller? */ + fatal("unknown answer ID %02x\n", cmd); + } + + param_len = cmdinfo->recvsize; + + /* + * the getfileheader answer has a varying param_len, + * we need to calculate it + */ + if (cmd == dg100cmd_getfileheader) { + numheaders = be_read16(buf + 5); + param_len = 2 + 2 + 12 * numheaders; + } + + if (model->has_trailing_bytes) { + param_len += cmdinfo->trailing_bytes; + } + + /* Frame length calculation: + * frame start sequence(2), payload length field(2), command id(1), + * param(variable length), + * payload end seqence(2 or 0), checksum(2), frame end sequence(2) */ + frame_len = 2 + 2 + 1 + param_len + ((model->has_payload_end_seq) ? 2 : 0) + 2 + 2; + + if (frame_len > FRAME_MAXLEN) { + fatal("frame too large (frame_len=%d, FRAME_MAXLEN=%d)\n", + frame_len, FRAME_MAXLEN); + } + + i = gbser_read_wait(serial_handle, &buf[7], frame_len - 7, 1000); + if (i < frame_len - 7) { + fatal("Expected to read %d bytes, but got %d\n", + frame_len - 7, i); + } + dg100_debug("", 0, frame_len - 7, &buf[7]); + + frame_start_seq = be_read16(buf + 0); + payload_len_field = be_read16(buf + 2); + if (model->has_payload_end_seq) { + payload_end_seq = be_read16(buf + frame_len - 6); + } + payload_checksum = be_read16(buf + frame_len - 4); + frame_end_seq = be_read16(buf + frame_len - 2); + + dg100_log("RX: Start %04x Len %04x Cmd: %s\n", + frame_start_seq, payload_len_field, cmdinfo->text); + + /* calculate checksum */ + sum = dg100_checksum(buf + 4, frame_len - 8); + if (sum != payload_checksum) { + fatal("checksum mismatch: data sum is 0x%04x, checksum received is 0x%04x\n", + sum, payload_checksum); + } + + /* + * TODO: check signatures; + * on failure, flush input or scan for end sequence + */ + + *cmdinfo_result = cmdinfo; + *payload = buf + 5; + dg100_debug("\n", 0, 0, &buf[i]); + return(param_len); } /* return value: number of bytes copied into buf, -1 on error */ static int -dg100_recv(gbuint8 expected_id, void *buf, unsigned int len) +dg100_recv(gbuint8 expected_id, void* buf, unsigned int len) { - int n; - struct dg100_command *cmdinfo; - gbuint8 *data; - unsigned int copysize, trailing_bytes; - - n = dg100_recv_frame(&cmdinfo, &data); - - /* check whether the received frame matches the expected answer type */ - if (cmdinfo->id != expected_id) { - fprintf(stderr, "ERROR: answer type %02x, expecting %02x", cmdinfo->id, expected_id); - return -1; - } - - trailing_bytes = cmdinfo->trailing_bytes; - copysize = n - trailing_bytes; - - /* check for buffer overflow */ - if (len < copysize) { - fprintf(stderr, "ERROR: buffer too small, size=%d, need=%d", len, copysize); - return -1; - } - - memcpy(buf, data, copysize); - return(copysize); + int n; + struct dg100_command* cmdinfo; + gbuint8* data; + unsigned int copysize, trailing_bytes; + + n = dg100_recv_frame(&cmdinfo, &data); + + /* check whether the received frame matches the expected answer type */ + if (cmdinfo->id != expected_id) { + fprintf(stderr, "ERROR: answer type %02x, expecting %02x", cmdinfo->id, expected_id); + return -1; + } + + trailing_bytes = (model->has_trailing_bytes) ? (cmdinfo->trailing_bytes) : 0; + copysize = n - trailing_bytes; + + /* check for buffer overflow */ + if (len < copysize) { + fprintf(stderr, "ERROR: buffer too small, size=%d, need=%d", len, copysize); + return -1; + } + + memcpy(buf, data, copysize); + return(copysize); } /* the number of bytes to be sent is determined by cmd, * count is the size of recvbuf */ static int -dg100_request(gbuint8 cmd, const void *sendbuf, void *recvbuf, size_t count) +dg100_request(gbuint8 cmd, const void* sendbuf, void* recvbuf, size_t count) { - struct dg100_command *cmdinfo; - int n, i, frames, fill; - gbuint8 *buf; - - cmdinfo = dg100_findcmd(cmd); - assert (cmdinfo != NULL); - dg100_send(cmd, sendbuf, cmdinfo->sendsize); - - /* the number of frames the answer will comprise */ - frames = (cmd == dg100cmd_getfile) ? 2 : 1; - /* alias pointer for easy typecasting */ - buf = recvbuf; - fill = 0; - for (i = 0; i < frames; i++) { - n = dg100_recv(cmd, buf + fill, count - fill); - if (n < 0) - return(-1); - fill += n; - } - return(fill); + struct dg100_command* cmdinfo; + int n, i, frames, fill; + gbuint8* buf; + + cmdinfo = dg100_findcmd(cmd); + assert(cmdinfo != NULL); + dg100_send(cmd, sendbuf, cmdinfo->sendsize); + + /* the number of frames the answer will comprise */ + frames = (cmd == dg100cmd_getfile) ? 2 : 1; + /* alias pointer for easy typecasting */ + buf = (gbuint8*) recvbuf; + fill = 0; + for (i = 0; i < frames; i++) { + n = dg100_recv(cmd, buf + fill, count - fill); + if (n < 0) { + return(-1); + } + fill += n; + } + return(fill); } /* higher level communication functions */ static void -dg100_getfileheaders(struct dynarray16 *headers) +dg100_getfileheaders(struct dynarray16* headers) { - gbuint8 request[2]; - gbuint8 answer[FRAME_MAXLEN]; - int seqnum; - gbint16 numheaders, nextheader, *h; - int i, offset; - - nextheader = 0; - do { - /* request the next batch of headers */ - be_write16(request, nextheader); - dg100_request(dg100cmd_getfileheader, request, answer, sizeof(answer)); - - /* process the answer */ - numheaders = be_read16(answer); - nextheader = be_read16(answer + 2); - dg100_log("found %d headers, nextheader=%d\n", - numheaders, nextheader); - if (numheaders <= 0) { - dg100_log("no further headers, aborting the loop\n"); - break; - } - - h = dynarray16_alloc(headers, numheaders); - for (i = 0; i < numheaders; i++) { - offset = 4 + i * 12; - seqnum = be_read32(answer + offset + 8); - h[i] = seqnum; - if (global_opts.debug_level) { - int time = be_read32(answer + offset); - int date = be_read32(answer + offset + 4); - time_t ti = bintime2utc(date, time); - dg100_log("Header #%d: Seq: %d Time: %s", - i, seqnum, ctime(&ti)); - } - } - } while (nextheader != 0); + gbuint8 request[2]; + gbuint8 answer[FRAME_MAXLEN]; + int seqnum; + gbint16 numheaders, nextheader, *h; + int i, offset; + + nextheader = 0; + do { + /* request the next batch of headers */ + be_write16(request, nextheader); + dg100_request(dg100cmd_getfileheader, request, answer, sizeof(answer)); + + /* process the answer */ + numheaders = be_read16(answer); + nextheader = be_read16(answer + 2); + dg100_log("found %d headers, nextheader=%d\n", + numheaders, nextheader); + if (numheaders <= 0) { + dg100_log("no further headers, aborting the loop\n"); + break; + } + + h = dynarray16_alloc(headers, numheaders); + for (i = 0; i < numheaders; i++) { + offset = 4 + i * 12; + seqnum = be_read32(answer + offset + 8); + h[i] = seqnum; + if (global_opts.debug_level) { + int time = be_read32(answer + offset) & 0x7FFFFFFF; + int date = be_read32(answer + offset + 4); + time_t ti = bintime2utc(date, time); + dg100_log("Header #%d: Seq: %d Time: %s", + i, seqnum, ctime(&ti)); + } + } + } while (nextheader != 0); } static void -dg100_getfile(gbint16 num, route_head *track) +dg100_getfile(gbint16 num, route_head** track) { - gbuint8 request[2]; - gbuint8 answer[2048]; + gbuint8 request[2]; + gbuint8 answer[2048]; - be_write16(request, num); - dg100_request(dg100cmd_getfile, request, answer, sizeof(answer)); - process_gpsfile(answer, track); + be_write16(request, num); + dg100_request(dg100cmd_getfile, request, answer, sizeof(answer)); + process_gpsfile(answer, track); } static void dg100_getfiles() { - unsigned int i; - int filenum; - struct dynarray16 headers; - route_head *track; - - track = route_head_alloc(); - track->rte_name = xstrdup("DG-100 tracklog"); - track->rte_desc = xstrdup("DG-100 GPS tracklog data"); - track_add_head(track); - - /* maximum number of headers observed so far: 672 - * if necessary, the dynarray will grow even further */ - dynarray16_init(&headers, 1024); - - dg100_getfileheaders(&headers); - - for (i = 0; i < headers.count; i++) { - filenum = headers.data[i]; - dg100_getfile(filenum, track); - } + unsigned int i; + int filenum; + struct dynarray16 headers; + route_head* track = NULL; + + /* maximum number of headers observed so far: 672 + * if necessary, the dynarray will grow even further */ + dynarray16_init(&headers, 1024); + + dg100_getfileheaders(&headers); + + for (i = 0; i < headers.count; i++) { + filenum = headers.data[i]; + dg100_getfile(filenum, &track); + } } static int dg100_erase() { - gbuint8 request[2] = { 0xFF, 0xFF }; - gbuint8 answer[4]; - - dg100_request(dg100cmd_erase, request, answer, sizeof(answer)); - if (be_read32(answer) != 1) { - fprintf(stderr, "dg100_erase() FAILED\n"); - return(-1); - } - return(0); + gbuint8 request[2] = { 0xFF, 0xFF }; + gbuint8 answer[4]; + + dg100_request(dg100cmd_erase, request, answer, sizeof(answer)); + if (be_read32(answer) != 1) { + fprintf(stderr, "dg100_erase() FAILED\n"); + return(-1); + } + return(0); } /* GPSBabel integration */ -static char *erase; -static char *erase_only; +static char* erase; +static char* erase_only; static arglist_t dg100_args[] = { - { "erase", &erase, "Erase device data after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "erase_only", &erase_only, "Only erase device data, do not download anything", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "erase", &erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "erase_only", &erase_only, "Only erase device data, do not download anything", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /******************************************************************************* @@ -635,37 +685,53 @@ arglist_t dg100_args[] = { *******************************************************************************/ static void -dg100_rd_init(const char *fname) +common_rd_init(const char* fname) +{ + if (serial_handle = gbser_init(fname), NULL == serial_handle) { + fatal(MYNAME ": Can't open port '%s'\n", fname); + } + if (gbser_set_speed(serial_handle, model->speed) != gbser_OK) { + fatal(MYNAME ": Can't configure port '%s'\n", fname); + } + // Toss anything that came in before our speed was set, particularly + // for the bluetooth BT-335 product. + gbser_flush(serial_handle); +} + +static void +dg100_rd_init(const char* fname) +{ + static const model_t dg100_model = { 115200, 1, 1 }; + model = &dg100_model; + common_rd_init(fname); +} + +static void +dg200_rd_init(const char* fname) { - if (serial_handle = gbser_init(fname), NULL == serial_handle) { - fatal(MYNAME ": Can't open port '%s'\n", fname); - } - if (gbser_set_speed(serial_handle, 115200) != gbser_OK) { - fatal(MYNAME ": Can't configure port '%s'\n", fname); - } - // Toss anything that came in before our speed was set, particularly - // for the bluetooth BT-335 product. - gbser_flush(serial_handle); + static const model_t dg200_model = { 230400, 0, 0 }; + model = &dg200_model; + common_rd_init(fname); } -static void +static void dg100_rd_deinit(void) { - gbser_deinit(serial_handle); - serial_handle = NULL; + gbser_deinit(serial_handle); + serial_handle = NULL; } static void dg100_read(void) { - if (*erase_only == '1') { - dg100_erase(); - return; - } - dg100_getfiles(); - if (*erase == '1') { - dg100_erase(); - } + if (*erase_only == '1') { + dg100_erase(); + return; + } + dg100_getfiles(); + if (*erase == '1') { + dg100_erase(); + } } /**************************************************************************/ @@ -673,21 +739,40 @@ dg100_read(void) // capabilities below means: we can only read tracks ff_vecs_t dg100_vecs = { - ff_type_serial, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - dg100_rd_init, - NULL, - dg100_rd_deinit, - NULL, - dg100_read, - NULL, - NULL, - dg100_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + dg100_rd_init, + NULL, + dg100_rd_deinit, + NULL, + dg100_read, + NULL, + NULL, + dg100_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ +}; + +ff_vecs_t dg200_vecs = { + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + dg200_rd_init, + NULL, + dg100_rd_deinit, + NULL, + dg100_read, + NULL, + NULL, + dg100_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/discard.c b/gpsbabel/discard.c index 9e380a2b7..fae159299 100644 --- a/gpsbabel/discard.c +++ b/gpsbabel/discard.c @@ -23,151 +23,180 @@ #include "filterdefs.h" #if FILTERS_ENABLED -static char *hdopopt = NULL; -static char *vdopopt = NULL; -static char *andopt = NULL; -static char *satopt = NULL; -static char *fixnoneopt = NULL; -static char *fixunknownopt = NULL; -static char *eleminopt = NULL; -static char *elemaxopt = NULL; +static char* hdopopt = NULL; +static char* vdopopt = NULL; +static char* andopt = NULL; +static char* satopt = NULL; +static char* fixnoneopt = NULL; +static char* fixunknownopt = NULL; +static char* eleminopt = NULL; +static char* elemaxopt = NULL; static double hdopf; static double vdopf; static int satpf; static int eleminpf; static int elemaxpf; static gpsdata_type what; -static route_head *head; +static route_head* head; static arglist_t fix_args[] = { - {"hdop", &hdopopt, "Suppress waypoints with higher hdop", - "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"vdop", &vdopopt, "Suppress waypoints with higher vdop", - "-1.0", ARGTYPE_END_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"hdopandvdop", &andopt, "Link hdop and vdop supression with AND", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"sat", &satopt, "Minimium sats to keep waypoints", - "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX}, - {"fixnone", &fixnoneopt, "Suppress waypoints without fix", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"fixunknown", &fixunknownopt, "Suppress waypoints with unknown fix", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"elemin", &eleminopt, "Suppress waypoints below given elevation in meters", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX}, - {"elemax", &elemaxopt, "Suppress waypoints above given elevation in meters", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "hdop", &hdopopt, "Suppress waypoints with higher hdop", + "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "vdop", &vdopopt, "Suppress waypoints with higher vdop", + "-1.0", ARGTYPE_END_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "hdopandvdop", &andopt, "Link hdop and vdop supression with AND", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "sat", &satopt, "Minimium sats to keep waypoints", + "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX + }, + { + "fixnone", &fixnoneopt, "Suppress waypoints without fix", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "fixunknown", &fixunknownopt, "Suppress waypoints with unknown fix", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "elemin", &eleminopt, "Suppress waypoints below given elevation in meters", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX + }, + { + "elemax", &elemaxopt, "Suppress waypoints above given elevation in meters", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /* * Decide whether to keep or toss this point. */ static void -fix_process_wpt(const waypoint *wpt) +fix_process_wpt(const waypoint* wpt) { - int del = 0; - int delh = 0; - int delv = 0; - - waypoint *waypointp = (waypoint *) wpt; - - if ((hdopf >= 0.0) && (waypointp->hdop > hdopf)) - delh = 1; - if ((vdopf >= 0.0) && (waypointp->vdop > vdopf)) - delv = 1; - - if (andopt) - del = delh && delv; - else - del = delh || delv; - - if ((satpf >= 0) && (waypointp->sat < satpf)) - del = 1; - - if ((fixnoneopt) && (waypointp->fix == fix_none)) - del = 1; - - if ((fixunknownopt) && (waypointp->fix == fix_unknown)) - del = 1; - - if ((eleminopt) && (waypointp->altitude < eleminpf)) - del = 1; - - if ((elemaxopt) && (waypointp->altitude > elemaxpf)) - del = 1; - - if (del) { - switch(what) { - case wptdata: - waypt_del(waypointp); - break; - case trkdata: - track_del_wpt(head, waypointp); - break; - case rtedata: - route_del_wpt(head, waypointp); - break; - default: - return; - } - waypt_free(waypointp); - } + int del = 0; + int delh = 0; + int delv = 0; + + waypoint* waypointp = (waypoint*) wpt; + + if ((hdopf >= 0.0) && (waypointp->hdop > hdopf)) { + delh = 1; + } + if ((vdopf >= 0.0) && (waypointp->vdop > vdopf)) { + delv = 1; + } + + if (andopt) { + del = delh && delv; + } else { + del = delh || delv; + } + + if ((satpf >= 0) && (waypointp->sat < satpf)) { + del = 1; + } + + if ((fixnoneopt) && (waypointp->fix == fix_none)) { + del = 1; + } + + if ((fixunknownopt) && (waypointp->fix == fix_unknown)) { + del = 1; + } + + if ((eleminopt) && (waypointp->altitude < eleminpf)) { + del = 1; + } + + if ((elemaxopt) && (waypointp->altitude > elemaxpf)) { + del = 1; + } + + if (del) { + switch (what) { + case wptdata: + waypt_del(waypointp); + break; + case trkdata: + track_del_wpt(head, waypointp); + break; + case rtedata: + route_del_wpt(head, waypointp); + break; + default: + return; + } + waypt_free(waypointp); + } } static void -fix_process_head(const route_head *trk) +fix_process_head(const route_head* trk) { - head = (route_head *)trk; + head = (route_head*)trk; } static void fix_process(void) { - // Filter waypoints. - what = wptdata; - waypt_disp_all(fix_process_wpt); - - // Filter tracks - what = trkdata; - track_disp_all(fix_process_head, NULL, fix_process_wpt); - - // And routes - what = rtedata; - route_disp_all(fix_process_head, NULL, fix_process_wpt); - + // Filter waypoints. + what = wptdata; + waypt_disp_all(fix_process_wpt); + + // Filter tracks + what = trkdata; + track_disp_all(fix_process_head, NULL, fix_process_wpt); + + // And routes + what = rtedata; + route_disp_all(fix_process_head, NULL, fix_process_wpt); + } static void -fix_init(const char *args) +fix_init(const char* args) { - if (hdopopt) - hdopf = atof(hdopopt); - else - hdopf = -1.0; - - if (vdopopt) - vdopf = atof(vdopopt); - else - vdopf = -1.0; - - if (satopt) - satpf = atoi(satopt); - else - satpf = -1; - - if (eleminopt) - eleminpf = atoi(eleminopt); - - if (elemaxopt) - elemaxpf = atoi(elemaxopt); + if (hdopopt) { + hdopf = atof(hdopopt); + } else { + hdopf = -1.0; + } + + if (vdopopt) { + vdopf = atof(vdopopt); + } else { + vdopf = -1.0; + } + + if (satopt) { + satpf = atoi(satopt); + } else { + satpf = -1; + } + + if (eleminopt) { + eleminpf = atoi(eleminopt); + } + + if (elemaxopt) { + elemaxpf = atoi(elemaxopt); + } } filter_vecs_t discard_vecs = { - fix_init, - fix_process, - NULL, - NULL, - fix_args + fix_init, + fix_process, + NULL, + NULL, + fix_args }; #endif diff --git a/gpsbabel/dmtlog.c b/gpsbabel/dmtlog.c index 8f0088899..762076383 100644 --- a/gpsbabel/dmtlog.c +++ b/gpsbabel/dmtlog.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include "jeeps/gpsmath.h" #include "xmlgeneric.h" @@ -32,12 +32,12 @@ #define DEFLATE_BUFF_SIZE 16384 -static gbfile *fin, *fout; +static gbfile* fin, *fout; -static char *xmlbin; -static waypoint *xmlwpt; -static route_head *xmltrk; -static char *xmlgrid; +static char* xmlbin; +static waypoint* xmlwpt; +static route_head* xmltrk; +static char* xmlgrid; static int xmldatum; static double xmlEasting, xmlNorthing; static double xmlLatitude, xmlLongitude; @@ -48,14 +48,16 @@ static int xmlbinsize; #endif static char header_written; -static char *opt_index; +static char* opt_index; static int track_index, this_index; static arglist_t dmtlog_args[] = { - { "index", &opt_index, - "Index of track (if more than one in source)", "1", ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR + { + "index", &opt_index, + "Index of track (if more than one in source)", "1", ARGTYPE_INT, "1", NULL + }, + ARG_TERMINATOR }; @@ -63,10 +65,10 @@ arglist_t dmtlog_args[] = { static xg_callback tlog3a_xgcb_version, tlog3a_xgcb_length, tlog3a_xgcb_data; static xg_tag_mapping tlog3a_xgcb_map[] = { - { tlog3a_xgcb_version, cb_cdata, "/CXMLSafe/Version" }, - { tlog3a_xgcb_length, cb_cdata, "/CXMLSafe/Length" }, - { tlog3a_xgcb_data, cb_cdata, "/CXMLSafe/Data" }, - { NULL, 0, NULL} + { tlog3a_xgcb_version, cb_cdata, "/CXMLSafe/Version" }, + { tlog3a_xgcb_length, cb_cdata, "/CXMLSafe/Length" }, + { tlog3a_xgcb_data, cb_cdata, "/CXMLSafe/Data" }, + { NULL, (xg_cb_type)0, NULL} }; #endif @@ -79,526 +81,558 @@ static xg_callback tlog3b_xgcb_wptno, tlog3b_xgcb_wptal; static xg_callback tlog3b_xgcb_tptdt; static xg_tag_mapping tlog3b_xgcb_map[] = { - { tlog3b_xgcb_tfna, cb_cdata, "/CTrackFile/Name" }, - { tlog3b_xgcb_tfdes, cb_cdata, "/CTrackFile/Description" }, - { tlog3b_xgcb_wptst, cb_start, "/CTrackFile/CWayPoint" }, - { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CWayPoint/Id" }, - { tlog3b_xgcb_wptdt, cb_cdata, "/CTrackFile/CWayPoint/Datum" }, - { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CWayPoint/Grid" }, - { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CWayPoint/Easting" }, - { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CWayPoint/Northing" }, - { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CWayPoint/Altitude" }, - { tlog3b_xgcb_wpten, cb_end, "/CTrackFile/CWayPoint" }, - { tlog3b_xgcb_tptst, cb_start, "/CTrackFile/CTrackPoint" }, - { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CTrackPoint/Id" }, - { tlog3b_xgcb_tptdt, cb_cdata, "/CTrackFile/CTrackPoint/Datum" }, - { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CTrackPoint/Grid" }, - { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CTrackPoint/Easting" }, - { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CTrackPoint/Northing" }, - { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CTrackPoint/Altitude" }, - { tlog3b_xgcb_tpten, cb_end, "/CTrackFile/CTrackPoint" }, - { NULL, 0, NULL} + { tlog3b_xgcb_tfna, cb_cdata, "/CTrackFile/Name" }, + { tlog3b_xgcb_tfdes, cb_cdata, "/CTrackFile/Description" }, + { tlog3b_xgcb_wptst, cb_start, "/CTrackFile/CWayPoint" }, + { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CWayPoint/Id" }, + { tlog3b_xgcb_wptdt, cb_cdata, "/CTrackFile/CWayPoint/Datum" }, + { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CWayPoint/Grid" }, + { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CWayPoint/Easting" }, + { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CWayPoint/Northing" }, + { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CWayPoint/Altitude" }, + { tlog3b_xgcb_wpten, cb_end, "/CTrackFile/CWayPoint" }, + { tlog3b_xgcb_tptst, cb_start, "/CTrackFile/CTrackPoint" }, + { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CTrackPoint/Id" }, + { tlog3b_xgcb_tptdt, cb_cdata, "/CTrackFile/CTrackPoint/Datum" }, + { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CTrackPoint/Grid" }, + { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CTrackPoint/Easting" }, + { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CTrackPoint/Northing" }, + { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CTrackPoint/Altitude" }, + { tlog3b_xgcb_tpten, cb_end, "/CTrackFile/CTrackPoint" }, + { NULL, (xg_cb_type)0, NULL} }; /* helpers */ static void -convert_datum(waypoint *wpt, int datum) +convert_datum(waypoint* wpt, int datum) { - if (datum != DATUM_WGS84) { - double lat = wpt->latitude; - double lon = wpt->longitude; - double alt = wpt->altitude; - GPS_Math_Known_Datum_To_WGS84_C(lat, lon, alt, - &wpt->latitude, &wpt->longitude, &wpt->altitude, - datum); - } + if (datum != DATUM_WGS84) { + double lat = wpt->latitude; + double lon = wpt->longitude; + double alt = wpt->altitude; + GPS_Math_Known_Datum_To_WGS84_C(lat, lon, alt, + &wpt->latitude, &wpt->longitude, &wpt->altitude, + datum); + } } static void -finalize_pt(waypoint *wpt) -{ - if (strcmp(xmlgrid, "BNG") == 0) { - GPS_Math_NGENToAiry1830LatLon(xmlEasting, xmlNorthing, - &wpt->latitude, &wpt->longitude); - xmldatum = DATUM_OSGB36; - } - else { - wpt->latitude = xmlLatitude; - wpt->longitude = xmlLongitude; - } - /* NOTE: - * Alan White reports this program actually subtracts a number - * of meters ranging between 46 and 50 meters. It appears to be - * constant for each location, but different without an obvious - * correlation to ground altitude. We considered offsetting this - * in GPSBabel, but concluded it wasn't worth the bother. - * If we get complaints, probably all of our alt reading and writing - * should offset an average of 46m or so. - */ - wpt->altitude = xmlAltitude; - convert_datum(wpt, xmldatum); +finalize_pt(waypoint* wpt) +{ + if (strcmp(xmlgrid, "BNG") == 0) { + GPS_Math_NGENToAiry1830LatLon(xmlEasting, xmlNorthing, + &wpt->latitude, &wpt->longitude); + xmldatum = DATUM_OSGB36; + } else { + wpt->latitude = xmlLatitude; + wpt->longitude = xmlLongitude; + } + /* NOTE: + * Alan White reports this program actually subtracts a number + * of meters ranging between 46 and 50 meters. It appears to be + * constant for each location, but different without an obvious + * correlation to ground altitude. We considered offsetting this + * in GPSBabel, but concluded it wasn't worth the bother. + * If we get complaints, probably all of our alt reading and writing + * should offset an average of 46m or so. + */ + wpt->altitude = xmlAltitude; + convert_datum(wpt, xmldatum); } /* xml-reader callbacks */ #if !ZLIB_INHIBITED -static void -tlog3a_xgcb_version(const char *args, const char **unused) -{ - if (strcmp(args, "1") != 0) - fatal(MYNAME ": Unsupported file version '%s'!\n", args); -} - -static void -tlog3a_xgcb_length(const char *args, const char **unused) -{ -} - -static void -tlog3a_xgcb_data(const char *args, const char **unused) -{ - int len; - char *bin; - char *cin, *cout; - char cl, ch; - - len = strlen(args); - bin = xmalloc((len >> 1) + 1); - - cin = (char *)args; - cout = bin; - - cl = 0x10; - while (*cin) { - char c = *cin++; - - if (c == '\0') break; - else if ((c >= 'A') && (c <= 'F')) c -= 'A' - 10; - else if ((c >= 'a') && (c <= 'f')) c -= 'a' - 10; - else if ((c >= '0') && (c <= '9')) c -= '0'; - else continue; - - if (cl == 0x10) cl = c; - else { - ch = (cl << 4) | c; - *cout++ = ch; - cl = 0x10; - } - } - xmlbin = bin; - xmlbinsize = (cout - bin); +static void +tlog3a_xgcb_version(const char* args, const char** unused) +{ + if (strcmp(args, "1") != 0) { + fatal(MYNAME ": Unsupported file version '%s'!\n", args); + } +} + +static void +tlog3a_xgcb_length(const char* args, const char** unused) +{ +} + +static void +tlog3a_xgcb_data(const char* args, const char** unused) +{ + int len; + char* bin; + char* cin, *cout; + char cl, ch; + + len = strlen(args); + bin = (char*) xmalloc((len >> 1) + 1); + + cin = (char*)args; + cout = bin; + + cl = 0x10; + while (*cin) { + char c = *cin++; + + if (c == '\0') { + break; + } else if ((c >= 'A') && (c <= 'F')) { + c -= 'A' - 10; + } else if ((c >= 'a') && (c <= 'f')) { + c -= 'a' - 10; + } else if ((c >= '0') && (c <= '9')) { + c -= '0'; + } else { + continue; + } + + if (cl == 0x10) { + cl = c; + } else { + ch = (cl << 4) | c; + *cout++ = ch; + cl = 0x10; + } + } + xmlbin = bin; + xmlbinsize = (cout - bin); } #endif static void -tlog3b_xgcb_tfna(const char *args, const char **unused) +tlog3b_xgcb_tfna(const char* args, const char** unused) { - if (xmltrk == NULL) { - xmltrk = route_head_alloc(); - track_add_head(xmltrk); - } - xmltrk->rte_name = strdup(args); + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + xmltrk->rte_name = strdup(args); } static void -tlog3b_xgcb_tfdes(const char *args, const char **unused) +tlog3b_xgcb_tfdes(const char* args, const char** unused) { - if (xmltrk == NULL) { - xmltrk = route_head_alloc(); - track_add_head(xmltrk); - } - xmltrk->rte_desc = strdup(args); + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + xmltrk->rte_desc = strdup(args); } static void -tlog3b_xgcb_wptst(const char *args, const char **unused) +tlog3b_xgcb_wptst(const char* args, const char** unused) { - xmlwpt = waypt_new(); - xmldatum = DATUM_WGS84; + xmlwpt = waypt_new(); + xmldatum = DATUM_WGS84; } static void -tlog3b_xgcb_tptst(const char *args, const char **unused) +tlog3b_xgcb_tptst(const char* args, const char** unused) { - xmlwpt = waypt_new(); - xmldatum = DATUM_WGS84; + xmlwpt = waypt_new(); + xmldatum = DATUM_WGS84; } static void -tlog3b_xgcb_tpten(const char *args, const char **unused) +tlog3b_xgcb_tpten(const char* args, const char** unused) { - finalize_pt(xmlwpt); - - if (xmltrk == NULL) { - xmltrk = route_head_alloc(); - track_add_head(xmltrk); - } - track_add_wpt(xmltrk, xmlwpt); - xmlwpt = NULL; + finalize_pt(xmlwpt); + + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + track_add_wpt(xmltrk, xmlwpt); + xmlwpt = NULL; } static void -tlog3b_xgcb_wptid(const char *args, const char **unused) +tlog3b_xgcb_wptid(const char* args, const char** unused) { - if (*args) - xmlwpt->shortname = xstrdup(args); + if (*args) { + xmlwpt->shortname = xstrdup(args); + } } static void -tlog3b_xgcb_wptdt(const char *args, const char **unused) +tlog3b_xgcb_wptdt(const char* args, const char** unused) { - xmldatum = GPS_Lookup_Datum_Index(args); + xmldatum = GPS_Lookup_Datum_Index(args); } static void -tlog3b_xgcb_wptgr(const char *args, const char **unused) +tlog3b_xgcb_wptgr(const char* args, const char** unused) { - if (xmlgrid != NULL) { - if (strcmp(xmlgrid, args) == 0) return; - xfree(xmlgrid); - } - xmlgrid = xstrdup(args); + if (xmlgrid != NULL) { + if (strcmp(xmlgrid, args) == 0) { + return; + } + xfree(xmlgrid); + } + xmlgrid = xstrdup(args); } static void -tlog3b_xgcb_wptno(const char *args, const char **unused) +tlog3b_xgcb_wptno(const char* args, const char** unused) { - xmlNorthing = atof(args); + xmlNorthing = atof(args); } static void -tlog3b_xgcb_wptea(const char *args, const char **unused) +tlog3b_xgcb_wptea(const char* args, const char** unused) { - xmlEasting = atof(args); + xmlEasting = atof(args); } static void -tlog3b_xgcb_wptal(const char *args, const char **unused) +tlog3b_xgcb_wptal(const char* args, const char** unused) { - xmlAltitude = atof(args); + xmlAltitude = atof(args); } static void -tlog3b_xgcb_tptdt(const char *args, const char **unused) +tlog3b_xgcb_tptdt(const char* args, const char** unused) { - xmldatum = GPS_Lookup_Datum_Index(args); + xmldatum = GPS_Lookup_Datum_Index(args); } static void -tlog3b_xgcb_wpten(const char *args, const char **unused) +tlog3b_xgcb_wpten(const char* args, const char** unused) { - finalize_pt(xmlwpt); - waypt_add(xmlwpt); - xmlwpt = NULL; + finalize_pt(xmlwpt); + waypt_add(xmlwpt); + xmlwpt = NULL; } -static char * -read_str(gbfile *f) +static char* +read_str(gbfile* f) { - int i; - char *res; + int i; + char* res; + + i = gbfgetc(f); + if (i == 0xff) { + i = gbfgetint16(f); + } - i = gbfgetc(f); - if (i == 0xff) i = gbfgetint16(f); - - res = xmalloc(i + 1); - res[i] = '\0'; - if (i) gbfread(res, 1, i, f); - - return res; + res = (char*) xmalloc(i + 1); + res[i] = '\0'; + if (i) { + gbfread(res, 1, i, f); + } + + return res; } static void -write_str(const char *str, gbfile *f) +write_str(const char* str, gbfile* f) { - if (str && *str) { - int len = strlen(str); - if (len > 0xfe) { + if (str && *str) { + int len = strlen(str); + if (len > 0xfe) { #if 0 - if (len > 0x7fff) len = 0x7fff; - gbfputc((unsigned char) 0xff, f); - gbfputint16(len, f); + if (len > 0x7fff) { + len = 0x7fff; + } + gbfputc((unsigned char) 0xff, f); + gbfputint16(len, f); #else - len = 0xfe; - gbfputc(len, f); + len = 0xfe; + gbfputc(len, f); #endif - } - else gbfputc(len, f); - gbfwrite(str, len, 1, f); - } - else gbfputc(0, f); + } else { + gbfputc(len, f); + } + gbfwrite(str, len, 1, f); + } else { + gbfputc(0, f); + } } static int -read_datum(gbfile *f) +read_datum(gbfile* f) { - int res; - char *d, *g; - - d = read_str(f); - g = read_str(f); - - res = GPS_Lookup_Datum_Index(d); - - if (*g && (strcmp(d, g) != 0)) { - fatal(MYNAME ": Unsupported combination of datum '%s' and grid '%s'!\n", - d, g); - } - xfree(d); - xfree(g); - - return res; + int res; + char* d, *g; + + d = read_str(f); + g = read_str(f); + + res = GPS_Lookup_Datum_Index(d); + + if (*g && (strcmp(d, g) != 0)) { + fatal(MYNAME ": Unsupported combination of datum '%s' and grid '%s'!\n", + d, g); + } + xfree(d); + xfree(g); + + return res; } static void read_CTrackFile(const int version) { - char buf[128]; - gbuint32 ver; - gbint32 tcount, wcount; - gbint16 u1; - gbint32 ux; - route_head *track; - int i; - int datum; - - u1 = gbfgetint16(fin); - - gbfread(buf, 1, 10, fin); - if ((u1 != 0x0a) || (strncmp("CTrackFile", buf, 10) != 0)) - fatal(MYNAME ": Unknown or invalid track file.\n"); - - if (version == 8) - gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ - - ver = gbfgetint32(fin); - if (ver != version) - fatal(MYNAME ": Unknown or invalid track file (%d).\n", ver); - - ux = gbfgetint32(fin); // Unknown 2 - ux = gbfgetint32(fin); // Unknown 3 - ux = gbfgetint32(fin); // Unknown 4 - - track = route_head_alloc(); - track_add_head(track); - - /* S1 .. S9: comments, hints, jokes, aso */ - for (i = 0; i < 9; i++) { - char *s = read_str(fin); - xfree(s); - } - - tcount = gbfgetint32(fin); - if (tcount > 0) { - datum = read_datum(fin); - if (version == 8) { - int len; - - gbfread(buf, 1, 4, fin); - len = gbfgetint16(fin); - gbfseek(fin, len, SEEK_CUR); - } - } - - while (tcount > 0) - { - waypoint *wpt; - - tcount--; - - if (version == 8) - datum = read_datum(fin); - - wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - wpt->altitude = gbfgetdbl(fin); - - convert_datum(wpt, datum); - - track_add_wpt(track, wpt); - - if (version == 8) - gbfseek(fin, 34, SEEK_CUR); /* skip unknown 34 bytes */ - } - - if (version == 8) { - - i = gbfgetint16(fin); - i = gbfgetc(fin); - if (i == 0) return; - - gbfungetc(i, fin); - datum = read_datum(fin); - - (void) gbfgetint16(fin); - (void) gbfgetint32(fin); - - gbfread(buf, 1, 9, fin); - if (strncmp(buf, "CWayPoint", 9) != 0) { - warning(MYNAME ": Unsupported waypoint structure!\n"); - return; - } - - while (! gbfeof(fin)) { - waypoint *wpt; - - i = gbfgetc(fin); - if (i == 0) break; - - gbfungetc(i, fin); - datum = read_datum(fin); - - wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - wpt->altitude = gbfgetdbl(fin); - - gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ - - wpt->notes = read_str(fin); - wpt->description = read_str(fin); - (void) gbfgetint16(fin); - - waypt_add(wpt); - } - return; - } - - wcount = gbfgetint32(fin); - if (wcount == 0) return; - - datum = read_datum(fin); - - while (wcount > 0) { - waypoint *wpt; - gbint32 namect, i; - - wcount--; - - wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - wpt->altitude = gbfgetdbl(fin); - - convert_datum(wpt, datum); - - namect = gbfgetint32(fin); - - // variants of shortname - - for (i = 0; i < namect; i++) { - char *name; - - name = read_str(fin); - if (name && *name) { - switch(i) { - case 0: wpt->description = xstrdup(name); break; - case 1: wpt->shortname = xstrdup(name); break; - } - } - xfree(name); - } - - waypt_add(wpt); - } + char buf[128]; + gbuint32 ver; + gbint32 tcount, wcount; + gbint16 u1; + gbint32 ux; + route_head* track; + int i; + int datum; + + u1 = gbfgetint16(fin); + + gbfread(buf, 1, 10, fin); + if ((u1 != 0x0a) || (strncmp("CTrackFile", buf, 10) != 0)) { + fatal(MYNAME ": Unknown or invalid track file.\n"); + } + + if (version == 8) { + gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ + } + + ver = gbfgetint32(fin); + if (ver != version) { + fatal(MYNAME ": Unknown or invalid track file (%d).\n", ver); + } + + ux = gbfgetint32(fin); // Unknown 2 + ux = gbfgetint32(fin); // Unknown 3 + ux = gbfgetint32(fin); // Unknown 4 + + track = route_head_alloc(); + track_add_head(track); + + /* S1 .. S9: comments, hints, jokes, aso */ + for (i = 0; i < 9; i++) { + char* s = read_str(fin); + xfree(s); + } + + tcount = gbfgetint32(fin); + if (tcount > 0) { + datum = read_datum(fin); + if (version == 8) { + int len; + + gbfread(buf, 1, 4, fin); + len = gbfgetint16(fin); + gbfseek(fin, len, SEEK_CUR); + } + } + + while (tcount > 0) { + waypoint* wpt; + + tcount--; + + if (version == 8) { + datum = read_datum(fin); + } + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + convert_datum(wpt, datum); + + track_add_wpt(track, wpt); + + if (version == 8) { + gbfseek(fin, 34, SEEK_CUR); /* skip unknown 34 bytes */ + } + } + + if (version == 8) { + + i = gbfgetint16(fin); + i = gbfgetc(fin); + if (i == 0) { + return; + } + + gbfungetc(i, fin); + datum = read_datum(fin); + + (void) gbfgetint16(fin); + (void) gbfgetint32(fin); + + gbfread(buf, 1, 9, fin); + if (strncmp(buf, "CWayPoint", 9) != 0) { + warning(MYNAME ": Unsupported waypoint structure!\n"); + return; + } + + while (! gbfeof(fin)) { + waypoint* wpt; + + i = gbfgetc(fin); + if (i == 0) { + break; + } + + gbfungetc(i, fin); + datum = read_datum(fin); + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ + + wpt->notes = read_str(fin); + wpt->description = read_str(fin); + (void) gbfgetint16(fin); + + waypt_add(wpt); + } + return; + } + + wcount = gbfgetint32(fin); + if (wcount == 0) { + return; + } + + datum = read_datum(fin); + + while (wcount > 0) { + waypoint* wpt; + gbint32 namect, i; + + wcount--; + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + convert_datum(wpt, datum); + + namect = gbfgetint32(fin); + + // variants of shortname + + for (i = 0; i < namect; i++) { + char* name; + + name = read_str(fin); + if (name && *name) { + switch (i) { + case 0: + wpt->description = xstrdup(name); + break; + case 1: + wpt->shortname = xstrdup(name); + break; + } + } + xfree(name); + } + + waypt_add(wpt); + } } #if !ZLIB_INHIBITED static int -inflate_buff(const char *buff, const size_t size, char **out_buff) -{ - int res = Z_OK; - z_stream strm; - char out[DEFLATE_BUFF_SIZE]; - char *cout = NULL; - gbuint32 bytes = 0; - gbuint32 have; - - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = 0; - strm.next_in = Z_NULL; - - res = inflateInit(&strm); - if (res != Z_OK) { - return res; - } - - strm.avail_in = size; - strm.next_in = (void *)buff; - - do { - strm.avail_out = DEFLATE_BUFF_SIZE; - strm.next_out = (void *)out; - res = inflate(&strm, Z_NO_FLUSH); - - switch (res) { - case Z_NEED_DICT: - res = Z_DATA_ERROR; /* and fall through */ - case Z_DATA_ERROR: - case Z_MEM_ERROR: - (void)inflateEnd(&strm); - return res; - } - have = DEFLATE_BUFF_SIZE - strm.avail_out; - if (have > 0) { - cout = xrealloc(cout, bytes + have); - memcpy(cout+bytes, out, have); - bytes+=have; - } - } while (strm.avail_out == 0); - - *out_buff = cout; - return res; +inflate_buff(const char* buff, const size_t size, char** out_buff) +{ + int res = Z_OK; + z_stream strm; + char out[DEFLATE_BUFF_SIZE]; + char* cout = NULL; + gbuint32 bytes = 0; + gbuint32 have; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + + res = inflateInit(&strm); + if (res != Z_OK) { + return res; + } + + strm.avail_in = size; + strm.next_in = (Bytef*)buff; + + do { + strm.avail_out = DEFLATE_BUFF_SIZE; + strm.next_out = (Bytef*)out; + res = inflate(&strm, Z_NO_FLUSH); + + switch (res) { + case Z_NEED_DICT: + res = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return res; + } + have = DEFLATE_BUFF_SIZE - strm.avail_out; + if (have > 0) { + cout = (char*) xrealloc(cout, bytes + have); + memcpy(cout+bytes, out, have); + bytes+=have; + } + } while (strm.avail_out == 0); + + *out_buff = cout; + return res; } static void read_CXMLSafe(void) { - char *xmlstr = NULL; - - xmlbin = NULL; - xmlbinsize = 0; - - xml_init(fin->name, tlog3a_xgcb_map, NULL); - xml_read(); - xml_deinit(); - - if (xmlbin != NULL) { - inflate_buff(xmlbin, xmlbinsize, &xmlstr); - xfree(xmlbin); - - xml_init(NULL, tlog3b_xgcb_map, NULL); - xml_readstring(xmlstr); - xml_deinit(); - - xfree(xmlstr); - } + char* xmlstr = NULL; + + xmlbin = NULL; + xmlbinsize = 0; + + xml_init(fin->name, tlog3a_xgcb_map, NULL); + xml_read(); + xml_deinit(); + + if (xmlbin != NULL) { + inflate_buff(xmlbin, xmlbinsize, &xmlstr); + xfree(xmlbin); + + xml_init(NULL, tlog3b_xgcb_map, NULL); + xml_readstring(xmlstr); + xml_deinit(); + + xfree(xmlstr); + } } #endif @@ -606,11 +640,11 @@ read_CXMLSafe(void) static void read_XML(void) { - xml_init(fin->name, tlog3b_xgcb_map, NULL); - xml_read(); - xml_deinit(); - - return; + xml_init(fin->name, tlog3b_xgcb_map, NULL); + xml_read(); + xml_deinit(); + + return; } /******************************************************************************* @@ -618,178 +652,191 @@ read_XML(void) *******************************************************************************/ static void -dmtlog_rd_init(const char *fname) +dmtlog_rd_init(const char* fname) { - fin = gbfopen_le(fname, "rb", MYNAME); - - xmlbin = NULL; - xmltrk = NULL; - xmlwpt = NULL; - xmlgrid = NULL; + fin = gbfopen_le(fname, "rb", MYNAME); + + xmlbin = NULL; + xmltrk = NULL; + xmlwpt = NULL; + xmlgrid = NULL; } -static void +static void dmtlog_rd_deinit(void) { - gbfclose(fin); - if (xmlgrid != NULL) xfree(xmlgrid); + gbfclose(fin); + if (xmlgrid != NULL) { + xfree(xmlgrid); + } } static void dmtlog_read(void) { - switch(gbfgetuint32(fin)) { - - case 0x4FFFF: - read_CTrackFile(4); - break; - - case 0x8FFFF: - read_CTrackFile(8); - break; - - case 0x4d58433c: + switch (gbfgetuint32(fin)) { + + case 0x4FFFF: + read_CTrackFile(4); + break; + + case 0x8FFFF: + read_CTrackFile(8); + break; + + case 0x4d58433c: #if !ZLIB_INHIBITED - read_CXMLSafe(); + read_CXMLSafe(); #else - fatal(MYNAME ": Zlib was not included in this build.\n"); -#endif - break; - case 0x7254433c: - read_XML(); - break; + fatal(MYNAME ": Zlib was not included in this build.\n"); +#endif + break; + case 0x7254433c: + read_XML(); + break; - default: - fatal(MYNAME ": Unknown or unsupported file type.\n"); - } + default: + fatal(MYNAME ": Unknown or unsupported file type.\n"); + } } static void -dmtlog_wr_init(const char *fname) +dmtlog_wr_init(const char* fname) { - fout = gbfopen_le(fname, "wb", MYNAME); + fout = gbfopen_le(fname, "wb", MYNAME); } static void dmtlog_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void -write_header(const route_head *trk) +write_header(const route_head* trk) { - int count, i; - char *cout; - const char ZERO = '\0'; - - header_written = 1; - - count = 0; - if (trk != NULL) { - queue *curr, *prev; - QUEUE_FOR_EACH(&trk->waypoint_list, curr, prev) count++; - } - write_str(trk && trk->rte_name && *trk->rte_name ? trk->rte_name : "Name", fout); - - xasprintf(&cout, "%d trackpoints and %d waypoints", count, waypt_count()); - write_str(cout, fout); - xfree(cout); - - for (i = 3; i <= 8; i++) gbfputc(ZERO, fout); - write_str("GPSBabel", fout); - gbfputint32(count, fout); - if (count > 0) { - write_str("WGS84", fout); - write_str("WGS84", fout); - } + int count, i; + char* cout; + const char ZERO = '\0'; + + header_written = 1; + + count = 0; + if (trk != NULL) { + queue* curr, *prev; + QUEUE_FOR_EACH(&trk->waypoint_list, curr, prev) count++; + } + write_str(trk && trk->rte_name && *trk->rte_name ? trk->rte_name : "Name", fout); + + xasprintf(&cout, "%d trackpoints and %d waypoints", count, waypt_count()); + write_str(cout, fout); + xfree(cout); + + for (i = 3; i <= 8; i++) { + gbfputc(ZERO, fout); + } + write_str("GPSBabel", fout); + gbfputint32(count, fout); + if (count > 0) { + write_str("WGS84", fout); + write_str("WGS84", fout); + } } static void -track_hdr_cb(const route_head *trk) +track_hdr_cb(const route_head* trk) { - - this_index++; - if (this_index != track_index) return; - write_header(trk); + + this_index++; + if (this_index != track_index) { + return; + } + write_header(trk); } static void -track_tlr_cb(const route_head *trk) +track_tlr_cb(const route_head* trk) { } static void -track_wpt_cb(const waypoint *wpt) +track_wpt_cb(const waypoint* wpt) { - if (this_index != track_index) return; - - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); + if (this_index != track_index) { + return; + } + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); } static void -wpt_cb(const waypoint *wpt) +wpt_cb(const waypoint* wpt) { - int names; - - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); - - names = 1; - if (wpt->description && *wpt->description) names = 2; - gbfputint32(names, fout); - if (names > 1) write_str(wpt->description, fout); - write_str(wpt->shortname && *wpt->shortname ? wpt->shortname : "Name", fout); + int names; + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); + + names = 1; + if (wpt->description && *wpt->description) { + names = 2; + } + gbfputint32(names, fout); + if (names > 1) { + write_str(wpt->description, fout); + } + write_str(wpt->shortname && *wpt->shortname ? wpt->shortname : "Name", fout); } static void dmtlog_write(void) { - track_index = atoi(opt_index); - /* ... validate index */ - - gbfputint32(0x4FFFF, fout); - gbfputuint16(0x0A, fout); - gbfputs("CTrackFile", fout); - gbfputint32(4, fout); - gbfputint32(1, fout); - gbfputint32(0x100001, fout); - gbfputuint32((const gbuint32)gpsbabel_time, fout); - - header_written = 0; - this_index = 0; - track_disp_all(track_hdr_cb, track_tlr_cb, track_wpt_cb); - if (!header_written) - write_header(NULL); - gbfputint32(waypt_count(), fout); - if (waypt_count() > 0) { - write_str("WGS84", fout); - write_str("WGS84", fout); - waypt_disp_all(wpt_cb); - } + track_index = atoi(opt_index); + /* ... validate index */ + + gbfputint32(0x4FFFF, fout); + gbfputuint16(0x0A, fout); + gbfputs("CTrackFile", fout); + gbfputint32(4, fout); + gbfputint32(1, fout); + gbfputint32(0x100001, fout); + gbfputuint32((const gbuint32)gpsbabel_time, fout); + + header_written = 0; + this_index = 0; + track_disp_all(track_hdr_cb, track_tlr_cb, track_wpt_cb); + if (!header_written) { + write_header(NULL); + } + gbfputint32(waypt_count(), fout); + if (waypt_count() > 0) { + write_str("WGS84", fout); + write_str("WGS84", fout); + waypt_disp_all(wpt_cb); + } } /**************************************************************************/ ff_vecs_t dmtlog_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - dmtlog_rd_init, - dmtlog_wr_init, - dmtlog_rd_deinit, - dmtlog_wr_deinit, - dmtlog_read, - dmtlog_write, - NULL, - dmtlog_args, - CET_CHARSET_ASCII, 0 + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + dmtlog_rd_init, + dmtlog_wr_init, + dmtlog_rd_deinit, + dmtlog_wr_deinit, + dmtlog_read, + dmtlog_write, + NULL, + dmtlog_args, + CET_CHARSET_ASCII, 0 }; diff --git a/gpsbabel/duplicate.c b/gpsbabel/duplicate.c index 1043faf5d..bca2779ad 100644 --- a/gpsbabel/duplicate.c +++ b/gpsbabel/duplicate.c @@ -23,85 +23,96 @@ #include "filterdefs.h" #if FILTERS_ENABLED -static char *snopt = NULL; -static char *lcopt = NULL; -static char *purge_duplicates = NULL; -static char *correct_coords = NULL; +static char* snopt = NULL; +static char* lcopt = NULL; +static char* purge_duplicates = NULL; +static char* correct_coords = NULL; static arglist_t dup_args[] = { - {"shortname", &snopt, "Suppress duplicate waypoints based on name", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, - {"location", &lcopt, "Suppress duplicate waypoint based on coords", - NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, - {"all", &purge_duplicates, "Suppress all instances of duplicates", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"correct", &correct_coords, "Use coords from duplicate points", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "shortname", &snopt, "Suppress duplicate waypoints based on name", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "location", &lcopt, "Suppress duplicate waypoint based on coords", + NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "all", &purge_duplicates, "Suppress all instances of duplicates", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "correct", &correct_coords, "Use coords from duplicate points", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; typedef struct btree_node { - struct btree_node *left, *right; - unsigned long data; - waypoint *wpt; + struct btree_node* left, *right; + unsigned long data; + waypoint* wpt; } btree_node; -static btree_node * -addnode (btree_node * tree, btree_node * newnode, btree_node **oldnode) +static btree_node* +addnode(btree_node* tree, btree_node* newnode, btree_node** oldnode) { - btree_node * tmp, * last = NULL; - - if ( *oldnode ) {*oldnode = NULL;} - - if (!tree) - return (newnode); - - tmp = tree; - - while (tmp) { - last = tmp; - if (newnode->data < tmp->data) { - tmp = tmp->right; - } else if (newnode->data > tmp->data) { - tmp = tmp->left; - } else { - if ( oldnode ) { - *oldnode = tmp; - } - return (NULL); - } - } - - if (newnode->data < last->data) { - last->right = newnode; - } else { - last->left = newnode; - } - - return (tree); + btree_node* tmp, * last = NULL; + + if (*oldnode) { + *oldnode = NULL; + } + + if (!tree) { + return (newnode); + } + + tmp = tree; + + while (tmp) { + last = tmp; + if (newnode->data < tmp->data) { + tmp = tmp->right; + } else if (newnode->data > tmp->data) { + tmp = tmp->left; + } else { + if (oldnode) { + *oldnode = tmp; + } + return (NULL); + } + } + + if (newnode->data < last->data) { + last->right = newnode; + } else { + last->left = newnode; + } + + return (tree); } void -free_tree (btree_node *tree) +free_tree(btree_node* tree) { - if ( tree->left ) { - free_tree(tree->left); - } - if ( tree->right ) { - free_tree(tree->right); - } - xfree(tree); + if (tree->left) { + free_tree(tree->left); + } + if (tree->right) { + free_tree(tree->right); + } + xfree(tree); } typedef struct { - waypoint *wpt; - int index; + waypoint* wpt; + int index; } wpt_ptr; /* - + It looks odd that we have different comparisons for date and index. If exported if a < b return 1 if index if a < b return -1 @@ -136,26 +147,26 @@ because, sadly, quicksort can be O(n^2) on presorted elements.) static int -compare(const void *a, const void *b) +compare(const void* a, const void* b) { - const wpt_ptr *wa = (wpt_ptr *)a; - const wpt_ptr *wb = (wpt_ptr *)b; + const wpt_ptr* wa = (wpt_ptr*)a; + const wpt_ptr* wb = (wpt_ptr*)b; - if ( wa->wpt->gc_data->exported < wb->wpt->gc_data->exported ) { - return 1; - } else if ( wa->wpt->gc_data->exported > wb->wpt->gc_data->exported ) { - return -1; - } + if (wa->wpt->gc_data->exported < wb->wpt->gc_data->exported) { + return 1; + } else if (wa->wpt->gc_data->exported > wb->wpt->gc_data->exported) { + return -1; + } - /* If the exported dates are the same, sort by index. */ - if ( wa->index < wb->index ) { - return -1; - } else if (wa->index > wb->index ) { - return 1; - } + /* If the exported dates are the same, sort by index. */ + if (wa->index < wb->index) { + return -1; + } else if (wa->index > wb->index) { + return 1; + } - /* If index and date are the same, it's the same element. */ - return 0; + /* If index and date are the same, it's the same element. */ + return 0; } @@ -163,98 +174,102 @@ compare(const void *a, const void *b) static void duplicate_process(void) { - waypoint * waypointp; - btree_node * newnode, * btmp, * sup_tree = NULL; - btree_node * oldnode = NULL; - unsigned long crc = 0; - struct { char shortname[32]; char lat[13]; char lon[13]; } dupe; - waypoint * delwpt = NULL; - - int i, ct = waypt_count(); - wpt_ptr *htable, *bh; - queue *elem, *tmp; - - htable = (wpt_ptr *) xmalloc(ct * sizeof(*htable)); - bh = htable; - - i = 0; - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - bh->wpt = (waypoint *) elem; - bh->index = i; - i ++; - bh ++; - } - qsort(htable, ct, sizeof(*htable), compare); - - for (i=0;ishortname, sizeof(dupe.shortname) - 1); - } - - if (lcopt) { - /* let sprintf take care of rounding */ - sprintf(dupe.lat, "%11.4f", waypointp->latitude); - sprintf(dupe.lon, "%11.4f", waypointp->longitude); - /* The degrees2ddmm stuff is a feeble attempt to - * get everything rounded the same way in a precision - * that's "close enough" for determining duplicates. - */ - sprintf(dupe.lat, "%11.3f", degrees2ddmm(waypointp->latitude)); - sprintf(dupe.lon, "%11.3f", degrees2ddmm(waypointp->longitude)); - - } - - crc = get_crc32(&dupe, sizeof(dupe)); - - newnode = (btree_node *)xcalloc(sizeof(btree_node), 1); - newnode->data = crc; - newnode->wpt = waypointp; - - btmp = addnode(sup_tree, newnode, &oldnode ); - - if (btmp == NULL) { - if ( delwpt ) { - waypt_free(delwpt); - } - if ( correct_coords && oldnode && oldnode->wpt ) { - oldnode->wpt->latitude = waypointp->latitude; - oldnode->wpt->longitude = waypointp->longitude; - } - delwpt = waypointp; - waypt_del(waypointp); /* collision */ - xfree(newnode); - if ( purge_duplicates && oldnode ) { - if ( oldnode->wpt ) { - waypt_del( oldnode->wpt ); - waypt_free( oldnode->wpt ); - oldnode->wpt = NULL; - } - } - - } else { - sup_tree = btmp; - } - } - - if ( delwpt ) { - waypt_free(delwpt); - } - - xfree(htable); - if ( sup_tree ) { - free_tree(sup_tree); - } + waypoint* waypointp; + btree_node* newnode, * btmp, * sup_tree = NULL; + btree_node* oldnode = NULL; + unsigned long crc = 0; + struct { + char shortname[32]; + char lat[13]; + char lon[13]; + } dupe; + waypoint* delwpt = NULL; + + int i, ct = waypt_count(); + wpt_ptr* htable, *bh; + queue* elem, *tmp; + + htable = (wpt_ptr*) xmalloc(ct * sizeof(*htable)); + bh = htable; + + i = 0; + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + bh->wpt = (waypoint*) elem; + bh->index = i; + i ++; + bh ++; + } + qsort(htable, ct, sizeof(*htable), compare); + + for (i=0; ishortname, sizeof(dupe.shortname) - 1); + } + + if (lcopt) { + /* let sprintf take care of rounding */ + sprintf(dupe.lat, "%11.4f", waypointp->latitude); + sprintf(dupe.lon, "%11.4f", waypointp->longitude); + /* The degrees2ddmm stuff is a feeble attempt to + * get everything rounded the same way in a precision + * that's "close enough" for determining duplicates. + */ + sprintf(dupe.lat, "%11.3f", degrees2ddmm(waypointp->latitude)); + sprintf(dupe.lon, "%11.3f", degrees2ddmm(waypointp->longitude)); + + } + + crc = get_crc32(&dupe, sizeof(dupe)); + + newnode = (btree_node*)xcalloc(sizeof(btree_node), 1); + newnode->data = crc; + newnode->wpt = waypointp; + + btmp = addnode(sup_tree, newnode, &oldnode); + + if (btmp == NULL) { + if (delwpt) { + waypt_free(delwpt); + } + if (correct_coords && oldnode && oldnode->wpt) { + oldnode->wpt->latitude = waypointp->latitude; + oldnode->wpt->longitude = waypointp->longitude; + } + delwpt = waypointp; + waypt_del(waypointp); /* collision */ + xfree(newnode); + if (purge_duplicates && oldnode) { + if (oldnode->wpt) { + waypt_del(oldnode->wpt); + waypt_free(oldnode->wpt); + oldnode->wpt = NULL; + } + } + + } else { + sup_tree = btmp; + } + } + + if (delwpt) { + waypt_free(delwpt); + } + + xfree(htable); + if (sup_tree) { + free_tree(sup_tree); + } } filter_vecs_t duplicate_vecs = { - NULL, - duplicate_process, - NULL, - NULL, - dup_args + NULL, + duplicate_process, + NULL, + NULL, + dup_args }; #endif diff --git a/gpsbabel/easygps.c b/gpsbabel/easygps.c index 2bc95850b..1cdc3820e 100644 --- a/gpsbabel/easygps.c +++ b/gpsbabel/easygps.c @@ -22,8 +22,8 @@ #include "defs.h" #include -static gbfile *file_in; -static gbfile *file_out; +static gbfile* file_in; +static gbfile* file_out; static short_handle mkshort_handle; /* static char *deficon = NULL; */ @@ -31,185 +31,185 @@ static short_handle mkshort_handle; static arglist_t easygps_args[] = { -/* {"deficon", &deficon, "Default icon name", "Waypoint", - ARGTYPE_STRING}, */ - ARG_TERMINATOR + /* {"deficon", &deficon, "Default icon name", "Waypoint", + ARGTYPE_STRING}, */ + ARG_TERMINATOR }; static void -rd_init(const char *fname) +rd_init(const char* fname) { - int sz; - char ibuf[100] = {'0'} ; - const char *ezsig = "TerraByte Location File"; - - file_in = gbfopen_le(fname, "rb", MYNAME); - - sz = gbfread(ibuf, 1, 52, file_in); - - if ((sz < 52) || - strncmp(ibuf, ezsig, sizeof(ezsig)-1) || - (ibuf[51] != 'W')) { - fatal(MYNAME ": %s is not an EasyGPS file.\n", fname); - } + int sz; + char ibuf[100] = {'0'} ; + const char* ezsig = "TerraByte Location File"; + + file_in = gbfopen_le(fname, "rb", MYNAME); + + sz = gbfread(ibuf, 1, 52, file_in); + + if ((sz < 52) || + strncmp(ibuf, ezsig, sizeof(ezsig)-1) || + (ibuf[51] != 'W')) { + fatal(MYNAME ": %s is not an EasyGPS file.\n", fname); + } } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void data_read(void) { - char p; - char ibuf[10]; - do { - unsigned char tag; - waypoint *wpt_tmp; - - wpt_tmp = waypt_new(); - - for (tag = gbfgetc(file_in); tag != 0xff; tag = gbfgetc(file_in)) { - switch (tag) { - case 1: - wpt_tmp->shortname = gbfgetpstr(file_in); - break; - case 2: - case 3: - wpt_tmp->description = gbfgetpstr(file_in);; - break; - case 5: - wpt_tmp->notes = gbfgetpstr(file_in);; - break; - case 6: - wpt_tmp->url_link_text = gbfgetpstr(file_in);; - break; - case 7: - wpt_tmp->icon_descr = gbfgetpstr(file_in);; - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - break; - case 8: /* NULL Terminated (vs. pascal) descr */ - wpt_tmp->notes = gbfgetcstr(file_in); - break; - case 9: /* NULL Terminated (vs. pascal) link */ - wpt_tmp->url = gbfgetcstr(file_in); - break; - case 0x10: - wpt_tmp->url_link_text = gbfgetcstr(file_in); - break; - case 0x63: - wpt_tmp->latitude = gbfgetdbl(file_in); - break; - case 0x64: - wpt_tmp->longitude = gbfgetdbl(file_in); - break; - case 0x65: - case 0x66: - gbfread(ibuf, 8, 1, file_in); - break; - case 0x84: - case 0x85: - gbfread(ibuf, 4, 1, file_in); - break; - case 0x86: /* May be proximity. I think it's time. */ - gbfread(ibuf, 4, 1, file_in); - break; - default: - printf("Unknown tag %x\n", tag); - ; - } - } - waypt_add(wpt_tmp); - p = gbfgetc(file_in); - } while (!gbfeof(file_in) && (p == 'W')); + char p; + char ibuf[10]; + do { + unsigned char tag; + waypoint* wpt_tmp; + + wpt_tmp = waypt_new(); + + for (tag = gbfgetc(file_in); tag != 0xff; tag = gbfgetc(file_in)) { + switch (tag) { + case 1: + wpt_tmp->shortname = gbfgetpstr(file_in); + break; + case 2: + case 3: + wpt_tmp->description = gbfgetpstr(file_in);; + break; + case 5: + wpt_tmp->notes = gbfgetpstr(file_in);; + break; + case 6: + wpt_tmp->url_link_text = gbfgetpstr(file_in);; + break; + case 7: + wpt_tmp->icon_descr = gbfgetpstr(file_in);; + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 8: /* NULL Terminated (vs. pascal) descr */ + wpt_tmp->notes = gbfgetcstr(file_in); + break; + case 9: /* NULL Terminated (vs. pascal) link */ + wpt_tmp->url = gbfgetcstr(file_in); + break; + case 0x10: + wpt_tmp->url_link_text = gbfgetcstr(file_in); + break; + case 0x63: + wpt_tmp->latitude = gbfgetdbl(file_in); + break; + case 0x64: + wpt_tmp->longitude = gbfgetdbl(file_in); + break; + case 0x65: + case 0x66: + gbfread(ibuf, 8, 1, file_in); + break; + case 0x84: + case 0x85: + gbfread(ibuf, 4, 1, file_in); + break; + case 0x86: /* May be proximity. I think it's time. */ + gbfread(ibuf, 4, 1, file_in); + break; + default: + printf("Unknown tag %x\n", tag); + ; + } + } + waypt_add(wpt_tmp); + p = gbfgetc(file_in); + } while (!gbfeof(file_in) && (p == 'W')); } static void -ez_disp(const waypoint *wpt) +ez_disp(const waypoint* wpt) { - gbfputc('W', file_out); - - if (wpt->shortname) { - gbfputc(1, file_out); - gbfputpstr(wpt->shortname, file_out); - } - if (wpt->description) { - gbfputc(3, file_out); - gbfputpstr(wpt->description, file_out); - } - if (wpt->icon_descr) { - gbfputc(7, file_out); - gbfputpstr(wpt->icon_descr, file_out); - } - gbfputc(0x63, file_out); - gbfputdbl(wpt->latitude, file_out); - - gbfputc(0x64, file_out); - gbfputdbl(wpt->longitude, file_out); - - if (wpt->notes) { - gbfputc(5, file_out); - gbfputpstr(wpt->notes, file_out); - } - if (wpt->url_link_text) { - gbfputc(6, file_out); - gbfputpstr(wpt->url_link_text, file_out); - } - if (1 && wpt->url) { - gbfputc(9, file_out); - gbfputcstr(wpt->url, file_out); - } - gbfputc(0xff, file_out); + gbfputc('W', file_out); + + if (wpt->shortname) { + gbfputc(1, file_out); + gbfputpstr(wpt->shortname, file_out); + } + if (wpt->description) { + gbfputc(3, file_out); + gbfputpstr(wpt->description, file_out); + } + if (wpt->icon_descr) { + gbfputc(7, file_out); + gbfputpstr(wpt->icon_descr, file_out); + } + gbfputc(0x63, file_out); + gbfputdbl(wpt->latitude, file_out); + + gbfputc(0x64, file_out); + gbfputdbl(wpt->longitude, file_out); + + if (wpt->notes) { + gbfputc(5, file_out); + gbfputpstr(wpt->notes, file_out); + } + if (wpt->url_link_text) { + gbfputc(6, file_out); + gbfputpstr(wpt->url_link_text, file_out); + } + if (1 && wpt->url) { + gbfputc(9, file_out); + gbfputcstr(wpt->url, file_out); + } + gbfputc(0xff, file_out); } static void data_write(void) { - setshort_length(mkshort_handle, 6); + setshort_length(mkshort_handle, 6); - gbfprintf(file_out, - "TerraByte Location File Copyright 2001 TopoGrafix\n"); - /* - * I don't know what this is. - */ - gbfprintf(file_out, "%c", 0xb); + gbfprintf(file_out, + "TerraByte Location File Copyright 2001 TopoGrafix\n"); + /* + * I don't know what this is. + */ + gbfprintf(file_out, "%c", 0xb); - waypt_disp_all(ez_disp); + waypt_disp_all(ez_disp); - /* - * Files seem to always end in a zero. - */ - gbfputc(0x00, file_out); + /* + * Files seem to always end in a zero. + */ + gbfputc(0x00, file_out); } ff_vecs_t easygps_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - easygps_args, - CET_CHARSET_ASCII, 0 /* CET REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + easygps_args, + CET_CHARSET_ASCII, 0 /* CET REVIEW */ }; diff --git a/gpsbabel/enigma.c b/gpsbabel/enigma.c index fd006715f..2d6c8d748 100755 --- a/gpsbabel/enigma.c +++ b/gpsbabel/enigma.c @@ -54,106 +54,105 @@ #define WTYPE_ALTITUDECHANGE 26 // Location at which altitude should be changed union wpt_data { - gbint32 wp_altitude; // Waypoint type 0-6,8: waypoint altitude in feet - gbint32 tg_altitude; // Waypoint type 26: target altitude in feet - gbuint32 frequency; // Waypoint type 9-25: freq in steps of 1000Hz (118Mhz = 180000) - gbint32 dummy; // waypoint type 7, unused + gbint32 wp_altitude; // Waypoint type 0-6,8: waypoint altitude in feet + gbint32 tg_altitude; // Waypoint type 26: target altitude in feet + gbuint32 frequency; // Waypoint type 9-25: freq in steps of 1000Hz (118Mhz = 180000) + gbint32 dummy; // waypoint type 7, unused }; typedef struct enigma_wpt { - gbint32 latitude; - gbint32 longitude; - union wpt_data data; - gbuint8 waypoint_type; - gbuint8 shortname_len; - char shortname[6]; - gbuint8 longname_len; - char longname[27]; + gbint32 latitude; + gbint32 longitude; + union wpt_data data; + gbuint8 waypoint_type; + gbuint8 shortname_len; + char shortname[6]; + gbuint8 longname_len; + char longname[27]; } ENIGMA_WPT; -static gbfile *file_in, *file_out; +static gbfile* file_in, *file_out; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } -gbint32 decToEnigmaPosition (double val) +gbint32 decToEnigmaPosition(double val) { - int degrees = fabs(val); - double frac = fabs(val) - degrees; - int enigmadeg = degrees * 180000; - int enigmafrac = 180000 * frac; - int sign = (val < 0) ? -1 : +1; - return sign * (enigmadeg + enigmafrac); + int degrees = fabs(val); + double frac = fabs(val) - degrees; + int enigmadeg = degrees * 180000; + int enigmafrac = 180000 * frac; + int sign = (val < 0) ? -1 : +1; + return sign * (enigmadeg + enigmafrac); } -float enigmaPositionToDec (gbint32 val) +float enigmaPositionToDec(gbint32 val) { - int deg = abs(val) / 180000; - int enigmafrac = abs(val) % 180000; - double frac = (double)enigmafrac / 180000; - int sign = (val < 0) ? -1 : +1; - return sign * (deg + frac); + int deg = abs(val) / 180000; + int enigmafrac = abs(val) % 180000; + double frac = (double)enigmafrac / 180000; + int sign = (val < 0) ? -1 : +1; + return sign * (deg + frac); } static void data_read(void) { - struct enigma_wpt ewpt; - route_head *route = route_head_alloc(); - route_add_head (route); - - while (1 == gbfread(&ewpt, sizeof (ewpt), 1, file_in)) { - waypoint *wpt = waypt_new(); - wpt->latitude = enigmaPositionToDec(le_read32(&ewpt.latitude)); - wpt->longitude = enigmaPositionToDec(le_read32(&ewpt.longitude)); - wpt->shortname = xstrndup(ewpt.shortname, ewpt.shortname_len); - wpt->description = xstrndup(ewpt.longname, ewpt.longname_len); - switch (ewpt.waypoint_type) - { - case WTYPE_WAYPOINT: // 0 - case WTYPE_AIRPORT: // 1 - case WTYPE_MAJORAIRPORT: // 2 - case WTYPE_SEAPLANEBASE: // 3 - case WTYPE_AIRFIELD: // 4 - case WTYPE_PRIVATEAIRFIELD: // 5 - case WTYPE_ULTRALIGHTFIELD: // 6 - case WTYPE_HELIPORT: // 8 - // waypoint altitude - wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.wp_altitude) - 1000); - break; - case WTYPE_ALTITUDECHANGE: // 26 - // target altitude - wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.tg_altitude) - 1000); - break; - case WTYPE_INTERSECTION: // 7 - // unused - break; - default: - // frequency - // wpt->frequency = wpt.le_readu32(ewpt.data.frequency); - ; - } - route_add_wpt(route, wpt); - } + struct enigma_wpt ewpt; + route_head* route = route_head_alloc(); + route_add_head(route); + + while (1 == gbfread(&ewpt, sizeof(ewpt), 1, file_in)) { + waypoint* wpt = waypt_new(); + wpt->latitude = enigmaPositionToDec(le_read32(&ewpt.latitude)); + wpt->longitude = enigmaPositionToDec(le_read32(&ewpt.longitude)); + wpt->shortname = xstrndup(ewpt.shortname, ewpt.shortname_len); + wpt->description = xstrndup(ewpt.longname, ewpt.longname_len); + switch (ewpt.waypoint_type) { + case WTYPE_WAYPOINT: // 0 + case WTYPE_AIRPORT: // 1 + case WTYPE_MAJORAIRPORT: // 2 + case WTYPE_SEAPLANEBASE: // 3 + case WTYPE_AIRFIELD: // 4 + case WTYPE_PRIVATEAIRFIELD: // 5 + case WTYPE_ULTRALIGHTFIELD: // 6 + case WTYPE_HELIPORT: // 8 + // waypoint altitude + wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.wp_altitude) - 1000); + break; + case WTYPE_ALTITUDECHANGE: // 26 + // target altitude + wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.tg_altitude) - 1000); + break; + case WTYPE_INTERSECTION: // 7 + // unused + break; + default: + // frequency + // wpt->frequency = wpt.le_readu32(ewpt.data.frequency); + ; + } + route_add_wpt(route, wpt); + } } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); } static void -route_head_noop(const route_head *wp) +route_head_noop(const route_head* wp) { } @@ -165,56 +164,55 @@ route_head_noop(const route_head *wp) #endif static void -enigma_waypt_disp(const waypoint *wpt) +enigma_waypt_disp(const waypoint* wpt) { - struct enigma_wpt ewpt; - - memset (&ewpt, 0, sizeof (ewpt)); - - le_write32(&ewpt.latitude, decToEnigmaPosition(wpt->latitude)); - le_write32(&ewpt.longitude, decToEnigmaPosition(wpt->longitude)); - ewpt.waypoint_type = WTYPE_WAYPOINT; - if (wpt->altitude != unknown_alt) - le_write32(&ewpt.data.wp_altitude, METERS_TO_FEET(wpt->altitude) + 1000); - if (wpt->shortname != NULL) - { - ewpt.shortname_len = min (6, strlen (wpt->shortname)); - strncpy(ewpt.shortname, wpt->shortname, 6); - } - if (wpt->description != NULL) - { - ewpt.longname_len = min (27, strlen (wpt->description)); - strncpy(ewpt.longname, wpt->description, 27); - } - gbfwrite(&ewpt, sizeof (ewpt), 1, file_out); + struct enigma_wpt ewpt; + + memset(&ewpt, 0, sizeof(ewpt)); + + le_write32(&ewpt.latitude, decToEnigmaPosition(wpt->latitude)); + le_write32(&ewpt.longitude, decToEnigmaPosition(wpt->longitude)); + ewpt.waypoint_type = WTYPE_WAYPOINT; + if (wpt->altitude != unknown_alt) { + le_write32(&ewpt.data.wp_altitude, METERS_TO_FEET(wpt->altitude) + 1000); + } + if (wpt->shortname != NULL) { + ewpt.shortname_len = min(6, strlen(wpt->shortname)); + strncpy(ewpt.shortname, wpt->shortname, 6); + } + if (wpt->description != NULL) { + ewpt.longname_len = min(27, strlen(wpt->description)); + strncpy(ewpt.longname, wpt->description, 27); + } + gbfwrite(&ewpt, sizeof(ewpt), 1, file_out); } static void data_write(void) { - route_disp_all(route_head_noop, route_head_noop, enigma_waypt_disp); + route_disp_all(route_head_noop, route_head_noop, enigma_waypt_disp); } static void wr_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } ff_vecs_t enigma_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write, /* waypoints */ - ff_cap_none, /* tracks */ - ff_cap_read | ff_cap_write /* routes */ - }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write), /* waypoints */ + ff_cap_none, /* tracks */ + (ff_cap)(ff_cap_read | ff_cap_write) /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/exif.c b/gpsbabel/exif.c index 29d0004c2..2876d4c4d 100644 --- a/gpsbabel/exif.c +++ b/gpsbabel/exif.c @@ -93,1070 +93,1231 @@ #define GPS_IFD_TAG_DATESTAMP 0x001D typedef struct exif_tag_s { - queue Q; - gbuint16 id; - gbuint16 type; - gbuint32 count; - gbuint32 value; - gbuint32 origin; - gbuint32 size; + queue Q; + gbuint16 id; + gbuint16 type; + gbuint32 count; + gbuint32 value; + gbuint32 origin; + gbuint32 size; #ifdef EXIF_DBG - gbuint32 offs; + gbuint32 offs; #endif - unsigned char data_is_dynamic:1; - void *data; + unsigned char data_is_dynamic:1; + void* data; } exif_tag_t; typedef struct exif_ifd_s { - queue Q; - gbuint32 next_ifd; - gbuint16 nr; - gbuint16 count; - queue tags; + queue Q; + gbuint32 next_ifd; + gbuint16 nr; + gbuint16 count; + queue tags; } exif_ifd_t, *exif_ifd_p; typedef struct exif_app_s { - queue Q; - gbuint16 marker; - gbsize_t len; - gbfile *fcache; - gbfile *fexif; - queue ifds; + queue Q; + gbuint16 marker; + gbsize_t len; + gbfile* fcache; + gbfile* fexif; + queue ifds; } exif_app_t; -static gbfile *fin, *fout; +static gbfile* fin, *fout; static queue exif_apps; -static exif_app_t *exif_app; -const waypoint *exif_wpt_ref; +static exif_app_t* exif_app; +const waypoint* exif_wpt_ref; time_t exif_time_ref; static char exif_success; -static char *exif_fout_name; +static char* exif_fout_name; -static char *opt_filename, *opt_overwrite, *opt_frame, *opt_name; +static char* opt_filename, *opt_overwrite, *opt_frame, *opt_name; arglist_t exif_args[] = { - { "filename", &opt_filename, "Set waypoint name to source filename", "Y", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "frame", &opt_frame, "Time-frame (in seconds)", "10", ARGTYPE_INT, "0", NULL }, - { "name", &opt_name, "Locate waypoint for tagging by this name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "overwrite", &opt_overwrite, "!OVERWRITE! the original file. Default=N", "N", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { "filename", &opt_filename, "Set waypoint name to source filename", "Y", ARGTYPE_BOOL, ARG_NOMINMAX }, + { "frame", &opt_frame, "Time-frame (in seconds)", "10", ARGTYPE_INT, "0", NULL }, + { "name", &opt_name, "Locate waypoint for tagging by this name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "overwrite", &opt_overwrite, "!OVERWRITE! the original file. Default=N", "N", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #ifdef EXIF_DBG static void -print_buff(const char *buf, int sz, const char *cmt) +print_buff(const char* buf, int sz, const char* cmt) { - int i; - - printf("%s: ", cmt); - for (i = 0; i < sz; i++) - printf("%02x ", buf[i] & 0xFF); - for (i = 0; i < sz; i++) { - char c = buf[i]; - if (isspace(c)) c = ' '; - else if (! isprint(c)) c = '.'; - printf("%c", c); - } + int i; + + printf("%s: ", cmt); + for (i = 0; i < sz; i++) { + printf("%02x ", buf[i] & 0xFF); + } + for (i = 0; i < sz; i++) { + char c = buf[i]; + if (isspace(c)) { + c = ' '; + } else if (! isprint(c)) { + c = '.'; + } + printf("%c", c); + } } #endif static gbuint16 exif_type_size(const gbuint16 type) { - gbuint16 size; - - switch(type) { - case EXIF_TYPE_BYTE: - case EXIF_TYPE_ASCII: - case EXIF_TYPE_UNK: size = 1; break; - - case EXIF_TYPE_SHORT: - case EXIF_TYPE_SSHORT: - case EXIF_TYPE_UNICODE: size = 2; break; - case EXIF_TYPE_IFD: - case EXIF_TYPE_LONG: - case EXIF_TYPE_SLONG: - case EXIF_TYPE_FLOAT: size = 4; break; - - case EXIF_TYPE_RAT: - case EXIF_TYPE_SRAT: - case EXIF_TYPE_DOUBLE: - case EXIF_TYPE_LONG8: - case EXIF_TYPE_SLONG8: - case EXIF_TYPE_IFD8: size = 8; break; - - default: - fatal(MYNAME ": Unknown data type %d! Please report.\n", type); - } - return size; + gbuint16 size; + + switch (type) { + case EXIF_TYPE_BYTE: + case EXIF_TYPE_ASCII: + case EXIF_TYPE_UNK: + size = 1; + break; + + case EXIF_TYPE_SHORT: + case EXIF_TYPE_SSHORT: + case EXIF_TYPE_UNICODE: + size = 2; + break; + case EXIF_TYPE_IFD: + case EXIF_TYPE_LONG: + case EXIF_TYPE_SLONG: + case EXIF_TYPE_FLOAT: + size = 4; + break; + + case EXIF_TYPE_RAT: + case EXIF_TYPE_SRAT: + case EXIF_TYPE_DOUBLE: + case EXIF_TYPE_LONG8: + case EXIF_TYPE_SLONG8: + case EXIF_TYPE_IFD8: + size = 8; + break; + + default: + fatal(MYNAME ": Unknown data type %d! Please report.\n", type); + } + return size; } -static char * +static char* exif_time_str(const time_t time) { - struct tm tm; - char *res; + struct tm tm; + char* res; - tm = *localtime(&time); - tm.tm_year += 1900; - tm.tm_mon += 1; - xasprintf(&res, "%04d/%02d/%02d, %02d:%02d:%02d", - tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + tm = *localtime(&time); + tm.tm_year += 1900; + tm.tm_mon += 1; + xasprintf(&res, "%04d/%02d/%02d, %02d:%02d:%02d", + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - return res; + return res; } -static char * -exif_read_str(exif_tag_t *tag) +static char* +exif_read_str(exif_tag_t* tag) { - // Panasonic DMC-TZ10 stores datum with trailing spaces. - char *buf = xstrndup((char *)tag->data, tag->size); - rtrim (buf); - return buf; + // Panasonic DMC-TZ10 stores datum with trailing spaces. + char* buf = xstrndup((char*)tag->data, tag->size); + rtrim(buf); + return buf; } static double -exif_read_double(const exif_tag_t *tag, const int index) +exif_read_double(const exif_tag_t* tag, const int index) { - unsigned int num, den; - gbint32 *data = (void *)tag->data; + unsigned int num, den; + gbint32* data = (gbint32*)tag->data; - num = data[index * 2]; - den = data[(index * 2) + 1]; - if (den == 0) den = 1; + num = data[index * 2]; + den = data[(index * 2) + 1]; + if (den == 0) { + den = 1; + } - return (double)num / (double)den; + return (double)num / (double)den; } static double -exif_read_coord(const exif_tag_t *tag) +exif_read_coord(const exif_tag_t* tag) { - double res, min, sec; + double res, min, sec; - res = exif_read_double(tag, 0); - if (tag->count == 1) return res; + res = exif_read_double(tag, 0); + if (tag->count == 1) { + return res; + } - min = exif_read_double(tag, 1); - res += (min / 60); - if (tag->count == 2) return res; + min = exif_read_double(tag, 1); + res += (min / 60); + if (tag->count == 2) { + return res; + } - sec = exif_read_double(tag, 2); - res += (sec / 3600); + sec = exif_read_double(tag, 2); + res += (sec / 3600); - return res; + return res; } static time_t -exif_read_timestamp(const exif_tag_t *tag) +exif_read_timestamp(const exif_tag_t* tag) { - double hour, min, sec; + double hour, min, sec; - hour = exif_read_double(tag, 0); - min = exif_read_double(tag, 1); - sec = exif_read_double(tag, 2); + hour = exif_read_double(tag, 0); + min = exif_read_double(tag, 1); + sec = exif_read_double(tag, 2); - return ((int)hour * SECONDS_PER_HOUR) + ((int)min * 60) + (int)sec; + return ((int)hour * SECONDS_PER_HOUR) + ((int)min * 60) + (int)sec; } static time_t -exif_read_datestamp(const exif_tag_t *tag) +exif_read_datestamp(const exif_tag_t* tag) { - struct tm tm; - char *str; + struct tm tm; + char* str; - memset(&tm, 0, sizeof(tm)); - str = xstrndup((char *)tag->data, tag->size); - sscanf(str, "%d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday); - xfree(str); + memset(&tm, 0, sizeof(tm)); + str = xstrndup((char*)tag->data, tag->size); + sscanf(str, "%d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday); + xfree(str); - tm.tm_year -= 1900; - tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_mon -= 1; - return mkgmtime(&tm); + return mkgmtime(&tm); } static void -exif_release_tag(exif_tag_t *tag) +exif_release_tag(exif_tag_t* tag) { - dequeue(&tag->Q); - if (tag->data_is_dynamic) xfree(tag->data); - xfree(tag); + dequeue(&tag->Q); + if (tag->data_is_dynamic) { + xfree(tag->data); + } + xfree(tag); } static void -exif_release_ifd(exif_ifd_t *ifd) +exif_release_ifd(exif_ifd_t* ifd) { - if (ifd != NULL) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_release_tag((exif_tag_t *)elem); - } - xfree(ifd); - } + if (ifd != NULL) { + queue* elem, *tmp; + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_release_tag((exif_tag_t*)elem); + } + xfree(ifd); + } } static void exif_release_apps(void) { - queue *e0, *t0; - - QUEUE_FOR_EACH(&exif_apps, e0, t0) { - queue *e1, *t1; - exif_app_t *app = (exif_app_t *)dequeue(e0); - - if (app->fcache) gbfclose(app->fcache); - if (app->fexif) gbfclose(app->fexif); - QUEUE_FOR_EACH(&app->ifds, e1, t1) { - exif_ifd_t *ifd = (exif_ifd_t *)dequeue(e1); - exif_release_ifd(ifd); - } - xfree(app); - } + queue* e0, *t0; + + QUEUE_FOR_EACH(&exif_apps, e0, t0) { + queue* e1, *t1; + exif_app_t* app = (exif_app_t*)dequeue(e0); + + if (app->fcache) { + gbfclose(app->fcache); + } + if (app->fexif) { + gbfclose(app->fexif); + } + QUEUE_FOR_EACH(&app->ifds, e1, t1) { + exif_ifd_t* ifd = (exif_ifd_t*)dequeue(e1); + exif_release_ifd(ifd); + } + xfree(app); + } } static gbuint32 -exif_ifd_size(exif_ifd_t *ifd) +exif_ifd_size(exif_ifd_t* ifd) { - queue *elem, *tmp; - gbuint32 res = 6; /* nr of tags + next_ifd */ - - res += (ifd->count * 12); - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - if (tag->size > 4) { - gbuint32 size = tag->size; - if (size & 1) size++; - res += size; - } - } - - return res; + queue* elem, *tmp; + gbuint32 res = 6; /* nr of tags + next_ifd */ + + res += (ifd->count * 12); + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t* tag = (exif_tag_t*)elem; + if (tag->size > 4) { + gbuint32 size = tag->size; + if (size & 1) { + size++; + } + res += size; + } + } + + return res; } -static exif_app_t * +static exif_app_t* exif_load_apps(void) { - exif_app_t *exif_app = NULL; + exif_app_t* exif_app = NULL; - while (! gbfeof(fin)) { - exif_app_t *app = xcalloc(sizeof(*app), 1); + while (! gbfeof(fin)) { + exif_app_t* app = (exif_app_t*) xcalloc(sizeof(*app), 1); - ENQUEUE_TAIL(&exif_apps, &app->Q); - QUEUE_INIT(&app->ifds); - app->fcache = gbfopen(NULL, "wb", MYNAME); + ENQUEUE_TAIL(&exif_apps, &app->Q); + QUEUE_INIT(&app->ifds); + app->fcache = gbfopen(NULL, "wb", MYNAME); - app->marker = gbfgetuint16(fin); - app->len = gbfgetuint16(fin); + app->marker = gbfgetuint16(fin); + app->len = gbfgetuint16(fin); #ifdef EXIF_DBG - printf(MYNAME ": api = %02X, len = %d, offs = %04X\n", app->marker & 0xFF, app->len, gbftell(fin)); + printf(MYNAME ": api = %02X, len = %d, offs = %04X\n", app->marker & 0xFF, app->len, gbftell(fin)); #endif - if (exif_app || (app->marker == 0xFFDA)) /* compressed data */ { - gbfcopyfrom(app->fcache, fin, 0x7FFFFFFF); + if (exif_app || (app->marker == 0xFFDA)) /* compressed data */ { + gbfcopyfrom(app->fcache, fin, 0x7FFFFFFF); #ifdef EXIF_DBG - printf(MYNAME ": compressed data size = %d\n", gbftell(app->fcache)); + printf(MYNAME ": compressed data size = %d\n", gbftell(app->fcache)); #endif - } - else { - gbfcopyfrom(app->fcache, fin, app->len - 2); - if (app->marker == 0xFFE1) { - exif_app = app; - } - } - } - - return exif_app; + } else { + gbfcopyfrom(app->fcache, fin, app->len - 2); + if (app->marker == 0xFFE1) { + exif_app = app; + } + } + } + + return exif_app; } -static exif_ifd_t * -exif_read_ifd(exif_app_t *app, const gbuint16 ifd_nr, gbsize_t offs, - gbuint32 *exif_ifd_ofs, gbuint32 *gps_ifd_ofs, gbuint32 *inter_ifd_ofs) +static exif_ifd_t* +exif_read_ifd(exif_app_t* app, const gbuint16 ifd_nr, gbsize_t offs, + gbuint32* exif_ifd_ofs, gbuint32* gps_ifd_ofs, gbuint32* inter_ifd_ofs) { - queue *elem, *tmp; - gbuint16 i; - exif_ifd_t *ifd; - gbfile *fin = app->fexif; + queue* elem, *tmp; + gbuint16 i; + exif_ifd_t* ifd; + gbfile* fin = app->fexif; - ifd = xcalloc(sizeof(*ifd), 1); - QUEUE_INIT(&ifd->tags); - ENQUEUE_TAIL(&app->ifds, &ifd->Q); - ifd->nr = ifd_nr; + ifd = (exif_ifd_t*) xcalloc(sizeof(*ifd), 1); + QUEUE_INIT(&ifd->tags); + ENQUEUE_TAIL(&app->ifds, &ifd->Q); + ifd->nr = ifd_nr; - gbfseek(fin, offs, SEEK_SET); - ifd->count = gbfgetuint16(fin); + gbfseek(fin, offs, SEEK_SET); + ifd->count = gbfgetuint16(fin); #ifdef EXIF_DBG - { - char *name; - switch(ifd_nr) { - case IFD0: name = "IFD0"; break; - case IFD1: name = "IFD1"; break; - case GPS_IFD: name = "GPS"; break; - case EXIF_IFD: name = "EXIF"; break; - case INTER_IFD: name = "INTER"; break; - default: name = "private"; break; - } - printf(MYNAME "-offs 0x%04X: Number of items in IFD%d \"%s\" = %d (0x%2x)\n", - offs, ifd_nr, name, ifd->count, ifd->count); - } + { + char* name; + switch (ifd_nr) { + case IFD0: + name = "IFD0"; + break; + case IFD1: + name = "IFD1"; + break; + case GPS_IFD: + name = "GPS"; + break; + case EXIF_IFD: + name = "EXIF"; + break; + case INTER_IFD: + name = "INTER"; + break; + default: + name = "private"; + break; + } + printf(MYNAME "-offs 0x%04X: Number of items in IFD%d \"%s\" = %d (0x%2x)\n", + offs, ifd_nr, name, ifd->count, ifd->count); + } #endif - if (ifd->count == 0) return ifd; + if (ifd->count == 0) { + return ifd; + } - for (i = 0; i < ifd->count; i++) { - exif_tag_t *tag; - offs = gbftell(fin); + for (i = 0; i < ifd->count; i++) { + exif_tag_t* tag; + offs = gbftell(fin); - tag = xcalloc(sizeof(*tag), 1); + tag = (exif_tag_t*) xcalloc(sizeof(*tag), 1); - ENQUEUE_TAIL(&ifd->tags, &tag->Q); + ENQUEUE_TAIL(&ifd->tags, &tag->Q); - tag->id = gbfgetuint16(fin); - tag->type = gbfgetuint16(fin); - tag->count = gbfgetuint32(fin); - tag->size = exif_type_size(tag->type) * tag->count; - tag->data = &tag->value; + tag->id = gbfgetuint16(fin); + tag->type = gbfgetuint16(fin); + tag->count = gbfgetuint32(fin); + tag->size = exif_type_size(tag->type) * tag->count; + tag->data = &tag->value; #ifdef EXIF_DBG - tag->offs = offs; + tag->offs = offs; #endif - if (BYTE_TYPE(tag->type) && (tag->count <= 4)) { - gbfread(tag->data, 4, 1, fin); - } - else { - tag->value = gbfgetuint32(fin); - tag->origin = tag->value; - } - - if (ifd_nr == IFD0) { - if (tag->id == IFD0_TAG_EXIF_IFD_OFFS) *exif_ifd_ofs = tag->value; - else if (tag->id == IFD0_TAG_GPS_IFD_OFFS) *gps_ifd_ofs = tag->value; - } - else if (ifd_nr == EXIF_IFD) { - if (tag->id == EXIF_IFD_TAG_INTER_IFD_OFFS) *inter_ifd_ofs = tag->value; - } - } - - ifd->next_ifd = gbfgetuint16(fin); - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - if ((tag->size > 4) && (tag->value)) { - gbuint16 i; - char *ptr; - - tag->data = xmalloc(tag->size); - tag->data_is_dynamic = 1; - - ptr = tag->data; - gbfseek(fin, tag->value, SEEK_SET); - - if (BYTE_TYPE(tag->type)) gbfread(ptr, tag->count, 1, fin); - else for (i = 0; i < tag->count; i++) { - switch(tag->type) { - case EXIF_TYPE_SHORT: - case EXIF_TYPE_SSHORT: - *(gbint16 *)ptr = gbfgetuint16(fin); - break; - case EXIF_TYPE_IFD: - case EXIF_TYPE_LONG: - case EXIF_TYPE_SLONG: - *(gbint32 *)ptr = gbfgetuint32(fin); - break; - case EXIF_TYPE_RAT: - case EXIF_TYPE_SRAT: - *(gbint32 *)ptr = gbfgetuint32(fin); - *(gbint32 *)(ptr+4) = gbfgetuint32(fin); - break; - case EXIF_TYPE_FLOAT: - *(float *)ptr = gbfgetflt(fin); - break; - case EXIF_TYPE_DOUBLE: - *(double *)ptr = gbfgetdbl(fin); - break; - default: - gbfread(ptr, 1, 1, fin); - break; - } - ptr += (tag->size / tag->count); - } - } + if (BYTE_TYPE(tag->type) && (tag->count <= 4)) { + gbfread(tag->data, 4, 1, fin); + } else { + tag->value = gbfgetuint32(fin); + tag->origin = tag->value; + } + + if (ifd_nr == IFD0) { + if (tag->id == IFD0_TAG_EXIF_IFD_OFFS) { + *exif_ifd_ofs = tag->value; + } else if (tag->id == IFD0_TAG_GPS_IFD_OFFS) { + *gps_ifd_ofs = tag->value; + } + } else if (ifd_nr == EXIF_IFD) { + if (tag->id == EXIF_IFD_TAG_INTER_IFD_OFFS) { + *inter_ifd_ofs = tag->value; + } + } + } + + ifd->next_ifd = gbfgetuint16(fin); + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t* tag = (exif_tag_t*)elem; + if ((tag->size > 4) && (tag->value)) { + gbuint16 i; + char* ptr; + + tag->data = xmalloc(tag->size); + tag->data_is_dynamic = 1; + + ptr = (char*) tag->data; + gbfseek(fin, tag->value, SEEK_SET); + + if (BYTE_TYPE(tag->type)) { + gbfread(ptr, tag->count, 1, fin); + } else for (i = 0; i < tag->count; i++) { + switch (tag->type) { + case EXIF_TYPE_SHORT: + case EXIF_TYPE_SSHORT: + *(gbint16*)ptr = gbfgetuint16(fin); + break; + case EXIF_TYPE_IFD: + case EXIF_TYPE_LONG: + case EXIF_TYPE_SLONG: + *(gbint32*)ptr = gbfgetuint32(fin); + break; + case EXIF_TYPE_RAT: + case EXIF_TYPE_SRAT: + *(gbint32*)ptr = gbfgetuint32(fin); + *(gbint32*)(ptr+4) = gbfgetuint32(fin); + break; + case EXIF_TYPE_FLOAT: + *(float*)ptr = gbfgetflt(fin); + break; + case EXIF_TYPE_DOUBLE: + *(double*)ptr = gbfgetdbl(fin); + break; + default: + gbfread(ptr, 1, 1, fin); + break; + } + ptr += (tag->size / tag->count); + } + } #ifdef EXIF_DBG - printf(MYNAME "-offs 0x%04X: ifd=%d id=0x%04X t=0x%04X c=%4d s=%4d v=0x%08X", - tag->offs, ifd->nr, tag->id, tag->type, tag->count, tag->size, tag->value); - if (tag->type == EXIF_TYPE_ASCII) printf(" \"%s\"", exif_read_str(tag)); - printf("\n"); + printf(MYNAME "-offs 0x%04X: ifd=%d id=0x%04X t=0x%04X c=%4d s=%4d v=0x%08X", + tag->offs, ifd->nr, tag->id, tag->type, tag->count, tag->size, tag->value); + if (tag->type == EXIF_TYPE_ASCII) { + printf(" \"%s\"", exif_read_str(tag)); + } + printf("\n"); #endif - } + } - return ifd; + return ifd; } static void -exif_read_app(exif_app_t *app) +exif_read_app(exif_app_t* app) { - gbsize_t offs; - gbuint32 exif_ifd_ofs, gps_ifd_ofs, inter_ifd_ofs; - exif_ifd_t *ifd; - gbfile *fin = app->fexif; + gbsize_t offs; + gbuint32 exif_ifd_ofs, gps_ifd_ofs, inter_ifd_ofs; + exif_ifd_t* ifd; + gbfile* fin = app->fexif; #ifdef EXIF_DBG - printf(MYNAME ": read_app...\n"); - print_buff((const char *)fin->handle.mem, 16, MYNAME); - printf("\n"); + printf(MYNAME ": read_app...\n"); + print_buff((const char*)fin->handle.mem, 16, MYNAME); + printf("\n"); #endif - exif_ifd_ofs = gps_ifd_ofs = inter_ifd_ofs = 0; - - gbfseek(fin, 4, SEEK_SET); - offs = gbfgetuint32(fin); - - ifd = exif_read_ifd(app, IFD0, offs, &exif_ifd_ofs, &gps_ifd_ofs, &inter_ifd_ofs); - if (ifd == NULL) return; - - if (ifd->next_ifd) - ifd = exif_read_ifd(app, IFD1, ifd->next_ifd, &exif_ifd_ofs, &gps_ifd_ofs, &inter_ifd_ofs); - if (exif_ifd_ofs) - ifd = exif_read_ifd(app, EXIF_IFD, exif_ifd_ofs, NULL, NULL, &inter_ifd_ofs); - if (gps_ifd_ofs) - ifd = exif_read_ifd(app, 3, gps_ifd_ofs, NULL, NULL, NULL); - if (inter_ifd_ofs) - ifd = exif_read_ifd(app, 4, inter_ifd_ofs, NULL, NULL, NULL); + exif_ifd_ofs = gps_ifd_ofs = inter_ifd_ofs = 0; + + gbfseek(fin, 4, SEEK_SET); + offs = gbfgetuint32(fin); + + ifd = exif_read_ifd(app, IFD0, offs, &exif_ifd_ofs, &gps_ifd_ofs, &inter_ifd_ofs); + if (ifd == NULL) { + return; + } + + if (ifd->next_ifd) { + ifd = exif_read_ifd(app, IFD1, ifd->next_ifd, &exif_ifd_ofs, &gps_ifd_ofs, &inter_ifd_ofs); + } + if (exif_ifd_ofs) { + ifd = exif_read_ifd(app, EXIF_IFD, exif_ifd_ofs, NULL, NULL, &inter_ifd_ofs); + } + if (gps_ifd_ofs) { + ifd = exif_read_ifd(app, 3, gps_ifd_ofs, NULL, NULL, NULL); + } + if (inter_ifd_ofs) { + ifd = exif_read_ifd(app, 4, inter_ifd_ofs, NULL, NULL, NULL); + } } static void -exif_examine_app(exif_app_t *app) +exif_examine_app(exif_app_t* app) { - gbuint16 endianess; - gbuint32 ident; - gbfile *ftmp = exif_app->fcache; - int i; + gbuint16 endianess; + gbuint32 ident; + gbfile* ftmp = exif_app->fcache; + int i; - gbfrewind(ftmp); - ident = gbfgetuint32(ftmp); - is_fatal(ident != 0x66697845, MYNAME ": Invalid EXIF header magic."); - is_fatal(gbfgetint16(ftmp) != 0, MYNAME ": Error in EXIF header."); - endianess = gbfgetint16(ftmp); + gbfrewind(ftmp); + ident = gbfgetuint32(ftmp); + is_fatal(ident != 0x66697845, MYNAME ": Invalid EXIF header magic."); + is_fatal(gbfgetint16(ftmp) != 0, MYNAME ": Error in EXIF header."); + endianess = gbfgetint16(ftmp); #ifdef EXIF_DBG - printf(MYNAME ": endianess = 0x%04X\n", endianess); + printf(MYNAME ": endianess = 0x%04X\n", endianess); #endif - if (endianess == 0x4949) ftmp->big_endian = 0; - else if (endianess == 0x4D4D) ftmp->big_endian = 1; - else fatal(MYNAME ": Invalid endianess identifier 0x%04X!\n", endianess); - - gbfseek(ftmp, 6, SEEK_SET); - app->fexif = gbfopen(NULL, "wb", MYNAME); - app->fexif->big_endian = ftmp->big_endian; - i = gbfcopyfrom(app->fexif, ftmp, 0x7FFFFFFF); - - exif_read_app(exif_app); + if (endianess == 0x4949) { + ftmp->big_endian = 0; + } else if (endianess == 0x4D4D) { + ftmp->big_endian = 1; + } else { + fatal(MYNAME ": Invalid endianess identifier 0x%04X!\n", endianess); + } + + gbfseek(ftmp, 6, SEEK_SET); + app->fexif = gbfopen(NULL, "wb", MYNAME); + app->fexif->big_endian = ftmp->big_endian; + i = gbfcopyfrom(app->fexif, ftmp, 0x7FFFFFFF); + + exif_read_app(exif_app); } -static exif_ifd_t * -exif_find_ifd(exif_app_t *app, const gbuint16 ifd_nr) +static exif_ifd_t* +exif_find_ifd(exif_app_t* app, const gbuint16 ifd_nr) { - queue *e0, *t0; + queue* e0, *t0; - QUEUE_FOR_EACH(&app->ifds, e0, t0) { - exif_ifd_t *ifd = (exif_ifd_t *)e0; + QUEUE_FOR_EACH(&app->ifds, e0, t0) { + exif_ifd_t* ifd = (exif_ifd_t*)e0; - if (ifd->nr == ifd_nr) return ifd; - } - return NULL; + if (ifd->nr == ifd_nr) { + return ifd; + } + } + return NULL; } -static exif_tag_t * -exif_find_tag(exif_app_t *app, const gbuint16 ifd_nr, const gbuint16 tag_id) +static exif_tag_t* +exif_find_tag(exif_app_t* app, const gbuint16 ifd_nr, const gbuint16 tag_id) { - exif_ifd_t *ifd = exif_find_ifd(app, ifd_nr); - if (ifd != NULL) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - if (tag->id == tag_id) return tag; - } - } - return NULL; + exif_ifd_t* ifd = exif_find_ifd(app, ifd_nr); + if (ifd != NULL) { + queue* elem, *tmp; + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t* tag = (exif_tag_t*)elem; + if (tag->id == tag_id) { + return tag; + } + } + } + return NULL; } static time_t -exif_get_exif_time(exif_app_t *app) +exif_get_exif_time(exif_app_t* app) { - exif_tag_t *tag; - time_t res = 0; - - tag = exif_find_tag(app, EXIF_IFD, 0x9003); /* DateTimeOriginal from EXIF */ - if (! tag) tag = exif_find_tag(app, IFD0, 0x0132); /* DateTime from IFD0 */ - if (! tag) tag = exif_find_tag(app, EXIF_IFD, 0x9004); /* DateTimeDigitized from EXIF */ - if (tag) { - struct tm tm; - char *c, *str; - - memset(&tm, 0, sizeof(tm)); - str = exif_read_str(tag); - c = strptime(str, "%Y:%m:%d %H:%M:%S", &tm); - if (c && (*c == '\0')) res = mklocaltime(&tm); - - xfree(str); - } - return res; + exif_tag_t* tag; + time_t res = 0; + + tag = exif_find_tag(app, EXIF_IFD, 0x9003); /* DateTimeOriginal from EXIF */ + if (! tag) { + tag = exif_find_tag(app, IFD0, 0x0132); /* DateTime from IFD0 */ + } + if (! tag) { + tag = exif_find_tag(app, EXIF_IFD, 0x9004); /* DateTimeDigitized from EXIF */ + } + if (tag) { + struct tm tm; + char* c, *str; + + memset(&tm, 0, sizeof(tm)); + str = exif_read_str(tag); + c = strptime(str, "%Y:%m:%d %H:%M:%S", &tm); + if (c && (*c == '\0')) { + res = mklocaltime(&tm); + } + + xfree(str); + } + return res; } -static waypoint * -exif_waypt_from_exif_app(exif_app_t *app) +static waypoint* +exif_waypt_from_exif_app(exif_app_t* app) { - waypoint *wpt; - queue *elem, *tmp; - exif_ifd_t *ifd; - exif_tag_t *tag; - char lat_ref = '\0'; - char lon_ref = '\0'; - char alt_ref = 0; - char speed_ref = '\0'; - char *datum = NULL; - char mode = '\0'; - double gpsdop = unknown_alt; - double alt = unknown_alt; - time_t timestamp = UNKNOWN_TIMESTAMP; - time_t datestamp = UNKNOWN_TIMESTAMP; - - ifd = exif_find_ifd(app, GPS_IFD); - if (ifd == NULL) return NULL; - - wpt = waypt_new(); - - wpt->latitude = unknown_alt; - wpt->longitude = unknown_alt; - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - tag = (exif_tag_t *)elem; - - switch(tag->id) { - case GPS_IFD_TAG_VERSION: break; - case GPS_IFD_TAG_LATREF: lat_ref = *(char *)tag->data; break; - case GPS_IFD_TAG_LAT: wpt->latitude = exif_read_coord(tag); break; - case GPS_IFD_TAG_LONREF: lon_ref = *(char *)tag->data; break; - case GPS_IFD_TAG_LON: wpt->longitude = exif_read_coord(tag); break; - case GPS_IFD_TAG_ALTREF: alt_ref = *(char *)tag->data; break; - case GPS_IFD_TAG_ALT: alt = exif_read_double(tag, 0); break; - case GPS_IFD_TAG_TIMESTAMP: timestamp = exif_read_timestamp(tag); break; - case GPS_IFD_TAG_SAT: wpt->sat = atoi((char *)tag->data); break; - case GPS_IFD_TAG_MODE: mode = *(char *)tag->data; break; - case GPS_IFD_TAG_DOP: gpsdop = exif_read_double(tag, 0); break; - case GPS_IFD_TAG_SPEEDREF: speed_ref = *(char *)tag->data; break; - case GPS_IFD_TAG_SPEED: WAYPT_SET(wpt, speed, exif_read_double(tag, 0)); break; - case GPS_IFD_TAG_DATUM: datum = exif_read_str(tag); break; - case GPS_IFD_TAG_DATESTAMP: datestamp = exif_read_datestamp(tag); break; - } - } - - if ((wpt->latitude == unknown_alt) || (wpt->longitude == unknown_alt)) - fatal(MYNAME ": Missing GPSLatitude and/or GPSLongitude!\n"); - - if (lat_ref == 'S') - wpt->latitude *= -1; - else if (lat_ref != 'N') - warning(MYNAME ": GPSLatitudeRef not set! Using N(orth).\n"); - - if (lon_ref == 'W') - wpt->longitude *= -1; - else if (lon_ref != 'E') - warning(MYNAME ": GPSLongitudeRef not set! Using E(east).\n"); + waypoint* wpt; + queue* elem, *tmp; + exif_ifd_t* ifd; + exif_tag_t* tag; + char lat_ref = '\0'; + char lon_ref = '\0'; + char alt_ref = 0; + char speed_ref = '\0'; + char* datum = NULL; + char mode = '\0'; + double gpsdop = unknown_alt; + double alt = unknown_alt; + time_t timestamp = UNKNOWN_TIMESTAMP; + time_t datestamp = UNKNOWN_TIMESTAMP; + + ifd = exif_find_ifd(app, GPS_IFD); + if (ifd == NULL) { + return NULL; + } + + wpt = waypt_new(); + + wpt->latitude = unknown_alt; + wpt->longitude = unknown_alt; + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + tag = (exif_tag_t*)elem; + + switch (tag->id) { + case GPS_IFD_TAG_VERSION: + break; + case GPS_IFD_TAG_LATREF: + lat_ref = *(char*)tag->data; + break; + case GPS_IFD_TAG_LAT: + wpt->latitude = exif_read_coord(tag); + break; + case GPS_IFD_TAG_LONREF: + lon_ref = *(char*)tag->data; + break; + case GPS_IFD_TAG_LON: + wpt->longitude = exif_read_coord(tag); + break; + case GPS_IFD_TAG_ALTREF: + alt_ref = *(char*)tag->data; + break; + case GPS_IFD_TAG_ALT: + alt = exif_read_double(tag, 0); + break; + case GPS_IFD_TAG_TIMESTAMP: + timestamp = exif_read_timestamp(tag); + break; + case GPS_IFD_TAG_SAT: + wpt->sat = atoi((char*)tag->data); + break; + case GPS_IFD_TAG_MODE: + mode = *(char*)tag->data; + break; + case GPS_IFD_TAG_DOP: + gpsdop = exif_read_double(tag, 0); + break; + case GPS_IFD_TAG_SPEEDREF: + speed_ref = *(char*)tag->data; + break; + case GPS_IFD_TAG_SPEED: + WAYPT_SET(wpt, speed, exif_read_double(tag, 0)); + break; + case GPS_IFD_TAG_DATUM: + datum = exif_read_str(tag); + break; + case GPS_IFD_TAG_DATESTAMP: + datestamp = exif_read_datestamp(tag); + break; + } + } + + if ((wpt->latitude == unknown_alt) || (wpt->longitude == unknown_alt)) { + fatal(MYNAME ": Missing GPSLatitude and/or GPSLongitude!\n"); + } + + if (lat_ref == 'S') { + wpt->latitude *= -1; + } else if (lat_ref != 'N') { + warning(MYNAME ": GPSLatitudeRef not set! Using N(orth).\n"); + } + + if (lon_ref == 'W') { + wpt->longitude *= -1; + } else if (lon_ref != 'E') { + warning(MYNAME ": GPSLongitudeRef not set! Using E(east).\n"); + } #ifdef EXIF_DBG - printf(MYNAME "-GPSLatitude = %12.7f\n", wpt->latitude); - printf(MYNAME "-GPSLongitude = %12.7f\n", wpt->longitude); + printf(MYNAME "-GPSLatitude = %12.7f\n", wpt->latitude); + printf(MYNAME "-GPSLongitude = %12.7f\n", wpt->longitude); #endif - if (datum) { - int idatum = gt_lookup_datum_index(datum, MYNAME); - if (idatum < 0) - fatal(MYNAME ": Unknown GPSMapDatum \"%s\"!\n", datum); - if (idatum != DATUM_WGS84) { - double alt; - GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, - &wpt->latitude, &wpt->longitude, &alt, idatum); - } - xfree(datum); - } - - if (alt != unknown_alt) { - if (alt_ref != 0) - warning(MYNAME ": Invalid GPSAltitudeRef (%d)! Using 0 (= Sea level).\n", alt_ref); - wpt->altitude = alt; + if (datum) { + int idatum = gt_lookup_datum_index(datum, MYNAME); + if (idatum < 0) { + fatal(MYNAME ": Unknown GPSMapDatum \"%s\"!\n", datum); + } + if (idatum != DATUM_WGS84) { + double alt; + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + &wpt->latitude, &wpt->longitude, &alt, idatum); + } + xfree(datum); + } + + if (alt != unknown_alt) { + if (alt_ref != 0) { + warning(MYNAME ": Invalid GPSAltitudeRef (%d)! Using 0 (= Sea level).\n", alt_ref); + } + wpt->altitude = alt; #ifdef EXIF_DBG - printf(MYNAME "-GPSAltitude = %12.7f m\n", wpt->altitude); + printf(MYNAME "-GPSAltitude = %12.7f m\n", wpt->altitude); #endif - } - - if WAYPT_HAS(wpt, speed) { - switch(speed_ref) { - case 'K': - wpt->speed = KPH_TO_MPS(wpt->speed); - break; - case 'M': - wpt->speed = MPH_TO_MPS(wpt->speed); - break; - case 'N': - wpt->speed = KNOTS_TO_MPS(wpt->speed); - break; - default: - wpt->speed = 0; - WAYPT_UNSET(wpt, speed); - warning(MYNAME ": Unknown GPSSpeedRef unit %c (0x%02x)!\n", speed_ref, speed_ref); - } + } + + if WAYPT_HAS(wpt, speed) { + switch (speed_ref) { + case 'K': + wpt->speed = KPH_TO_MPS(wpt->speed); + break; + case 'M': + wpt->speed = MPH_TO_MPS(wpt->speed); + break; + case 'N': + wpt->speed = KNOTS_TO_MPS(wpt->speed); + break; + default: + wpt->speed = 0; + WAYPT_UNSET(wpt, speed); + warning(MYNAME ": Unknown GPSSpeedRef unit %c (0x%02x)!\n", speed_ref, speed_ref); + } #ifdef EXIF_DBG - if WAYPT_HAS(wpt, speed) printf(MYNAME "-GPSSpeed = %12.2f m/s\n", wpt->speed); + if WAYPT_HAS(wpt, speed) { + printf(MYNAME "-GPSSpeed = %12.2f m/s\n", wpt->speed); + } #endif - } - - if (mode == '2') { - wpt->fix = fix_2d; - if (gpsdop != unknown_alt) wpt->hdop = gpsdop; - } - else if (mode == '3') { - wpt->fix = fix_3d; - if (gpsdop != unknown_alt) wpt->pdop = gpsdop; - } - - if (timestamp != UNKNOWN_TIMESTAMP) { - if (datestamp != UNKNOWN_TIMESTAMP) timestamp += datestamp; - } - else timestamp = datestamp; - if (timestamp != UNKNOWN_TIMESTAMP) { + } + + if (mode == '2') { + wpt->fix = fix_2d; + if (gpsdop != unknown_alt) { + wpt->hdop = gpsdop; + } + } else if (mode == '3') { + wpt->fix = fix_3d; + if (gpsdop != unknown_alt) { + wpt->pdop = gpsdop; + } + } + + if (timestamp != UNKNOWN_TIMESTAMP) { + if (datestamp != UNKNOWN_TIMESTAMP) { + timestamp += datestamp; + } + } else { + timestamp = datestamp; + } + if (timestamp != UNKNOWN_TIMESTAMP) { #ifdef EXIF_DBG - char *str = exif_time_str(timestamp); - printf(MYNAME "-GPSTimeStamp = %s\n", str); - xfree(str); + char* str = exif_time_str(timestamp); + printf(MYNAME "-GPSTimeStamp = %s\n", str); + xfree(str); #endif - wpt->creation_time = timestamp; - } - else - wpt->creation_time = exif_get_exif_time(app); - - tag = exif_find_tag(app, EXIF_IFD, EXIF_IFD_TAG_USER_CMT); /* UserComment */ - if (tag && (tag->size > 8)) { - char *str = NULL; - if (memcmp(tag->data, "ASCII\0\0\0", 8) == 0) { - str = xstrndup((char *)tag->data + 8, tag->size - 8); - } - else if (memcmp(tag->data, "UNICODE\0", 8) == 0) { - int i, len = (tag->size - 8) / 2; - gbint16 *s = (void *)((char *)tag->data + 8); - for (i = 0; i < len; i++) s[i] = be_read16(&s[i]); /* always BE ? */ - str = cet_str_uni_to_any(s, len, global_opts.charset); - } - if (str != NULL) { - wpt->notes = str; - } - } - - if (opt_filename) { - char *c, *cx; - char *str = xstrdup(fin->name); - - cx = str; - if ((c = strrchr(cx, ':'))) cx = c + 1; - if ((c = strrchr(cx, '\\'))) cx = c + 1; - if ((c = strrchr(cx, '/'))) cx = c + 1; - if (((c = strchr(cx, '.'))) && (c != cx)) *c = '\0'; - - if (wpt->shortname) xfree(wpt->shortname); - wpt->shortname = xstrdup(cx); - xfree(str); - } - - return wpt; + wpt->creation_time = timestamp; + } else { + wpt->creation_time = exif_get_exif_time(app); + } + + tag = exif_find_tag(app, EXIF_IFD, EXIF_IFD_TAG_USER_CMT); /* UserComment */ + if (tag && (tag->size > 8)) { + char* str = NULL; + if (memcmp(tag->data, "ASCII\0\0\0", 8) == 0) { + str = xstrndup((char*)tag->data + 8, tag->size - 8); + } else if (memcmp(tag->data, "UNICODE\0", 8) == 0) { + int i, len = (tag->size - 8) / 2; + gbint16* s = (gbint16*)((char*)tag->data + 8); + for (i = 0; i < len; i++) { + s[i] = be_read16(&s[i]); /* always BE ? */ + } + str = cet_str_uni_to_any(s, len, global_opts.charset); + } + if (str != NULL) { + wpt->notes = str; + } + } + + if (opt_filename) { + char* c, *cx; + char* str = xstrdup(fin->name); + + cx = str; + if ((c = strrchr(cx, ':'))) { + cx = c + 1; + } + if ((c = strrchr(cx, '\\'))) { + cx = c + 1; + } + if ((c = strrchr(cx, '/'))) { + cx = c + 1; + } + if (((c = strchr(cx, '.'))) && (c != cx)) { + *c = '\0'; + } + + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup(cx); + xfree(str); + } + + return wpt; } static void -exif_dec2frac(double val, gbint32 *num, gbint32 *den) +exif_dec2frac(double val, gbint32* num, gbint32* den) { - char sval[16], snum[16]; - char dot = 0; - int den1 = 1; - int num1, num2, den2, rem; - char *cx; - double vx; - - if (val < 0.000000001) val = 0.0; - else if (val > 999999999.0) - fatal(MYNAME ": Value (%f) to big for a rational representation!\n", val); - - num1 = 0; - vx = fabs(val); - while (vx > 1) { - num1++; - vx = vx / 10; - } - - snprintf(sval, sizeof(sval), "%*.*f", 9, 9 - num1, fabs(val)); - snum[0] = '\0'; - - cx = sval; - while (*cx) { - if (dot) den1 *= 10; - if (*cx == '.') dot = 1; - else strncat(snum, cx, 1); - cx++; - } - - num1 = atoi(snum); - if (den1 == 1) { - *num = num1; - *den = den1; - } - - num2 = num1; - den2 = den1; - rem = 1; - - /* Euclid's Algorithm to find the gcd */ - while (num2 % den2) { - rem = num2 % den2; - num2 = den2; - den2 = rem; - } - if (den2 != den1) rem = den2; - - *num = num1 / rem; - *den = den1 / rem; + char sval[16], snum[16]; + char dot = 0; + int den1 = 1; + int num1, num2, den2, rem; + char* cx; + double vx; + + if (val < 0.000000001) { + val = 0.0; + } else if (val > 999999999.0) { + fatal(MYNAME ": Value (%f) to big for a rational representation!\n", val); + } + + num1 = 0; + vx = fabs(val); + while (vx > 1) { + num1++; + vx = vx / 10; + } + + snprintf(sval, sizeof(sval), "%*.*f", 9, 9 - num1, fabs(val)); + snum[0] = '\0'; + + cx = sval; + while (*cx) { + if (dot) { + den1 *= 10; + } + if (*cx == '.') { + dot = 1; + } else { + strncat(snum, cx, 1); + } + cx++; + } + + num1 = atoi(snum); + if (den1 == 1) { + *num = num1; + *den = den1; + } + + num2 = num1; + den2 = den1; + rem = 1; + + /* Euclid's Algorithm to find the gcd */ + while (num2 % den2) { + rem = num2 % den2; + num2 = den2; + den2 = rem; + } + if (den2 != den1) { + rem = den2; + } + + *num = num1 / rem; + *den = den1 / rem; } -static exif_tag_t * -exif_put_value(const int ifd_nr, const gbuint16 tag_id, const gbuint16 type, const gbuint32 count, const int index, const void *data) +static exif_tag_t* +exif_put_value(const int ifd_nr, const gbuint16 tag_id, const gbuint16 type, const gbuint32 count, const int index, const void* data) { - exif_tag_t *tag = NULL; - exif_ifd_t *ifd; - gbuint16 item_size, size; - - ifd = exif_find_ifd(exif_app, ifd_nr); - if (ifd == NULL) { - ifd = xcalloc(sizeof(*ifd), 1); - ifd->nr = ifd_nr; - QUEUE_INIT(&ifd->tags); - ENQUEUE_TAIL(&exif_app->ifds, &ifd->Q); - } - else tag = exif_find_tag(exif_app, ifd_nr, tag_id); - - item_size = exif_type_size(type); - - if ((data == NULL) || (count < 1) || (index < 0)) size = 0; - else size = (index + count) * item_size; - - if (tag == NULL) { - if (size == 0) return NULL; - - tag = xcalloc(sizeof(*tag), 1); - - tag->id = tag_id; - tag->type = type; - tag->count = index + count; - tag->size = size; - tag->data = xcalloc((size < 4) ? 4 : size, 1); - tag->data_is_dynamic = 1; - ifd->count++; - - ENQUEUE_TAIL(&ifd->tags, &tag->Q); - } - else { - if (size == 0) { /* remove this element */ - ifd->count--; - exif_release_tag(tag); - return NULL; - } - if (tag->count < (index + count)) { - if (! tag->data_is_dynamic) { - void *tmp = xmalloc(tag->size < 4 ? 4 : tag->size); - memcpy(tmp, tag->data, tag->size); - tag->data = tmp; - tag->data_is_dynamic = 1; - } - tag->size = size; - tag->count = index + count; - tag->data = xrealloc(tag->data, size < 4 ? 4 : size); - } - } - - switch(type) { - case EXIF_TYPE_RAT: - case EXIF_TYPE_SRAT: { - double val = *(double *)data; - gbuint32 *dest = tag->data; - - if ((int)val == val) { - dest[index * 2] = (int)val; - dest[(index * 2) + 1] = 1; - } - else { - gbint32 Nom, Den; - exif_dec2frac(val, &Nom, &Den); - if ((type == EXIF_TYPE_SRAT) && (val < 0.0)) Nom *= -1; - dest[index * 2] = Nom; - dest[(index * 2) + 1] = Den; - } - } - break; - default: { - char *dest = tag->data; - memcpy(&dest[index * item_size], data, count * item_size); - } - } - return tag; + exif_tag_t* tag = NULL; + exif_ifd_t* ifd; + gbuint16 item_size, size; + + ifd = exif_find_ifd(exif_app, ifd_nr); + if (ifd == NULL) { + ifd = (exif_ifd_t*) xcalloc(sizeof(*ifd), 1); + ifd->nr = ifd_nr; + QUEUE_INIT(&ifd->tags); + ENQUEUE_TAIL(&exif_app->ifds, &ifd->Q); + } else { + tag = exif_find_tag(exif_app, ifd_nr, tag_id); + } + + item_size = exif_type_size(type); + + if ((data == NULL) || (count < 1) || (index < 0)) { + size = 0; + } else { + size = (index + count) * item_size; + } + + if (tag == NULL) { + if (size == 0) { + return NULL; + } + + tag = (exif_tag_t*) xcalloc(sizeof(*tag), 1); + + tag->id = tag_id; + tag->type = type; + tag->count = index + count; + tag->size = size; + tag->data = xcalloc((size < 4) ? 4 : size, 1); + tag->data_is_dynamic = 1; + ifd->count++; + + ENQUEUE_TAIL(&ifd->tags, &tag->Q); + } else { + if (size == 0) { /* remove this element */ + ifd->count--; + exif_release_tag(tag); + return NULL; + } + if (tag->count < (index + count)) { + if (! tag->data_is_dynamic) { + void* tmp = xmalloc(tag->size < 4 ? 4 : tag->size); + memcpy(tmp, tag->data, tag->size); + tag->data = tmp; + tag->data_is_dynamic = 1; + } + tag->size = size; + tag->count = index + count; + tag->data = xrealloc(tag->data, size < 4 ? 4 : size); + } + } + + switch (type) { + case EXIF_TYPE_RAT: + case EXIF_TYPE_SRAT: { + double val = *(double*)data; + gbuint32* dest = (gbuint32*) tag->data; + + if ((int)val == val) { + dest[index * 2] = (int)val; + dest[(index * 2) + 1] = 1; + } else { + gbint32 Nom, Den; + exif_dec2frac(val, &Nom, &Den); + if ((type == EXIF_TYPE_SRAT) && (val < 0.0)) { + Nom *= -1; + } + dest[index * 2] = Nom; + dest[(index * 2) + 1] = Den; + } + } + break; + default: { + char* dest = (char*) tag->data; + memcpy(&dest[index * item_size], data, count * item_size); + } + } + return tag; } static void exif_put_double(const int ifd_nr, const int tag_id, const int index, const double val) { - double d = fabs(val); - exif_put_value(ifd_nr, tag_id, EXIF_TYPE_RAT, 1, index, &d); + double d = fabs(val); + exif_put_value(ifd_nr, tag_id, EXIF_TYPE_RAT, 1, index, &d); } static void -exif_put_str(const int ifd_nr, const int tag_id, const char *val) +exif_put_str(const int ifd_nr, const int tag_id, const char* val) { - int len = (val) ? strlen(val) + 1 : 0; - exif_put_value(ifd_nr, tag_id, EXIF_TYPE_ASCII, len, 0, val); + int len = (val) ? strlen(val) + 1 : 0; + exif_put_value(ifd_nr, tag_id, EXIF_TYPE_ASCII, len, 0, val); } static void exif_put_coord(const int ifd_nr, const int tag_id, const double val) { - double vmin, vsec; - int vint; + double vmin, vsec; + int vint; - vint = abs((int) val); - vmin = 60.0 * (fabs(val) - vint); - vsec = 60.0 * (vmin - floor(vmin)); - vmin = floor(vmin); + vint = abs((int) val); + vmin = 60.0 * (fabs(val) - vint); + vsec = 60.0 * (vmin - floor(vmin)); + vmin = floor(vmin); - exif_put_double(ifd_nr, tag_id, 0, (double)vint); - exif_put_double(ifd_nr, tag_id, 1, (double)vmin); - exif_put_double(ifd_nr, tag_id, 2, (double)vsec); + exif_put_double(ifd_nr, tag_id, 0, (double)vint); + exif_put_double(ifd_nr, tag_id, 1, (double)vmin); + exif_put_double(ifd_nr, tag_id, 2, (double)vsec); } static void exif_put_long(const int ifd_nr, const int tag_id, const int index, const gbint32 val) { - exif_put_value(ifd_nr, tag_id, EXIF_TYPE_LONG, 1, index, &val); + exif_put_value(ifd_nr, tag_id, EXIF_TYPE_LONG, 1, index, &val); } static void exif_remove_tag(const int ifd_nr, const int tag_id) { - exif_put_value(ifd_nr, tag_id, EXIF_TYPE_BYTE, 0, 0, NULL); + exif_put_value(ifd_nr, tag_id, EXIF_TYPE_BYTE, 0, 0, NULL); } static void -exif_find_wpt_by_time(const waypoint *wpt) +exif_find_wpt_by_time(const waypoint* wpt) { - if (wpt->creation_time <= 0) return; - - if (exif_wpt_ref == NULL) exif_wpt_ref = wpt; - else if (abs(exif_time_ref - wpt->creation_time) < abs(exif_time_ref - exif_wpt_ref->creation_time)) - exif_wpt_ref = wpt; + if (wpt->creation_time <= 0) { + return; + } + + if (exif_wpt_ref == NULL) { + exif_wpt_ref = wpt; + } else if (abs(exif_time_ref - wpt->creation_time) < abs(exif_time_ref - exif_wpt_ref->creation_time)) { + exif_wpt_ref = wpt; + } } static void -exif_find_wpt_by_name(const waypoint *wpt) +exif_find_wpt_by_name(const waypoint* wpt) { - if (exif_wpt_ref != NULL) - return; - else if ((wpt->shortname != NULL) && (case_ignore_strcmp(wpt->shortname, opt_name) == 0)) - exif_wpt_ref = wpt; + if (exif_wpt_ref != NULL) { + return; + } else if ((wpt->shortname != NULL) && (case_ignore_strcmp(wpt->shortname, opt_name) == 0)) { + exif_wpt_ref = wpt; + } } static int -exif_sort_tags_cb(const queue *A, const queue *B) +exif_sort_tags_cb(const queue* A, const queue* B) { - exif_tag_t *ta = (exif_tag_t *)A; - exif_tag_t *tb = (exif_tag_t *)B; + exif_tag_t* ta = (exif_tag_t*)A; + exif_tag_t* tb = (exif_tag_t*)B; - return ta->id - tb->id; + return ta->id - tb->id; } static int -exif_sort_ifds_cb(const queue *A, const queue *B) +exif_sort_ifds_cb(const queue* A, const queue* B) { - exif_ifd_t *ia = (exif_ifd_t *)A; - exif_ifd_t *ib = (exif_ifd_t *)B; + exif_ifd_t* ia = (exif_ifd_t*)A; + exif_ifd_t* ib = (exif_ifd_t*)B; - return ia->nr - ib->nr; + return ia->nr - ib->nr; } static void -exif_write_value(exif_tag_t *tag, gbfile *fout) +exif_write_value(exif_tag_t* tag, gbfile* fout) { - if (tag->size > 4) gbfputuint32(tag->value, fout); /* offset to data */ - else { - char *data = tag->data; - - if BYTE_TYPE(tag->type) gbfwrite(data, 4, 1, fout); - else if WORD_TYPE(tag->type) { - gbfputuint16(*(gbuint16 *)data, fout); - gbfputuint16(*(gbuint16 *)(data+2), fout); - } - else if LONG_TYPE(tag->type) gbfputuint32(*(gbuint32 *)data, fout); - else if (tag->type == EXIF_TYPE_FLOAT) gbfputflt(*(float *)data, fout); - else fatal(MYNAME ": Unknown data type %d!\n", tag->type); - } + if (tag->size > 4) { + gbfputuint32(tag->value, fout); /* offset to data */ + } else { + char* data = (char*) tag->data; + + if BYTE_TYPE(tag->type) { + gbfwrite(data, 4, 1, fout); + } else if WORD_TYPE(tag->type) { + gbfputuint16(*(gbuint16*)data, fout); + gbfputuint16(*(gbuint16*)(data+2), fout); + } else if LONG_TYPE(tag->type) { + gbfputuint32(*(gbuint32*)data, fout); + } else if (tag->type == EXIF_TYPE_FLOAT) { + gbfputflt(*(float*)data, fout); + } else { + fatal(MYNAME ": Unknown data type %d!\n", tag->type); + } + } } static void -exif_write_ifd(const exif_ifd_t *ifd, const char next, gbfile *fout) +exif_write_ifd(const exif_ifd_t* ifd, const char next, gbfile* fout) { - gbsize_t offs; - queue *elem, *tmp; - - gbfputuint16(ifd->count, fout); - offs = gbftell(fout) + (ifd->count * 12) + 4; - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - - gbfputuint16(tag->id, fout); - gbfputuint16(tag->type, fout); - gbfputuint32(tag->count, fout); - if (tag->size > 4) { - tag->value = offs; - offs += tag->size; - if (offs & 1) offs++; - gbfputuint32(tag->value, fout); - } - else exif_write_value(tag, fout); - } - - if (next) gbfputuint32(offs, fout); - else gbfputuint32(0, fout); - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - - if (tag->size > 4) { - gbuint16 i; - char *ptr = tag->data; - - if BYTE_TYPE(tag->type) gbfwrite(tag->data, tag->size, 1, fout); - else for (i = 0; i < tag->count; i++) { - switch(tag->type) { - case EXIF_TYPE_SHORT: - case EXIF_TYPE_SSHORT: - gbfputuint16(*(gbint16 *)ptr, fout); - break; - case EXIF_TYPE_LONG: - case EXIF_TYPE_SLONG: - case EXIF_TYPE_IFD: - gbfputuint32(*(gbint32 *)ptr, fout); - break; - case EXIF_TYPE_RAT: - case EXIF_TYPE_SRAT: - gbfputuint32(*(gbint32 *)ptr, fout); - gbfputuint32(*(gbint32 *)(ptr+4), fout); - break; - case EXIF_TYPE_FLOAT: - gbfputflt(*(float *)ptr, fout); - break; - case EXIF_TYPE_DOUBLE: - gbfputdbl(*(double *)ptr, fout); - break; - default: - gbfwrite(ptr, exif_type_size(tag->type), 1, fin); - break; - } - ptr += (tag->size / tag->count); - } - if (gbftell(fout) & 1) gbfputc(0, fout); - } - } + gbsize_t offs; + queue* elem, *tmp; + + gbfputuint16(ifd->count, fout); + offs = gbftell(fout) + (ifd->count * 12) + 4; + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t* tag = (exif_tag_t*)elem; + + gbfputuint16(tag->id, fout); + gbfputuint16(tag->type, fout); + gbfputuint32(tag->count, fout); + if (tag->size > 4) { + tag->value = offs; + offs += tag->size; + if (offs & 1) { + offs++; + } + gbfputuint32(tag->value, fout); + } else { + exif_write_value(tag, fout); + } + } + + if (next) { + gbfputuint32(offs, fout); + } else { + gbfputuint32(0, fout); + } + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t* tag = (exif_tag_t*)elem; + + if (tag->size > 4) { + gbuint16 i; + char* ptr = (char*) tag->data; + + if BYTE_TYPE(tag->type) { + gbfwrite(tag->data, tag->size, 1, fout); + } else for (i = 0; i < tag->count; i++) { + switch (tag->type) { + case EXIF_TYPE_SHORT: + case EXIF_TYPE_SSHORT: + gbfputuint16(*(gbint16*)ptr, fout); + break; + case EXIF_TYPE_LONG: + case EXIF_TYPE_SLONG: + case EXIF_TYPE_IFD: + gbfputuint32(*(gbint32*)ptr, fout); + break; + case EXIF_TYPE_RAT: + case EXIF_TYPE_SRAT: + gbfputuint32(*(gbint32*)ptr, fout); + gbfputuint32(*(gbint32*)(ptr+4), fout); + break; + case EXIF_TYPE_FLOAT: + gbfputflt(*(float*)ptr, fout); + break; + case EXIF_TYPE_DOUBLE: + gbfputdbl(*(double*)ptr, fout); + break; + default: + gbfwrite(ptr, exif_type_size(tag->type), 1, fin); + break; + } + ptr += (tag->size / tag->count); + } + if (gbftell(fout) & 1) { + gbfputc(0, fout); + } + } + } } static void exif_write_apps(void) { - queue *e0, *t0; - - gbfputuint16(0xFFD8, fout); - - QUEUE_FOR_EACH(&exif_apps, e0, t0) { - exif_app_t *app = (exif_app_t *)e0; - - gbfputuint16(app->marker, fout); - - if (app == exif_app) { - queue *e1, *t1; - gbuint16 len = 8; - gbfile *ftmp; - exif_tag_t *tag; - - exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, 0); - exif_put_long(GPS_IFD, GPS_IFD_TAG_VERSION, 0, 2); - - sortqueue(&exif_app->ifds, exif_sort_ifds_cb); - - QUEUE_FOR_EACH(&app->ifds, e1, t1) { - exif_ifd_t *ifd = (exif_ifd_t *)e1; - - if (ifd->nr == GPS_IFD) exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, len); - else if (ifd->nr == EXIF_IFD) exif_put_long(IFD0, IFD0_TAG_EXIF_IFD_OFFS, 0, len); - else if (ifd->nr == INTER_IFD) exif_put_long(EXIF_IFD, EXIF_IFD_TAG_INTER_IFD_OFFS, 0, len); - - len += exif_ifd_size(ifd); - } - - len += 4; /* DWORD(0) after last ifd */ - - if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_OFFS))) - exif_put_long(IFD1, IFD1_TAG_JPEG_OFFS, 0, len); - - QUEUE_FOR_EACH(&app->ifds, e1, t1) { - exif_ifd_t *ifd = (exif_ifd_t *)e1; - sortqueue(&ifd->tags, exif_sort_tags_cb); - } - - ftmp = gbfopen_be(NULL, "wb", MYNAME); - ftmp->big_endian = app->fcache->big_endian; - - gbfwrite((ftmp->big_endian) ? "MM" : "II", 2, 1, ftmp); - gbfputuint16(0x2A, ftmp); - gbfputuint32(0x08, ftmp); /* offset to first IFD */ - - QUEUE_FOR_EACH(&app->ifds, e1, t1) { - exif_ifd_t *ifd = (exif_ifd_t *)e1; - exif_ifd_t *ifd_next = (exif_ifd_t *)t1; - char next; - - if ((ifd->nr == IFD0) && (ifd_next->nr == IFD1)) next = 1; - else next = 0; - - exif_write_ifd(ifd, next, ftmp); - len = gbftell(ftmp); - } - - gbfputuint32(0, ftmp); /* DWORD(0) after last ifd */ - - if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_OFFS))) { - gbsize_t offs = tag->origin; - if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_SIZE))) { - gbfseek(app->fexif, offs, SEEK_SET); - gbfcopyfrom(ftmp, app->fexif, tag->value); - } - } - - len = gbftell(ftmp); - gbfrewind(ftmp); - gbfputuint16(len + 8, fout); - gbfwrite("Exif\0\0", 6, 1, fout); - gbfcopyfrom(fout, ftmp, len); - - gbfclose(ftmp); - } - else { - gbfputuint16(app->len, fout); - gbfrewind(app->fcache); - gbfcopyfrom(fout, app->fcache, 0x7FFFFFFF); - } - } + queue* e0, *t0; + + gbfputuint16(0xFFD8, fout); + + QUEUE_FOR_EACH(&exif_apps, e0, t0) { + exif_app_t* app = (exif_app_t*)e0; + + gbfputuint16(app->marker, fout); + + if (app == exif_app) { + queue* e1, *t1; + gbuint16 len = 8; + gbfile* ftmp; + exif_tag_t* tag; + + exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, 0); + exif_put_long(GPS_IFD, GPS_IFD_TAG_VERSION, 0, 2); + + sortqueue(&exif_app->ifds, exif_sort_ifds_cb); + + QUEUE_FOR_EACH(&app->ifds, e1, t1) { + exif_ifd_t* ifd = (exif_ifd_t*)e1; + + if (ifd->nr == GPS_IFD) { + exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, len); + } else if (ifd->nr == EXIF_IFD) { + exif_put_long(IFD0, IFD0_TAG_EXIF_IFD_OFFS, 0, len); + } else if (ifd->nr == INTER_IFD) { + exif_put_long(EXIF_IFD, EXIF_IFD_TAG_INTER_IFD_OFFS, 0, len); + } + + len += exif_ifd_size(ifd); + } + + len += 4; /* DWORD(0) after last ifd */ + + if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_OFFS))) { + exif_put_long(IFD1, IFD1_TAG_JPEG_OFFS, 0, len); + } + + QUEUE_FOR_EACH(&app->ifds, e1, t1) { + exif_ifd_t* ifd = (exif_ifd_t*)e1; + sortqueue(&ifd->tags, exif_sort_tags_cb); + } + + ftmp = gbfopen_be(NULL, "wb", MYNAME); + ftmp->big_endian = app->fcache->big_endian; + + gbfwrite((ftmp->big_endian) ? "MM" : "II", 2, 1, ftmp); + gbfputuint16(0x2A, ftmp); + gbfputuint32(0x08, ftmp); /* offset to first IFD */ + + QUEUE_FOR_EACH(&app->ifds, e1, t1) { + exif_ifd_t* ifd = (exif_ifd_t*)e1; + exif_ifd_t* ifd_next = (exif_ifd_t*)t1; + char next; + + if ((ifd->nr == IFD0) && (ifd_next->nr == IFD1)) { + next = 1; + } else { + next = 0; + } + + exif_write_ifd(ifd, next, ftmp); + len = gbftell(ftmp); + } + + gbfputuint32(0, ftmp); /* DWORD(0) after last ifd */ + + if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_OFFS))) { + gbsize_t offs = tag->origin; + if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_SIZE))) { + gbfseek(app->fexif, offs, SEEK_SET); + gbfcopyfrom(ftmp, app->fexif, tag->value); + } + } + + len = gbftell(ftmp); + gbfrewind(ftmp); + gbfputuint16(len + 8, fout); + gbfwrite("Exif\0\0", 6, 1, fout); + gbfcopyfrom(fout, ftmp, len); + + gbfclose(ftmp); + } else { + gbfputuint16(app->len, fout); + gbfrewind(app->fcache); + gbfcopyfrom(fout, app->fcache, 0x7FFFFFFF); + } + } } /******************************************************************************* @@ -1164,215 +1325,228 @@ exif_write_apps(void) *******************************************************************************/ static void -exif_rd_init(const char *fname) +exif_rd_init(const char* fname) { - fin = gbfopen_be(fname, "rb", MYNAME); - QUEUE_INIT(&exif_apps); + fin = gbfopen_be(fname, "rb", MYNAME); + QUEUE_INIT(&exif_apps); } static void exif_rd_deinit(void) { - exif_release_apps(); - gbfclose(fin); + exif_release_apps(); + gbfclose(fin); } static void exif_read(void) { - gbuint16 soi; - waypoint *wpt; + gbuint16 soi; + waypoint* wpt; - soi = gbfgetuint16(fin); - is_fatal(soi != 0xFFD8, MYNAME ": Unknown image file."); /* only jpeg for now */ + soi = gbfgetuint16(fin); + is_fatal(soi != 0xFFD8, MYNAME ": Unknown image file."); /* only jpeg for now */ - exif_app = exif_load_apps(); - is_fatal(exif_app == NULL, MYNAME ": No EXIF header in source file \"%s\".", fin->name); + exif_app = exif_load_apps(); + is_fatal(exif_app == NULL, MYNAME ": No EXIF header in source file \"%s\".", fin->name); - exif_examine_app(exif_app); - wpt = exif_waypt_from_exif_app(exif_app); - if (wpt) waypt_add(wpt); + exif_examine_app(exif_app); + wpt = exif_waypt_from_exif_app(exif_app); + if (wpt) { + waypt_add(wpt); + } } static void -exif_wr_init(const char *fname) +exif_wr_init(const char* fname) { - gbuint16 soi; - char *tmpname; + gbuint16 soi; + char* tmpname; - exif_success = 0; - exif_fout_name = xstrdup(fname); + exif_success = 0; + exif_fout_name = xstrdup(fname); - QUEUE_INIT(&exif_apps); + QUEUE_INIT(&exif_apps); - fin = gbfopen_be(fname, "rb", MYNAME); - is_fatal(fin->is_pipe, MYNAME ": Sorry, this format cannot be used with pipes!"); + fin = gbfopen_be(fname, "rb", MYNAME); + is_fatal(fin->is_pipe, MYNAME ": Sorry, this format cannot be used with pipes!"); - soi = gbfgetuint16(fin); - is_fatal(soi != 0xFFD8, MYNAME ": Unknown image file."); - exif_app = exif_load_apps(); - is_fatal(exif_app == NULL, MYNAME ": No EXIF header found in source file \"%s\".", fin->name); - exif_examine_app(exif_app); - gbfclose(fin); + soi = gbfgetuint16(fin); + is_fatal(soi != 0xFFD8, MYNAME ": Unknown image file."); + exif_app = exif_load_apps(); + is_fatal(exif_app == NULL, MYNAME ": No EXIF header found in source file \"%s\".", fin->name); + exif_examine_app(exif_app); + gbfclose(fin); - exif_time_ref = exif_get_exif_time(exif_app); - if (exif_time_ref == 0) fatal(MYNAME ": No valid timestamp found in picture!\n"); + exif_time_ref = exif_get_exif_time(exif_app); + if (exif_time_ref == 0) { + fatal(MYNAME ": No valid timestamp found in picture!\n"); + } - xasprintf(&tmpname, "%s.jpg", fname); - fout = gbfopen_be(tmpname, "wb", MYNAME); - xfree(tmpname); + xasprintf(&tmpname, "%s.jpg", fname); + fout = gbfopen_be(tmpname, "wb", MYNAME); + xfree(tmpname); } static void exif_wr_deinit(void) { - char *tmpname; - - exif_release_apps(); - tmpname = xstrdup(fout->name); - gbfclose(fout); - - if (exif_success) { - if (*opt_overwrite == '1') { - remove(exif_fout_name); - rename(tmpname, exif_fout_name); - } - } - else remove(tmpname); - - xfree(exif_fout_name); - xfree(tmpname); + char* tmpname; + + exif_release_apps(); + tmpname = xstrdup(fout->name); + gbfclose(fout); + + if (exif_success) { + if (*opt_overwrite == '1') { + remove(exif_fout_name); + rename(tmpname, exif_fout_name); + } + } else { + remove(tmpname); + } + + xfree(exif_fout_name); + xfree(tmpname); } static void exif_write(void) { - char alt_ref = 0; - time_t frame; - - exif_wpt_ref = NULL; - - if (opt_name) { - waypt_disp_all(exif_find_wpt_by_name); - if (exif_wpt_ref == NULL) route_disp_all(NULL, NULL, exif_find_wpt_by_name); - if (exif_wpt_ref == NULL) track_disp_all(NULL, NULL, exif_find_wpt_by_name); - if (exif_wpt_ref == NULL) { - warning(MYNAME ": No matching point with name \"%s\" found.\n", opt_name); - } - } - else { - char *str = exif_time_str(exif_time_ref); - - track_disp_all(NULL, NULL, exif_find_wpt_by_time); - route_disp_all(NULL, NULL, exif_find_wpt_by_time); - waypt_disp_all(exif_find_wpt_by_time); - - frame = atoi(opt_frame); - - if (exif_wpt_ref == NULL) - warning(MYNAME ": No point with a valid timestamp found.\n"); - else if (abs(exif_time_ref - exif_wpt_ref->creation_time) > frame) { - warning(MYNAME ": No matching point found for image date %s!\n", str); - if (exif_wpt_ref != NULL) { - char *str = exif_time_str(exif_wpt_ref->creation_time); - warning(MYNAME ": Best is from %s, %d second(s) away.\n", - str, abs(exif_time_ref - exif_wpt_ref->creation_time)); - xfree(str); - } - exif_wpt_ref = NULL; - } - xfree(str); - } - - if (exif_wpt_ref != NULL) { - const waypoint *wpt = exif_wpt_ref; - - exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, 0); - exif_put_long(GPS_IFD, GPS_IFD_TAG_VERSION, 0, 2); - exif_put_str(GPS_IFD, GPS_IFD_TAG_DATUM, "WGS-84"); - - exif_put_str(GPS_IFD, GPS_IFD_TAG_LATREF, wpt->latitude < 0 ? "S" : "N"); - exif_put_coord(GPS_IFD, GPS_IFD_TAG_LAT, fabs(wpt->latitude)); - exif_put_str(GPS_IFD, GPS_IFD_TAG_LONREF, wpt->longitude < 0 ? "W" : "E"); - exif_put_coord(GPS_IFD, GPS_IFD_TAG_LON, fabs(wpt->longitude)); - - if (wpt->altitude == unknown_alt) { - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_ALT); - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_ALTREF); - } - else { - exif_put_value(GPS_IFD, GPS_IFD_TAG_ALTREF, EXIF_TYPE_BYTE, 1, 0, &alt_ref); - exif_put_double(GPS_IFD, GPS_IFD_TAG_ALT, 0, wpt->altitude); - } - - if (wpt->creation_time) { - struct tm tm; - char buf[32]; - - tm = *gmtime(&wpt->creation_time); - tm.tm_year += 1900; - tm.tm_mon += 1; - - exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 0, tm.tm_hour); - exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 1, tm.tm_min); - exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 2, tm.tm_sec); - - snprintf(buf, sizeof(buf), "%04d:%02d:%02d", tm.tm_year, tm.tm_mon, tm.tm_mday); - exif_put_str(GPS_IFD, GPS_IFD_TAG_DATESTAMP, buf); - } - else { - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_TIMESTAMP); - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_DATESTAMP); - } - - if (wpt->sat > 0) { - char buf[16]; - snprintf(buf, sizeof(buf), "%d", wpt->sat); - exif_put_str(GPS_IFD, GPS_IFD_TAG_SAT, buf); - } - else exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SAT); - - if (wpt->fix == fix_2d) exif_put_str(GPS_IFD, GPS_IFD_TAG_MODE, "2"); - else if (wpt->fix == fix_3d) exif_put_str(GPS_IFD, GPS_IFD_TAG_MODE, "3"); - else exif_remove_tag(GPS_IFD, GPS_IFD_TAG_MODE); - - if (wpt->hdop > 0) exif_put_double(GPS_IFD, GPS_IFD_TAG_DOP, 0, wpt->hdop); - else exif_remove_tag(GPS_IFD, GPS_IFD_TAG_DOP); - - if WAYPT_HAS(wpt, speed) { - exif_put_str(GPS_IFD, GPS_IFD_TAG_SPEEDREF, "K"); - exif_put_double(GPS_IFD, GPS_IFD_TAG_SPEED, 0, MPS_TO_KPH(wpt->speed)); - } - else { - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SPEEDREF); - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SPEED); - } - - exif_write_apps(); /* Success, write the new file */ - - exif_success = 1; - } + char alt_ref = 0; + time_t frame; + + exif_wpt_ref = NULL; + + if (opt_name) { + waypt_disp_all(exif_find_wpt_by_name); + if (exif_wpt_ref == NULL) { + route_disp_all(NULL, NULL, exif_find_wpt_by_name); + } + if (exif_wpt_ref == NULL) { + track_disp_all(NULL, NULL, exif_find_wpt_by_name); + } + if (exif_wpt_ref == NULL) { + warning(MYNAME ": No matching point with name \"%s\" found.\n", opt_name); + } + } else { + char* str = exif_time_str(exif_time_ref); + + track_disp_all(NULL, NULL, exif_find_wpt_by_time); + route_disp_all(NULL, NULL, exif_find_wpt_by_time); + waypt_disp_all(exif_find_wpt_by_time); + + frame = atoi(opt_frame); + + if (exif_wpt_ref == NULL) { + warning(MYNAME ": No point with a valid timestamp found.\n"); + } else if (abs(exif_time_ref - exif_wpt_ref->creation_time) > frame) { + warning(MYNAME ": No matching point found for image date %s!\n", str); + if (exif_wpt_ref != NULL) { + char* str = exif_time_str(exif_wpt_ref->creation_time); + warning(MYNAME ": Best is from %s, %d second(s) away.\n", + str, abs(exif_time_ref - exif_wpt_ref->creation_time)); + xfree(str); + } + exif_wpt_ref = NULL; + } + xfree(str); + } + + if (exif_wpt_ref != NULL) { + const waypoint* wpt = exif_wpt_ref; + + exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, 0); + exif_put_long(GPS_IFD, GPS_IFD_TAG_VERSION, 0, 2); + exif_put_str(GPS_IFD, GPS_IFD_TAG_DATUM, "WGS-84"); + + exif_put_str(GPS_IFD, GPS_IFD_TAG_LATREF, wpt->latitude < 0 ? "S" : "N"); + exif_put_coord(GPS_IFD, GPS_IFD_TAG_LAT, fabs(wpt->latitude)); + exif_put_str(GPS_IFD, GPS_IFD_TAG_LONREF, wpt->longitude < 0 ? "W" : "E"); + exif_put_coord(GPS_IFD, GPS_IFD_TAG_LON, fabs(wpt->longitude)); + + if (wpt->altitude == unknown_alt) { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_ALT); + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_ALTREF); + } else { + exif_put_value(GPS_IFD, GPS_IFD_TAG_ALTREF, EXIF_TYPE_BYTE, 1, 0, &alt_ref); + exif_put_double(GPS_IFD, GPS_IFD_TAG_ALT, 0, wpt->altitude); + } + + if (wpt->creation_time) { + struct tm tm; + char buf[32]; + + tm = *gmtime(&wpt->creation_time); + tm.tm_year += 1900; + tm.tm_mon += 1; + + exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 0, tm.tm_hour); + exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 1, tm.tm_min); + exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 2, tm.tm_sec); + + snprintf(buf, sizeof(buf), "%04d:%02d:%02d", tm.tm_year, tm.tm_mon, tm.tm_mday); + exif_put_str(GPS_IFD, GPS_IFD_TAG_DATESTAMP, buf); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_TIMESTAMP); + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_DATESTAMP); + } + + if (wpt->sat > 0) { + char buf[16]; + snprintf(buf, sizeof(buf), "%d", wpt->sat); + exif_put_str(GPS_IFD, GPS_IFD_TAG_SAT, buf); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SAT); + } + + if (wpt->fix == fix_2d) { + exif_put_str(GPS_IFD, GPS_IFD_TAG_MODE, "2"); + } else if (wpt->fix == fix_3d) { + exif_put_str(GPS_IFD, GPS_IFD_TAG_MODE, "3"); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_MODE); + } + + if (wpt->hdop > 0) { + exif_put_double(GPS_IFD, GPS_IFD_TAG_DOP, 0, wpt->hdop); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_DOP); + } + + if WAYPT_HAS(wpt, speed) { + exif_put_str(GPS_IFD, GPS_IFD_TAG_SPEEDREF, "K"); + exif_put_double(GPS_IFD, GPS_IFD_TAG_SPEED, 0, MPS_TO_KPH(wpt->speed)); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SPEEDREF); + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SPEED); + } + + exif_write_apps(); /* Success, write the new file */ + + exif_success = 1; + } } /**************************************************************************/ ff_vecs_t exif_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - exif_rd_init, - exif_wr_init, - exif_rd_deinit, - exif_wr_deinit, - exif_read, - exif_write, - NULL, - exif_args, - CET_CHARSET_UTF8, 0 + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + exif_rd_init, + exif_wr_init, + exif_rd_deinit, + exif_wr_deinit, + exif_read, + exif_write, + NULL, + exif_args, + CET_CHARSET_UTF8, 0 }; /**************************************************************************/ diff --git a/gpsbabel/explorist_ini.c b/gpsbabel/explorist_ini.c new file mode 100644 index 000000000..7c06b34d9 --- /dev/null +++ b/gpsbabel/explorist_ini.c @@ -0,0 +1,74 @@ +#include "defs.h" +#include "inifile.h" +#include "explorist_ini.h" + +static inifile_t* inifile; +static const char myname[] = "explorist"; + +const char* +explorist_read_value(const char* section, const char* key) +{ + return inifile_readstr(inifile, section, key); +} + +static mag_info* +explorist_ini_try(const char* path) +{ + mag_info* info = NULL; + char* inipath; + char* s; + + xasprintf(&inipath, "%s/%s", path, "APP/Atlas.ini"); + inifile = inifile_init(inipath, myname); + if (!inifile) { + xfree(inipath); + return NULL; + } + + info = (mag_info*) xmalloc(sizeof(mag_info)); + info->geo_path = NULL; + info->track_path = NULL; + info->waypoint_path = NULL; + + s = xstrdup(inifile_readstr(inifile, "UGDS", "WpFolder")); + if (s) { + s = gstrsub(s, "\\", "/"); + xasprintf(&info->waypoint_path, "%s/%s", path, s); + } + s = xstrdup(inifile_readstr(inifile, "UGDS", "GcFolder")); + if (s) { + s = gstrsub(s, "\\", "/"); + xasprintf(&info->geo_path, "%s/%s", path, s); + } + s = xstrdup(inifile_readstr(inifile, "UGDS", "TrkFolder")); + if (s) { + s = gstrsub(s, "\\", "/"); + xasprintf(&info->track_path, "%s/%s", path, s); + } + + inifile_done(inifile); + xfree(inipath); + return info; +} + +mag_info* +explorist_ini_get(const char** dirlist) +{ + mag_info* r = NULL; + while (dirlist && *dirlist) { + r = explorist_ini_try(*dirlist); + if (r) { + return r; + } + } + return r; +} + +void +explorist_ini_done(mag_info* info) +{ + xfree(info->geo_path); + xfree(info->track_path); + xfree(info->waypoint_path); + xfree(info); +} diff --git a/gpsbabel/explorist_ini.h b/gpsbabel/explorist_ini.h new file mode 100644 index 000000000..06ce09b2d --- /dev/null +++ b/gpsbabel/explorist_ini.h @@ -0,0 +1,12 @@ + +/* + * Interesting traits of the device from the *.ini files. + */ +typedef struct { + char* geo_path; + char* track_path; + char* waypoint_path; +} mag_info; + +mag_info* explorist_ini_get(const char** directory_list); +void explorist_ini_done(mag_info* info); diff --git a/gpsbabel/fatal.c b/gpsbabel/fatal.c index 30275f474..9e5ccebd6 100644 --- a/gpsbabel/fatal.c +++ b/gpsbabel/fatal.c @@ -21,21 +21,21 @@ #include "defs.h" void -fatal(const char *fmt, ...) +fatal(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); } void -warning(const char *fmt, ...) +warning(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); } diff --git a/gpsbabel/filter_skeleton.c b/gpsbabel/filter_skeleton.c index 8c5651af7..0066f8943 100644 --- a/gpsbabel/filter_skeleton.c +++ b/gpsbabel/filter_skeleton.c @@ -1,14 +1,15 @@ /* - Filter skeleton: - - Simply copy this file to .c and - rename all filter_skeleton tokens to . Replace + Filter skeleton: + + Simply copy this file to .c and + rename all filter_skeleton tokens to . Replace the stupid name and address in the Copyright few lines below. - To active your new filter you have to create a new section in + To active your new filter you have to create a new section in filter_vecs and finally add complying statements to Makefile. Copyright (C) YYYY John Doe, anybody@wherever.com + Copyright (C) 2001-YYYY Robert Lipe, robertlipe@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include "filterdefs.h" #include @@ -34,13 +35,13 @@ #if FILTERS_ENABLED -// Any arg in this list will appear in command line help and will be +// Any arg in this list will appear in command line help and will be // populated for you. static arglist_t filter_skeleton_args[] = { -// {"foo", &fooopt, "The text of the foo option in help", -// "default", ARGYTPE_STRING, ARG_NOMINMAX} , - ARG_TERMINATOR +// {"foo", &fooopt, "The text of the foo option in help", +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR }; /******************************************************************************* @@ -48,17 +49,17 @@ arglist_t filter_skeleton_args[] = { *******************************************************************************/ static void -filter_skeleton_init(const char *args) +filter_skeleton_init(const char* args) { /* Called before filter processing */ - + /* optional. If not needed, delete and replace entry in vecs with NULL */ - + /* This may be used to parse filter options, allocate memory, and do other * housekeeping that should be done before filtering */ } -static void +static void filter_skeleton_process(void) /* this procedure must be present in vecs */ { // Here is how you register callbacks for all waypoints, routes, tracks. @@ -68,12 +69,12 @@ filter_skeleton_process(void) /* this procedure must be present in vecs */ } static void -filter_skeleton_deinit(void) +filter_skeleton_deinit(void) { /* called after filter processing */ - + /* optional. If not needed, delete and replace entry in vecs with NULL */ - + /* This should be used to clean up any memory allocations that are no longer * needed after the filter terminates. */ } @@ -82,12 +83,12 @@ static void filter_skeleton_exit(void) { /* called on program exit */ - + /* optional. If not needed, delete and replace entry in vecs with NULL */ - + /* You should not need this for simple filters, but it may be used to - * clean up memory allocations that must persist from one invocation of - * your filter to the next (for example, the stack in the stack filter.) + * clean up memory allocations that must persist from one invocation of + * your filter to the next (for example, the stack in the stack filter.) * Note that this member will be called even if your filter has not been * used, so it *cannot* assume that _init or _process has been called * previously. */ @@ -96,11 +97,11 @@ filter_skeleton_exit(void) /*******************************************************************************/ filter_vecs_t filter_skeleton_vecs = { - filter_skeleton_init, - filter_skeleton_process, - filter_skeleton_deinit, - filter_skeleton_exit, - filter_skeleton_args + filter_skeleton_init, + filter_skeleton_process, + filter_skeleton_deinit, + filter_skeleton_exit, + filter_skeleton_args }; /*******************************************************************************/ diff --git a/gpsbabel/filter_vecs.c b/gpsbabel/filter_vecs.c index f65d8e12e..41971eb76 100644 --- a/gpsbabel/filter_vecs.c +++ b/gpsbabel/filter_vecs.c @@ -1,6 +1,6 @@ /* Describe vectors containing filter operations. - + Copyright (C) 2002,2004,2005,2006,2007 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -25,11 +25,12 @@ #include "gbversion.h" typedef struct { - filter_vecs_t *vec; - const char *name; - const char *desc; + filter_vecs_t* vec; + const char* name; + const char* desc; } fl_vecs_t; +extern filter_vecs_t bend_vecs; extern filter_vecs_t position_vecs; extern filter_vecs_t radius_vecs; extern filter_vecs_t duplicate_vecs; @@ -50,203 +51,213 @@ extern filter_vecs_t swapdata_vecs; static fl_vecs_t filter_vec_list[] = { #if FILTERS_ENABLED - { - &arcdist_vecs, - "arc", - "Include Only Points Within Distance of Arc", - }, - { - &discard_vecs, - "discard", - "Remove unreliable points with high hdop or vdop" - }, - { - &duplicate_vecs, - "duplicate", - "Remove Duplicates", - }, - { - &interpolatefilt_vecs, - "interpolate", - "Interpolate between trackpoints" - }, - { - &nuke_vecs, - "nuketypes", - "Remove all waypoints, tracks, or routes" - }, - { - &polygon_vecs, - "polygon", - "Include Only Points Inside Polygon", - }, - { - &position_vecs, - "position", - "Remove Points Within Distance", - }, - { - &radius_vecs, - "radius", - "Include Only Points Within Radius", - }, - { - &routesimple_vecs, - "simplify", - "Simplify routes", - }, - { - &sort_vecs, - "sort", - "Rearrange waypoints by resorting", - }, - { - &stackfilt_vecs, - "stack", - "Save and restore waypoint lists" - }, - { - &reverse_route_vecs, - "reverse", - "Reverse stops within routes", - }, - { - &trackfilter_vecs, - "track", - "Manipulate track lists" - }, - { - &transform_vecs, - "transform", - "Transform waypoints into a route, tracks into routes, ..." - }, - { - &height_vecs, - "height", - "Manipulate altitudes" - }, - { - &swapdata_vecs, - "swap", - "Swap latitude and longitude of all loaded points" - }, - + { + &arcdist_vecs, + "arc", + "Include Only Points Within Distance of Arc", + }, + { + &bend_vecs, + "bend", + "Add points before and after bends in routes" + }, + { + &discard_vecs, + "discard", + "Remove unreliable points with high hdop or vdop" + }, + { + &duplicate_vecs, + "duplicate", + "Remove Duplicates", + }, + { + &interpolatefilt_vecs, + "interpolate", + "Interpolate between trackpoints" + }, + { + &nuke_vecs, + "nuketypes", + "Remove all waypoints, tracks, or routes" + }, + { + &polygon_vecs, + "polygon", + "Include Only Points Inside Polygon", + }, + { + &position_vecs, + "position", + "Remove Points Within Distance", + }, + { + &radius_vecs, + "radius", + "Include Only Points Within Radius", + }, + { + &routesimple_vecs, + "simplify", + "Simplify routes", + }, + { + &sort_vecs, + "sort", + "Rearrange waypoints by resorting", + }, + { + &stackfilt_vecs, + "stack", + "Save and restore waypoint lists" + }, + { + &reverse_route_vecs, + "reverse", + "Reverse stops within routes", + }, + { + &trackfilter_vecs, + "track", + "Manipulate track lists" + }, + { + &transform_vecs, + "transform", + "Transform waypoints into a route, tracks into routes, ..." + }, + { + &height_vecs, + "height", + "Manipulate altitudes" + }, + { + &swapdata_vecs, + "swap", + "Swap latitude and longitude of all loaded points" + }, + #elif defined (MINIMAL_FILTERS) - { - &trackfilter_vecs, - "track", - "Manipulate track lists" - }, + { + &trackfilter_vecs, + "track", + "Manipulate track lists" + }, #endif - { - NULL, - NULL, - NULL - } + { + NULL, + NULL, + NULL + } }; -filter_vecs_t * -find_filter_vec(char *const vecname, char **opts) +filter_vecs_t* +find_filter_vec(char* const vecname, char** opts) { - fl_vecs_t *vec = filter_vec_list; - char *v = xstrdup(vecname); - char *svecname = strtok(v, ","); - int found = 0; - - while (vec->vec) { - arglist_t *ap; - char *res; - - if (case_ignore_strcmp(svecname, vec->name)) { - vec++; - continue; - } - - /* step 1: initialize by inifile or default values */ - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++) { - const char *temp; - - temp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); - if (temp == NULL) temp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring); - if (temp == NULL) temp = ap->defaultvalue; - assign_option(vec->name, ap, temp); - } - } - - /* step 2: override settings with command-line values */ - res = strchr(vecname, ','); - if (res) { - *opts = res+1; - - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++){ - char *opt; - - opt = get_option(*opts, ap->argstring); - if ( opt ) { - found = 1; - assign_option(vec->name, ap, opt); - xfree(opt); - } - } - } - } - if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, vec->name); - } - - if (global_opts.debug_level >= 1) - disp_vec_options(vec->name, vec->vec->args); - - xfree(v); - return vec->vec; - - } - xfree(v); - return NULL; + fl_vecs_t* vec = filter_vec_list; + char* v = xstrdup(vecname); + char* svecname = strtok(v, ","); + int found = 0; + + while (vec->vec) { + arglist_t* ap; + char* res; + + if (case_ignore_strcmp(svecname, vec->name)) { + vec++; + continue; + } + + /* step 1: initialize by inifile or default values */ + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + const char* temp; + + temp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + if (temp == NULL) { + temp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring); + } + if (temp == NULL) { + temp = ap->defaultvalue; + } + assign_option(vec->name, ap, temp); + } + } + + /* step 2: override settings with command-line values */ + res = strchr(vecname, ','); + if (res) { + *opts = res+1; + + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + char* opt; + + opt = get_option(*opts, ap->argstring); + if (opt) { + found = 1; + assign_option(vec->name, ap, opt); + xfree(opt); + } + } + } + } + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + } + + if (global_opts.debug_level >= 1) { + disp_vec_options(vec->name, vec->vec->args); + } + + xfree(v); + return vec->vec; + + } + xfree(v); + return NULL; } void -free_filter_vec( filter_vecs_t *fvec ) +free_filter_vec(filter_vecs_t* fvec) { - arglist_t *ap; - - if ( fvec->args ) { - for ( ap = fvec->args; ap->argstring; ap++) { - if (ap->argvalptr) { - xfree(ap->argvalptr); - ap->argvalptr = *ap->argval = NULL; - } - } - } + arglist_t* ap; + + if (fvec->args) { + for (ap = fvec->args; ap->argstring; ap++) { + if (ap->argvalptr) { + xfree(ap->argvalptr); + ap->argvalptr = *ap->argval = NULL; + } + } + } } -void +void init_filter_vecs(void) { - fl_vecs_t *vec = filter_vec_list; - while ( vec->vec ) { - arglist_t *ap; - if ( vec->vec->args ) { - for ( ap = vec->vec->args; ap->argstring; ap++ ) { - ap->argvalptr = NULL; - } - } - vec++; - } + fl_vecs_t* vec = filter_vec_list; + while (vec->vec) { + arglist_t* ap; + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + ap->argvalptr = NULL; + } + } + vec++; + } } -void -exit_filter_vecs( void ) +void +exit_filter_vecs(void) { - fl_vecs_t *vec = filter_vec_list; - while ( vec->vec ) { - if ( vec->vec->f_exit ) { - (vec->vec->f_exit)(); - } - vec++; - } + fl_vecs_t* vec = filter_vec_list; + while (vec->vec) { + if (vec->vec->f_exit) { + (vec->vec->f_exit)(); + } + vec++; + } } /* @@ -256,81 +267,81 @@ exit_filter_vecs( void ) void disp_filter_vecs(void) { - fl_vecs_t *vec; - arglist_t *ap; - - for (vec = filter_vec_list; vec->vec; vec++) { - printf(" %-20.20s %-50.50s\n", - vec->name, vec->desc); - for (ap = vec->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN )) - printf(" %-18.18s %-.50s %s\n", - ap->argstring, ap->helpstring, - (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); - } - } + fl_vecs_t* vec; + arglist_t* ap; + + for (vec = filter_vec_list; vec->vec; vec++) { + printf(" %-20.20s %-50.50s\n", + vec->name, vec->desc); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %-.50s %s\n", + ap->argstring, ap->helpstring, + (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); + } + } } void -disp_filter_vec( const char *vecname ) +disp_filter_vec(const char* vecname) { - fl_vecs_t *vec; - arglist_t *ap; - - for (vec = filter_vec_list; vec->vec; vec++) { - if ( case_ignore_strcmp( vec->name, vecname )) { - continue; - } - printf(" %-20.20s %-50.50s\n", - vec->name, vec->desc); - for (ap = vec->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN )) - printf(" %-18.18s %-.50s %s\n", - ap->argstring, ap->helpstring, - (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); - } - } + fl_vecs_t* vec; + arglist_t* ap; + + for (vec = filter_vec_list; vec->vec; vec++) { + if (case_ignore_strcmp(vec->name, vecname)) { + continue; + } + printf(" %-20.20s %-50.50s\n", + vec->name, vec->desc); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %-.50s %s\n", + ap->argstring, ap->helpstring, + (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); + } + } } static signed int -alpha (const void *a, const void *b) +alpha(const void* a, const void* b) { - const fl_vecs_t *const ap = (const fl_vecs_t*) a; - const fl_vecs_t *const bp = (const fl_vecs_t*) b; + const fl_vecs_t* const ap = (const fl_vecs_t*) a; + const fl_vecs_t* const bp = (const fl_vecs_t*) b; - return case_ignore_strcmp(ap->desc , bp->desc); + return case_ignore_strcmp(ap->desc , bp->desc); } -static -void disp_help_url(const fl_vecs_t *vec, arglist_t *arg) +static +void disp_help_url(const fl_vecs_t* vec, arglist_t* arg) { - printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); - if (arg) { - printf("#fmt_%s_o_%s",vec->name, arg->argstring); - } + printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); + if (arg) { + printf("#fmt_%s_o_%s",vec->name, arg->argstring); + } } static void -disp_v1(const fl_vecs_t *vec) +disp_v1(const fl_vecs_t* vec) { - arglist_t *ap; - - disp_help_url(vec, NULL); - printf("\n"); - for (ap = vec->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN)) { - printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", - vec->name, - ap->argstring, - ap->helpstring, - name_option(ap->argtype), - ap->defaultvalue? ap->defaultvalue : "", - ap->minvalue? ap->minvalue : "", - ap->maxvalue? ap->maxvalue : ""); - disp_help_url(vec, ap); - printf("\n"); - } - } + arglist_t* ap; + + disp_help_url(vec, NULL); + printf("\n"); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) { + printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", + vec->name, + ap->argstring, + ap->helpstring, + name_option(ap->argtype), + ap->defaultvalue? ap->defaultvalue : "", + ap->minvalue? ap->minvalue : "", + ap->maxvalue? ap->maxvalue : ""); + disp_help_url(vec, ap); + printf("\n"); + } + } } /* @@ -341,27 +352,27 @@ disp_v1(const fl_vecs_t *vec) void disp_filters(int version) { - fl_vecs_t *vec; - - qsort(filter_vec_list, - sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1, - sizeof(filter_vec_list[0]), - alpha); - - - switch(version) { - case 0: - case 1: - for (vec = filter_vec_list; vec->vec; vec++) { - if (version == 0) { - printf("%s\t%s\n", vec->name, vec->desc); - } else { - printf("%s\t%s", vec->name, vec->desc); - disp_v1(vec); - } - } - break; - default: - ; - } + fl_vecs_t* vec; + + qsort(filter_vec_list, + sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1, + sizeof(filter_vec_list[0]), + alpha); + + + switch (version) { + case 0: + case 1: + for (vec = filter_vec_list; vec->vec; vec++) { + if (version == 0) { + printf("%s\t%s\n", vec->name, vec->desc); + } else { + printf("%s\t%s", vec->name, vec->desc); + disp_v1(vec); + } + } + break; + default: + ; + } } diff --git a/gpsbabel/filterdefs.h b/gpsbabel/filterdefs.h index a7005ed63..6af9a747f 100644 --- a/gpsbabel/filterdefs.h +++ b/gpsbabel/filterdefs.h @@ -29,18 +29,18 @@ extern queue waypt_head; typedef struct filter_vecs { - filter_init f_init; - filter_process f_process; - filter_deinit f_deinit; - filter_exit f_exit; - arglist_t *args; + filter_init f_init; + filter_process f_process; + filter_deinit f_deinit; + filter_exit f_exit; + arglist_t* args; } filter_vecs_t; -filter_vecs_t * find_filter_vec(char * const, char **); -void free_filter_vec(filter_vecs_t *); +filter_vecs_t* find_filter_vec(char* const, char**); +void free_filter_vec(filter_vecs_t*); void disp_filters(int version); -void disp_filter( const char *vecname ); -void disp_filter_vec( const char *vecname ); +void disp_filter(const char* vecname); +void disp_filter_vec(const char* vecname); void disp_filter_vecs(void); void init_filter_vecs(void); void exit_filter_vecs(void); diff --git a/gpsbabel/format_skeleton.c b/gpsbabel/format_skeleton.c index 82285d916..3c68527f3 100644 --- a/gpsbabel/format_skeleton.c +++ b/gpsbabel/format_skeleton.c @@ -4,21 +4,21 @@ Steps to create a new format. - 1) Copy this file to .c - 2) Rename all format_skeleton tokens to . + 1) Copy this file to .c + 2) Rename all format_skeleton tokens to . 3) Replace the fictional name and address in the Copyright section below. As your work is likely built on the work of others, please retain the original line. 4) Create a new section in vecs.c. 5) Add compilation instructions to Makefile. - 6) Add sample files (it's better when they're created by the "real" - application and not our own output) to reference/ along with - files in a well supported (preferably non-binary) format and + 6) Add sample files (it's better when they're created by the "real" + application and not our own output) to reference/ along with + files in a well supported (preferably non-binary) format and entries in our 'testo' program. This allows users of different OSes and hardware to exercise your module. Copyright (C) YYYY John Doe, anybody@wherever.com - Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + Copyright (C) 2001-YYYY Robert Lipe, robertlipe@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -42,15 +42,15 @@ #define MYNAME "format_skeleton" -// Any arg in this list will appear in command line help and will be +// Any arg in this list will appear in command line help and will be // populated for you. -// Values for ARGTYPE_xxx can be found in defs.h and are used to +// Values for ARGTYPE_xxx can be found in defs.h and are used to // select the type of option. static arglist_t format_skeleton_args[] = { -// {"foo", &fooopt, "The text of the foo option in help", -// "default", ARGYTPE_STRING, ARG_NOMINMAX} , - ARG_TERMINATOR +// {"foo", &fooopt, "The text of the foo option in help", +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR }; /******************************************************************************* @@ -58,12 +58,12 @@ arglist_t format_skeleton_args[] = { *******************************************************************************/ static void -format_skeleton_rd_init(const char *fname) +format_skeleton_rd_init(const char* fname) { // fin = gbfopen(fname, "r", MYNAME); } -static void +static void format_skeleton_rd_deinit(void) { // gbfclose(fin); @@ -88,24 +88,24 @@ format_skeleton_read(void) // populate waypoint // waypt_add(waypoint); // } -// +// // For routes: -// +// // route = route_head_alloc(); // populate struct route_hdr -// route_add_head(route); +// route_add_head(route); // while (have more routepoints) { // waypoint = waypt_new() // populate waypoint // route_add_wpt(route, waypoint) // } -// +// // Tracks are just like routes, except the word "track" replaces "routes". // } static void -format_skeleton_wr_init(const char *fname) +format_skeleton_wr_init(const char* fname) { // fout = gbfopen(fname, "w", MYNAME); } @@ -133,24 +133,24 @@ format_skeleton_exit(void) /* optional */ /**************************************************************************/ // capabilities below means: we can only read and write waypoints -// please change this depending on your new module +// please change this depending on your new module ff_vecs_t format_skeleton_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - format_skeleton_rd_init, - format_skeleton_wr_init, - format_skeleton_rd_deinit, - format_skeleton_wr_deinit, - format_skeleton_read, - format_skeleton_write, - format_skeleton_exit, - format_skeleton_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + format_skeleton_rd_init, + format_skeleton_wr_init, + format_skeleton_rd_deinit, + format_skeleton_wr_deinit, + format_skeleton_read, + format_skeleton_write, + format_skeleton_exit, + format_skeleton_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/formspec.c b/gpsbabel/formspec.c index ce1dbf90b..517143359 100644 --- a/gpsbabel/formspec.c +++ b/gpsbabel/formspec.c @@ -1,6 +1,6 @@ /* Functions to manage the format_specific_data chain - + Copyright (C) 2005 Ron Parker and Robert Lipe. This program is free software; you can redistribute it and/or modify @@ -25,43 +25,47 @@ #include "defs.h" -format_specific_data *fs_chain_copy( format_specific_data *source ) { - format_specific_data *result = NULL; - - format_specific_data **copy = &result; - while ( source ) { - source->copy( (void **)copy, (void *)source ); - /* prevent segfaults from badly-behaved copy functions */ - (*copy)->next = NULL; - copy = &((*copy)->next); - source = source->next; - } - return result; +format_specific_data* fs_chain_copy(format_specific_data* source) +{ + format_specific_data* result = NULL; + + format_specific_data** copy = &result; + while (source) { + source->copy((void**)copy, (void*)source); + /* prevent segfaults from badly-behaved copy functions */ + (*copy)->next = NULL; + copy = &((*copy)->next); + source = source->next; + } + return result; } -void fs_chain_destroy( format_specific_data *chain ) { - format_specific_data *cur = chain; - format_specific_data *next = NULL; - while ( cur ) { - next = cur->next; - cur->destroy( cur ); - cur = next; - } +void fs_chain_destroy(format_specific_data* chain) +{ + format_specific_data* cur = chain; + format_specific_data* next = NULL; + while (cur) { + next = cur->next; + cur->destroy(cur); + cur = next; + } } -format_specific_data *fs_chain_find( format_specific_data *chain, long type ) { - format_specific_data *cur = chain; - while ( cur ) { - if (cur->type == type ) { - return cur; - } - cur = cur->next; - } - return NULL; +format_specific_data* fs_chain_find(format_specific_data* chain, long type) +{ + format_specific_data* cur = chain; + while (cur) { + if (cur->type == type) { + return cur; + } + cur = cur->next; + } + return NULL; } -void fs_chain_add( format_specific_data **chain, format_specific_data *data ) { - data->next = *chain; - *chain = data; +void fs_chain_add(format_specific_data** chain, format_specific_data* data) +{ + data->next = *chain; + *chain = data; } diff --git a/gpsbabel/g7towin.c b/gpsbabel/g7towin.c index 628d5a303..6a31212a5 100644 --- a/gpsbabel/g7towin.c +++ b/gpsbabel/g7towin.c @@ -39,7 +39,7 @@ #define G7T_HEADER "Version 2:G7T" -static gbfile *fin; +static gbfile* fin; static grid_type grid; static int datum; static gpsdata_type mode; @@ -49,7 +49,7 @@ static int event_ct; static arglist_t g7towin_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; #define WAYPT__OFS 0x00000 @@ -70,264 +70,292 @@ arglist_t g7towin_args[] = { #define WPT_cD_OFS 0x0cD00 static void -parse_line(char *buff, int index, const char *delimiter, waypoint *wpt) +parse_line(char* buff, int index, const char* delimiter, waypoint* wpt) { - char *cin; - garmin_fs_p gmsd = GMSD_FIND(wpt); - - while ((cin = csv_lineparse(buff, delimiter, "", index++))) { - - buff = NULL; - cin = lrtrim(cin); - - if ((*cin == '\0') || - (strcmp(cin, "INF") == 0) || - (strcmp(cin, "1e25") == 0) || - (strcmp(cin, "1.0e25") == 0)) continue; - - switch(index) { - - int categories, dyn; - struct tm tm; - char *cerr; - - case TRKPT__OFS + 1: - cin += parse_coordinates(cin, datum, grid, - &wpt->latitude, &wpt->longitude, MYNAME); - while (isspace(*cin)) cin++; - - memset(&tm, 0, sizeof(tm)); - cerr = strptime(cin, "%a %b %d %H:%M:%S %Y", &tm); - if (cerr == NULL) { - fatal(MYNAME ": Unable to convert date (%s)!\n", cin); - } - wpt->creation_time = mkgmtime(&tm); - break; - - case WAYPT__OFS + 1: - wpt->description = xstrdup(cin); - break; - - case WAYPT__OFS + 2: - wpt->icon_descr = gt_find_desc_from_icon_number( - atoi(cin), PCX, &dyn); - wpt->wpt_flags.icon_descr_is_dynamic = dyn; - break; - - case WAYPT__OFS + 4: - if (strcmp(cin, "S+C") == 0) { - GMSD_SET(display, gt_display_mode_symbol_and_comment); - } - else if (strcmp(cin, "S") == 0) { - GMSD_SET(display, gt_display_mode_symbol); - } - else if (strcmp(cin, "S+N") == 0) { - GMSD_SET(display, gt_display_mode_symbol_and_name); - } - break; - - case WPT_cA_OFS + 1: - case WPT_c1_OFS + 1: - if (wpt->shortname) xfree(wpt->shortname); - wpt->shortname = xstrdup(cin); - break; - - case WPT_cA_OFS + 4: - case WPT_c4_OFS + 2: - GMSD_SETSTR(city, cin); - break; - - case WPT_cA_OFS + 5: - case WPT_c4_OFS + 3: - GMSD_SETSTR(state, cin); - break; - - case WPT_cA_OFS + 6: - case WPT_c4_OFS + 4: - GMSD_SETSTR(cc, cin); - break; - - case WPT_cB_OFS + 1: - case WPT_c6_OFS + 2: - GMSD_SETSTR(facility, cin); - break; - - case WPT_cB_OFS + 2: - case WPT_c6_OFS + 3: - GMSD_SETSTR(addr, cin); - break; - - case WPT_cB_OFS + 3: /*cross road */ - case WPT_c6_OFS + 4: - GMSD_SETSTR(cross_road, cin); - break; - - case TRKPT__OFS + 2: /* altitude */ - case WPT_cC_OFS + 1: - case WPT_c5_OFS + 1: - case WPT_c8_OFS + 1: - wpt->altitude = altf * atof(cin); - break; - - case TRKPT__OFS + 3: /* depth */ - case WPT_cC_OFS + 2: - case WPT_c5_OFS + 2: - case WPT_c8_OFS + 2: - WAYPT_SET(wpt, depth, altf * atof(cin)); - break; - - case TRKPT__OFS + 10: /* temperature */ - if (*cin == '|') cin++; /* in track points */ - if (strcmp(cin, "1e25") == 0) break; - if (strcmp(cin, "1.0e25") == 0) break; - /* !!! NO BREAK !!! */ - case WPT_cD_OFS + 1: - case WPT_cB_OFS + 6: - WAYPT_SET(wpt, temperature, atof(cin)); - break; - - case WAYPT__OFS + 6: /* proximity */ - case WPT_cD_OFS + 2: - WAYPT_SET(wpt, proximity, atof(cin)); - break; - - case WPT_cB_OFS + 5: - case WPT_cD_OFS + 3: - categories = atoi(cin); - if (categories != 0) - GMSD_SET(category, atoi(cin)); - break; - + char* cin; + garmin_fs_p gmsd = GMSD_FIND(wpt); + + while ((cin = csv_lineparse(buff, delimiter, "", index++))) { + + buff = NULL; + cin = lrtrim(cin); + + if ((*cin == '\0') || + (strcmp(cin, "INF") == 0) || + (strcmp(cin, "1e25") == 0) || + (strcmp(cin, "1.0e25") == 0)) { + continue; + } + + switch (index) { + + int categories, dyn; + struct tm tm; + char* cerr; + + case TRKPT__OFS + 1: + cin += parse_coordinates(cin, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + while (isspace(*cin)) { + cin++; + } + + memset(&tm, 0, sizeof(tm)); + cerr = strptime(cin, "%a %b %d %H:%M:%S %Y", &tm); + if (cerr == NULL) { + fatal(MYNAME ": Unable to convert date (%s)!\n", cin); + } + wpt->creation_time = mkgmtime(&tm); + break; + + case WAYPT__OFS + 1: + wpt->description = xstrdup(cin); + break; + + case WAYPT__OFS + 2: + wpt->icon_descr = gt_find_desc_from_icon_number( + atoi(cin), PCX, &dyn); + wpt->wpt_flags.icon_descr_is_dynamic = dyn; + break; + + case WAYPT__OFS + 4: + if (strcmp(cin, "S+C") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_comment); + } else if (strcmp(cin, "S") == 0) { + GMSD_SET(display, gt_display_mode_symbol); + } else if (strcmp(cin, "S+N") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_name); + } + break; + + case WPT_cA_OFS + 1: + case WPT_c1_OFS + 1: + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup(cin); + break; + + case WPT_cA_OFS + 4: + case WPT_c4_OFS + 2: + GMSD_SETSTR(city, cin); + break; + + case WPT_cA_OFS + 5: + case WPT_c4_OFS + 3: + GMSD_SETSTR(state, cin); + break; + + case WPT_cA_OFS + 6: + case WPT_c4_OFS + 4: + GMSD_SETSTR(cc, cin); + break; + + case WPT_cB_OFS + 1: + case WPT_c6_OFS + 2: + GMSD_SETSTR(facility, cin); + break; + + case WPT_cB_OFS + 2: + case WPT_c6_OFS + 3: + GMSD_SETSTR(addr, cin); + break; + + case WPT_cB_OFS + 3: /*cross road */ + case WPT_c6_OFS + 4: + GMSD_SETSTR(cross_road, cin); + break; + + case TRKPT__OFS + 2: /* altitude */ + case WPT_cC_OFS + 1: + case WPT_c5_OFS + 1: + case WPT_c8_OFS + 1: + wpt->altitude = altf * atof(cin); + break; + + case TRKPT__OFS + 3: /* depth */ + case WPT_cC_OFS + 2: + case WPT_c5_OFS + 2: + case WPT_c8_OFS + 2: + WAYPT_SET(wpt, depth, altf * atof(cin)); + break; + + case TRKPT__OFS + 10: /* temperature */ + if (*cin == '|') { + cin++; /* in track points */ + } + if (strcmp(cin, "1e25") == 0) { + break; + } + if (strcmp(cin, "1.0e25") == 0) { + break; + } + /* !!! NO BREAK !!! */ + case WPT_cD_OFS + 1: + case WPT_cB_OFS + 6: + WAYPT_SET(wpt, temperature, atof(cin)); + break; + + case WAYPT__OFS + 6: /* proximity */ + case WPT_cD_OFS + 2: + WAYPT_SET(wpt, proximity, atof(cin)); + break; + + case WPT_cB_OFS + 5: + case WPT_cD_OFS + 3: + categories = atoi(cin); + if (categories != 0) { + GMSD_SET(category, atoi(cin)); + } + break; + #if 0 -/* currently unused */ - - case TRKPT__OFS + 5: /* distance from previous point */ - case TRKPT__OFS + 6: /* distance from segment start */ - case TRKPT__OFS + 7: /* distance from start */ - case TRKPT__OFS + 8: /* velocity from previous point */ - case TRKPT__OFS + 9: /* time (in seconds) from previous point */ - break; - - case WAYPT__OFS + 3: /* ignore color */ - break; - - case WAYPT__OFS + 5: /* always '0' */ - break; - - case TRKPT__OFS + 4: - if (case_ignore_strcmp(cin, "FT") == 0) ; - else if (case_ignore_strcmp(cin, "M") == 0) ; - else if (case_ignore_strcmp(cin, "SM") == 0) ; - else if (case_ignore_strcmp(cin, "NM") == 0) ; - else if (case_ignore_strcmp(cin, "KM") == 0) ; - break; - - case WPT_cB_OFS + 4: /* unknown (datatype) */ - break; - - case WPT_cC_OFS + 3: /* waypt_class (always FF) */ - break; - - case WPT_cC_OFS + 4: /* class & subclass */ - case WPT_cC_OFS + 5: - case WPT_cC_OFS + 6: - case WPT_cC_OFS + 7: - case WPT_cC_OFS + 8: - case WPT_cC_OFS + 9: - case WPT_cC_OFS + 10: - case WPT_cC_OFS + 11: - case WPT_cC_OFS + 12: - case WPT_cC_OFS + 13: - case WPT_cC_OFS + 14: - case WPT_cC_OFS + 15: - case WPT_cC_OFS + 16: - case WPT_cC_OFS + 17: - case WPT_cC_OFS + 18: - case WPT_cC_OFS + 19: - case WPT_cC_OFS + 20: - case WPT_cC_OFS + 21: - break; - - case WPT_cC_OFS + 22: - /* distance */ - break; + /* currently unused */ + + case TRKPT__OFS + 5: /* distance from previous point */ + case TRKPT__OFS + 6: /* distance from segment start */ + case TRKPT__OFS + 7: /* distance from start */ + case TRKPT__OFS + 8: /* velocity from previous point */ + case TRKPT__OFS + 9: /* time (in seconds) from previous point */ + break; + + case WAYPT__OFS + 3: /* ignore color */ + break; + + case WAYPT__OFS + 5: /* always '0' */ + break; + + case TRKPT__OFS + 4: + if (case_ignore_strcmp(cin, "FT") == 0) ; + else if (case_ignore_strcmp(cin, "M") == 0) ; + else if (case_ignore_strcmp(cin, "SM") == 0) ; + else if (case_ignore_strcmp(cin, "NM") == 0) ; + else if (case_ignore_strcmp(cin, "KM") == 0) ; + break; + + case WPT_cB_OFS + 4: /* unknown (datatype) */ + break; + + case WPT_cC_OFS + 3: /* waypt_class (always FF) */ + break; + + case WPT_cC_OFS + 4: /* class & subclass */ + case WPT_cC_OFS + 5: + case WPT_cC_OFS + 6: + case WPT_cC_OFS + 7: + case WPT_cC_OFS + 8: + case WPT_cC_OFS + 9: + case WPT_cC_OFS + 10: + case WPT_cC_OFS + 11: + case WPT_cC_OFS + 12: + case WPT_cC_OFS + 13: + case WPT_cC_OFS + 14: + case WPT_cC_OFS + 15: + case WPT_cC_OFS + 16: + case WPT_cC_OFS + 17: + case WPT_cC_OFS + 18: + case WPT_cC_OFS + 19: + case WPT_cC_OFS + 20: + case WPT_cC_OFS + 21: + break; + + case WPT_cC_OFS + 22: + /* distance */ + break; #endif - } - } + } + } } -static waypoint * -parse_waypt(char *buff) +static waypoint* +parse_waypt(char* buff) { - char *cin, *cerr; - int i; - struct tm tm; - waypoint *wpt; - garmin_fs_p gmsd; - - wpt = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - if (gardown) - cin = buff + 6; - else { - /* We've seen waypoints with length of 14 and 15 !!! */ - cin = buff + 15; - while ((cin > buff) && (! isspace(*cin))) cin--; - } - - while (isspace(*cin)) cin--; - if (cin >= buff) - wpt->shortname = xstrndup(buff, cin - buff + 1); - - if (gardown) - buff += 6; - else - buff += 15; - while (isspace(*buff)) buff++; - - buff += parse_coordinates(buff, datum, grid, - &wpt->latitude, &wpt->longitude, MYNAME); - while (isspace(*buff)) buff++; - - memset(&tm, 0, sizeof(tm)); - cerr = strptime(buff, "%a %b %d %H:%M:%S %Y", &tm); - if (cerr == NULL) - fatal(MYNAME ": Unable to convert date (%s)!\n", buff); - wpt->creation_time = mkgmtime(&tm); - - /* go over time stamp */ - i = 5; - while (buff && i) { - i--; - buff = strchr(buff, ' '); - if (buff) buff++; - } - if (gardown && (buff == NULL)) return wpt; - is_fatal((buff == NULL), MYNAME ": Incomplete waypoint line!"); - - while (isspace(*buff)) buff++; - - parse_line(buff, WAYPT__OFS, "^", wpt); - - return wpt; + char* cin, *cerr; + int i; + struct tm tm; + waypoint* wpt; + garmin_fs_p gmsd; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data*) gmsd); + + if (gardown) { + cin = buff + 6; + } else { + /* We've seen waypoints with length of 14 and 15 !!! */ + cin = buff + 15; + while ((cin > buff) && (! isspace(*cin))) { + cin--; + } + } + + while (isspace(*cin)) { + cin--; + } + if (cin >= buff) { + wpt->shortname = xstrndup(buff, cin - buff + 1); + } + + if (gardown) { + buff += 6; + } else { + buff += 15; + } + while (isspace(*buff)) { + buff++; + } + + buff += parse_coordinates(buff, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + while (isspace(*buff)) { + buff++; + } + + memset(&tm, 0, sizeof(tm)); + cerr = strptime(buff, "%a %b %d %H:%M:%S %Y", &tm); + if (cerr == NULL) { + fatal(MYNAME ": Unable to convert date (%s)!\n", buff); + } + wpt->creation_time = mkgmtime(&tm); + + /* go over time stamp */ + i = 5; + while (buff && i) { + i--; + buff = strchr(buff, ' '); + if (buff) { + buff++; + } + } + if (gardown && (buff == NULL)) { + return wpt; + } + is_fatal((buff == NULL), MYNAME ": Incomplete waypoint line!"); + + while (isspace(*buff)) { + buff++; + } + + parse_line(buff, WAYPT__OFS, "^", wpt); + + return wpt; } -static waypoint * -parse_trkpt(char *buff) +static waypoint* +parse_trkpt(char* buff) { - garmin_fs_p gmsd; - waypoint *wpt; - - wpt = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - parse_line(buff, TRKPT__OFS, ";", wpt); - - return wpt; + garmin_fs_p gmsd; + waypoint* wpt; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data*) gmsd); + + parse_line(buff, TRKPT__OFS, ";", wpt); + + return wpt; } /* @@ -335,212 +363,242 @@ parse_trkpt(char *buff) * w'll need a central storage with binding to the module * which has established a list of category names. */ - + static void -parse_categories(char *buff) +parse_categories(char* buff) { - char *cin; - int cat = 0; - - while ((cin = csv_lineparse(buff, ",", "", cat++))) { - gbuint16 cx; - - buff = NULL; - - cin = lrtrim(cin); - if (*cin == 0) continue; - - garmin_fs_convert_category(cin, &cx); - } + char* cin; + int cat = 0; + + while ((cin = csv_lineparse(buff, ",", "", cat++))) { + gbuint16 cx; + + buff = NULL; + + cin = lrtrim(cin); + if (*cin == 0) { + continue; + } + + garmin_fs_convert_category(cin, &cx); + } } /* main functions */ static void -rd_init(const char *fname) +rd_init(const char* fname) { - fin = gbfopen(fname, "rb", MYNAME); - - gardown = 1; - mode = wptdata; - grid = grid_lat_lon_dmm; - datum = DATUM_WGS84; - altf = 1; - event_ct = 0; + fin = gbfopen(fname, "rb", MYNAME); + + gardown = 1; + mode = wptdata; + grid = grid_lat_lon_dmm; + datum = DATUM_WGS84; + altf = 1; + event_ct = 0; } static void rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void data_read(void) { - char *buff; - int line = 0; - waypoint *wpt = NULL; - waypoint *prev = NULL; - route_head *head = NULL; - - while ((buff = gbfgetstr(fin))) { - char *cin = buff; - char *cdata; - - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - cin = lrtrim(buff); - if (!*cin) continue; - - cdata = cin+1; - while (! isspace(*cdata)) cdata++; - while (isspace(*cdata)) cdata++; - if (! *cdata) continue; - - switch(*cin) { - - case '#': /* comment */ - break; - - case 'A': - if (case_ignore_strncmp(cdata, "Meter", 5) == 0) - altf = 1.0; - else if (case_ignore_strncmp(cdata, "Feet", 4) == 0) - altf = FEET_TO_METERS(1.0); - break; - - case 'C': /* categories */ - parse_categories(cdata); - break; - - case 'D': - datum = gt_lookup_datum_index(cdata, MYNAME); - break; - - case 'I': /* event point */ - wpt = waypt_new(); - cdata += parse_coordinates(cdata, datum, grid, - &wpt->latitude, &wpt->longitude, MYNAME); - xasprintf(&wpt->shortname, "Event%d", ++event_ct); - while (isspace(*cdata)) cdata++; - if (*cdata == ';') { - int dyn; - - cdata++; - wpt->icon_descr = gt_find_desc_from_icon_number( - atoi(cdata), PCX, &dyn); - wpt->wpt_flags.icon_descr_is_dynamic = dyn; - } - waypt_add(wpt); - break; - - case 'M': - grid = gt_lookup_grid_type(cdata, MYNAME); - break; - - case 'P': /* proximity waypoint */ - case 'W': /* normal waypoint */ - wpt = parse_waypt(cin + 3); - prev = wpt; - if (wpt) { - if (mode == rtedata) - route_add_wpt(head, wpt); - else - waypt_add(wpt); - } - break; - - case 'c': /* additional lines */ - switch(*(cin+1)) { - int index; - - case 'A': case 'B': - case 'C': case 'D': - - index = WPT_cA_OFS + ((*(cin+1) - 'A') * 256); - parse_line(cdata, index, "|", wpt); - break; - - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': - - index = WPT_c0_OFS + ((*(cin+1) - '0') * 256); - parse_line(cdata, index, ";", wpt); - break; - - case 'L': - waypt_add_url(wpt, xstrdup(cdata), NULL); - break; - - default: - break; - } - break; - - case 'N': /* track log header */ - mode = trkdata; - head = route_head_alloc(); - cdata = strchr(cdata, '-'); - if (cdata) { - while (isspace(*cdata)) cdata++; - if (*cdata) { - char *s; - s = strrchr(cdata, ','); - if (s) { - *s = '\0'; - s = strrchr(cdata, ','); - if (s) { - *s = '\0'; - head->rte_name = xstrdup(cdata); - } - } - } - } - track_add_head(head); - break; - - case 'R': /* route header */ - mode = rtedata; - head = route_head_alloc(); - cdata += 3; /*skip route number */ - if (*cdata) head->rte_name = xstrdup(cdata); - route_add_head(head); - break; - - case 'T': - wpt = parse_trkpt(cdata); - if (wpt) track_add_wpt(head, wpt); - break; - - case 'V': - if (strcmp(cin, G7T_HEADER) != 0) { - fatal(MYNAME ": Invalid version or invalid file!\n"); - } - gardown = 0; - break; - - default: - break; - } - } + char* buff; + int line = 0; + waypoint* wpt = NULL; + waypoint* prev = NULL; + route_head* head = NULL; + + while ((buff = gbfgetstr(fin))) { + char* cin = buff; + char* cdata; + + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + cin = lrtrim(buff); + if (!*cin) { + continue; + } + + cdata = cin+1; + while (! isspace(*cdata)) { + cdata++; + } + while (isspace(*cdata)) { + cdata++; + } + if (! *cdata) { + continue; + } + + switch (*cin) { + + case '#': /* comment */ + break; + + case 'A': + if (case_ignore_strncmp(cdata, "Meter", 5) == 0) { + altf = 1.0; + } else if (case_ignore_strncmp(cdata, "Feet", 4) == 0) { + altf = FEET_TO_METERS(1.0); + } + break; + + case 'C': /* categories */ + parse_categories(cdata); + break; + + case 'D': + datum = gt_lookup_datum_index(cdata, MYNAME); + break; + + case 'I': /* event point */ + wpt = waypt_new(); + cdata += parse_coordinates(cdata, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + xasprintf(&wpt->shortname, "Event%d", ++event_ct); + while (isspace(*cdata)) { + cdata++; + } + if (*cdata == ';') { + int dyn; + + cdata++; + wpt->icon_descr = gt_find_desc_from_icon_number( + atoi(cdata), PCX, &dyn); + wpt->wpt_flags.icon_descr_is_dynamic = dyn; + } + waypt_add(wpt); + break; + + case 'M': + grid = gt_lookup_grid_type(cdata, MYNAME); + break; + + case 'P': /* proximity waypoint */ + case 'W': /* normal waypoint */ + wpt = parse_waypt(cin + 3); + prev = wpt; + if (wpt) { + if (mode == rtedata) { + route_add_wpt(head, wpt); + } else { + waypt_add(wpt); + } + } + break; + + case 'c': /* additional lines */ + switch (*(cin+1)) { + int index; + + case 'A': + case 'B': + case 'C': + case 'D': + + index = WPT_cA_OFS + ((*(cin+1) - 'A') * 256); + parse_line(cdata, index, "|", wpt); + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + + index = WPT_c0_OFS + ((*(cin+1) - '0') * 256); + parse_line(cdata, index, ";", wpt); + break; + + case 'L': + waypt_add_url(wpt, xstrdup(cdata), NULL); + break; + + default: + break; + } + break; + + case 'N': /* track log header */ + mode = trkdata; + head = route_head_alloc(); + cdata = strchr(cdata, '-'); + if (cdata) { + while (isspace(*cdata)) { + cdata++; + } + if (*cdata) { + char* s; + s = strrchr(cdata, ','); + if (s) { + *s = '\0'; + s = strrchr(cdata, ','); + if (s) { + *s = '\0'; + head->rte_name = xstrdup(cdata); + } + } + } + } + track_add_head(head); + break; + + case 'R': /* route header */ + mode = rtedata; + head = route_head_alloc(); + cdata += 3; /*skip route number */ + if (*cdata) { + head->rte_name = xstrdup(cdata); + } + route_add_head(head); + break; + + case 'T': + wpt = parse_trkpt(cdata); + if (wpt) { + track_add_wpt(head, wpt); + } + break; + + case 'V': + if (strcmp(cin, G7T_HEADER) != 0) { + fatal(MYNAME ": Invalid version or invalid file!\n"); + } + gardown = 0; + break; + + default: + break; + } + } } /* --------------------------------------------------------------------------- */ ff_vecs_t g7towin_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_read, ff_cap_read }, - rd_init, - NULL, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - g7towin_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_read }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + g7towin_args, + CET_CHARSET_MS_ANSI, 0 }; #endif /* CSVFMTS_ENABLED */ diff --git a/gpsbabel/garmin.c b/gpsbabel/garmin.c index 73155d5f7..6b5a4f5dc 100644 --- a/gpsbabel/garmin.c +++ b/gpsbabel/garmin.c @@ -1,6 +1,6 @@ /* Jeeps wrapper for Garmin serial protocol. - + Copyright (C) 2002, 2003, 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -30,522 +30,552 @@ #define SOON 1 -#define MYNAME "GARMIN" -static const char *portname; +#define MYNAME "GARMIN" +static const char* portname; static short_handle mkshort_handle; -static GPS_PWay *tx_waylist; -static GPS_PWay *tx_routelist; -static GPS_PWay *cur_tx_routelist_entry; -static GPS_PTrack *tx_tracklist; -static GPS_PTrack *cur_tx_tracklist_entry; +static GPS_PWay* tx_waylist; +static GPS_PWay* tx_routelist; +static GPS_PWay* cur_tx_routelist_entry; +static GPS_PTrack* tx_tracklist; +static GPS_PTrack* cur_tx_tracklist_entry; static int my_track_count = 0; -static char *getposn = NULL; -static char *poweroff = NULL; -static char *eraset = NULL; -static char *resettime = NULL; -static char *snlen = NULL; -static char *snwhiteopt = NULL; -static char *deficon = NULL; -static char *category = NULL; -static char *categorybitsopt = NULL; +static char* getposn = NULL; +static char* poweroff = NULL; +static char* eraset = NULL; +static char* resettime = NULL; +static char* snlen = NULL; +static char* snwhiteopt = NULL; +static char* deficon = NULL; +static char* category = NULL; +static char* categorybitsopt = NULL; static int categorybits; static int receiver_must_upper = 1; -static ff_vecs_t *gpx_vec; +static ff_vecs_t* gpx_vec; #define MILITANT_VALID_WAYPT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" /* Technically, even this is a little loose as spaces arent allowed */ -static const char *valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " "; +static const char* valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " "; static arglist_t garmin_args[] = { - { "snlen", &snlen, "Length of generated shortnames", NULL, - ARGTYPE_INT, "1", NULL }, - { "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "get_posn", &getposn, "Return current position as a waypoint", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "power_off", &poweroff, "Command unit to power itself down", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "erase_t", &eraset, "Erase existing courses when writing new ones", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "resettime", &resettime, "Sync GPS time to computer time", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "category", &category, "Category number to use for written waypoints", - NULL, ARGTYPE_INT, "1", "16"}, - { "bitscategory", &categorybitsopt, "Bitmap of categories", - NULL, ARGTYPE_INT, "1", "65535"}, - ARG_TERMINATOR + { + "snlen", &snlen, "Length of generated shortnames", NULL, + ARGTYPE_INT, "1", NULL + }, + { + "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { + "get_posn", &getposn, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "power_off", &poweroff, "Command unit to power itself down", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "erase_t", &eraset, "Erase existing courses when writing new ones", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "resettime", &resettime, "Sync GPS time to computer time", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "category", &category, "Category number to use for written waypoints", + NULL, ARGTYPE_INT, "1", "16" + }, + { + "bitscategory", &categorybitsopt, "Bitmap of categories", + NULL, ARGTYPE_INT, "1", "65535" + }, + ARG_TERMINATOR }; -static const char * d103_symbol_from_icon_number(unsigned int n); -static int d103_icon_number_from_symbol(const char *s); +static const char* d103_symbol_from_icon_number(unsigned int n); +static int d103_icon_number_from_symbol(const char* s); static void -rw_init(const char *fname) +rw_init(const char* fname) { - int receiver_short_length; - int receiver_must_upper = 1; - char * receiver_charset = NULL; - - if (!mkshort_handle) - mkshort_handle = mkshort_new_handle(); - - if (global_opts.debug_level > 0) { - GPS_Enable_Warning(); - GPS_Enable_User(); - } - if (global_opts.debug_level > 1) { - GPS_Enable_Diagnose(); - } - GPS_Enable_Error(); - - if (poweroff) { - GPS_Command_Off(fname); - return; - } - - /* - * THis is Gross. The B&W Vista sometimes sets its time decades into - * the future with no way to reset it. This apparently can "cure" - * an affected unit. - */ - if (resettime) { - GPS_Command_Send_Time(fname, current_time()); - return; - } - - if (categorybitsopt) { - categorybits = strtol(categorybitsopt, NULL, 0); - } - - if (GPS_Init(fname) < 0) { - fatal(MYNAME ":Can't init %s\n", fname); - } - portname = fname; - - /* - * Grope the unit we're talking to to set setshort_length to - * 20 for the V, - * 10 for Street Pilot, (old) Rhino, 76 - * 6 for the III, 12, emap, and etrex - * Fortunately, getting this "wrong" only results in ugly names - * when we're using the synthesize_shortname path. - */ - receiver_short_length = 10; - - switch ( gps_waypt_type ) /* waypoint type as defined by jeeps */ - { - case 0: - fatal("Garmin unit %d does not support waypoint xfer.", - gps_save_id); - - break; - case 100: /* The GARMIN GPS Interface Specification, */ - case 101: /* says these waypoint types use an ident */ - case 102: /* length of 6. Waypoint types 106, 108 */ - case 103: /* and 109 are all variable length */ - case 104: - case 105: - case 107: - case 150: - case 151: - case 152: - case 154: - case 155: - receiver_short_length = 6; - break; - case 106: /* Waypoint types with variable ident length */ - case 108: /* Need GPSr id to know the actual length */ - case 109: - case 110: - switch ( gps_save_id ) - { - case 130: /* Garmin Etrex (yellow) */ - receiver_short_length = 6; - break; - case 295: /* eTrex (yellow, fw v. 3.30) */ - case 696: /* eTrex HC */ - case 574: /* Geko 201 */ - receiver_short_length = 6; - valid_waypt_chars = - MILITANT_VALID_WAYPT_CHARS " +-"; - setshort_badchars(mkshort_handle, "\"$.,'!"); - break; - - case 155: /* Garmin V */ - case 404: /* SP2720 */ - case 520: /* SP2820 */ - receiver_short_length = 20; - break; - case 382: /* C320 */ - receiver_short_length = 30; - receiver_must_upper = 0; - break; - case 292: /* (60|76)C[S]x series */ - case 421: /* Vista|Legend Cx */ - case 694: /* Legend HCx */ - case 695: /* Vista HC */ - case 786: /* HC model */ - case 957: /* Legend HC */ - receiver_short_length = 14; - snwhiteopt = xstrdup("1"); - receiver_must_upper = 0; - /* This might be 8859-1 */ - receiver_charset = CET_CHARSET_MS_ANSI; - break; - case 291: /* GPSMAP 60CS, probably others */ - case 1095: /* GPS 72H */ - receiver_short_length = 10; - valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " +-"; - setshort_badchars(mkshort_handle, "\"$.,'!"); - break; - case 231: /* Quest */ - case 463: /* Quest 2 */ - receiver_must_upper = 0; - receiver_short_length = 30; - receiver_charset = CET_CHARSET_MS_ANSI; - break; - case 577: // Rino 530HCx Version 2.50 - receiver_must_upper = 0; - receiver_short_length = 14; - break; - case 429: // Streetpilot i3 - receiver_must_upper = 0; - receiver_charset = CET_CHARSET_MS_ANSI; - receiver_short_length = 30; - break; - case 484: // Forerunner 305 - receiver_short_length = 8; - break; - case 260: /* GPSMap 296 */ - default: - break; - } - break; - default: - break; - - } - - // If a user has specified a non-default character set, we'll trust - // them to sort our the wreckage of violating the Garmin protocol and - // ship characters to the device in that character set. - if (global_opts.charset != &cet_cs_vec_utf8) { - receiver_charset = global_opts.charset_name; - } - if (global_opts.debug_level > 0) { - fprintf(stderr, "Waypoint type: %d\n" - "Chosen waypoint length %d\n", - gps_waypt_type, receiver_short_length); - if (gps_category_type) { - fprintf(stderr, "Waypoint category type: %d\n", - gps_category_type); - } - } - - // Allow override of sent character set for internationalized GPSes. - if (global_opts.charset != &cet_cs_vec_utf8) - receiver_charset = xstrdup(global_opts.charset_name); - - /* - * If the user provided a short_length, override the calculated value. - */ - if (snlen) - setshort_length(mkshort_handle, atoi(snlen)); - else - setshort_length(mkshort_handle, receiver_short_length); - - if (snwhiteopt) - setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); - - /* - * Until Garmins documents how to determine valid character space - * for the new models, we just release this safety check manually. - */ - if (receiver_must_upper) { - setshort_goodchars(mkshort_handle, valid_waypt_chars); - } else { - setshort_badchars(mkshort_handle, ""); - } - - setshort_mustupper(mkshort_handle, receiver_must_upper); - - if (receiver_charset) - cet_convert_init(receiver_charset, 1); + int receiver_short_length; + int receiver_must_upper = 1; + const char* receiver_charset = NULL; + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + + if (global_opts.debug_level > 0) { + GPS_Enable_Warning(); + GPS_Enable_User(); + } + if (global_opts.debug_level > 1) { + GPS_Enable_Diagnose(); + } + GPS_Enable_Error(); + + if (poweroff) { + GPS_Command_Off(fname); + return; + } + + /* + * THis is Gross. The B&W Vista sometimes sets its time decades into + * the future with no way to reset it. This apparently can "cure" + * an affected unit. + */ + if (resettime) { + GPS_Command_Send_Time(fname, current_time()); + return; + } + + if (categorybitsopt) { + categorybits = strtol(categorybitsopt, NULL, 0); + } + + if (GPS_Init(fname) < 0) { + fatal(MYNAME ":Can't init %s\n", fname); + } + portname = fname; + + /* + * Grope the unit we're talking to to set setshort_length to + * 20 for the V, + * 10 for Street Pilot, (old) Rhino, 76 + * 6 for the III, 12, emap, and etrex + * Fortunately, getting this "wrong" only results in ugly names + * when we're using the synthesize_shortname path. + */ + receiver_short_length = 10; + + switch (gps_waypt_type) { /* waypoint type as defined by jeeps */ + case 0: + fatal("Garmin unit %d does not support waypoint xfer.", + gps_save_id); + + break; + case 100: /* The GARMIN GPS Interface Specification, */ + case 101: /* says these waypoint types use an ident */ + case 102: /* length of 6. Waypoint types 106, 108 */ + case 103: /* and 109 are all variable length */ + case 104: + case 105: + case 107: + case 150: + case 151: + case 152: + case 154: + case 155: + receiver_short_length = 6; + break; + case 106: /* Waypoint types with variable ident length */ + case 108: /* Need GPSr id to know the actual length */ + case 109: + case 110: + switch (gps_save_id) { + case 130: /* Garmin Etrex (yellow) */ + receiver_short_length = 6; + break; + case 295: /* eTrex (yellow, fw v. 3.30) */ + case 696: /* eTrex HC */ + case 574: /* Geko 201 */ + receiver_short_length = 6; + valid_waypt_chars = + MILITANT_VALID_WAYPT_CHARS " +-"; + setshort_badchars(mkshort_handle, "\"$.,'!"); + break; + + case 155: /* Garmin V */ + case 404: /* SP2720 */ + case 520: /* SP2820 */ + receiver_short_length = 20; + break; + case 382: /* C320 */ + receiver_short_length = 30; + receiver_must_upper = 0; + break; + case 292: /* (60|76)C[S]x series */ + case 421: /* Vista|Legend Cx */ + case 694: /* Legend HCx */ + case 695: /* Vista HC */ + case 786: /* HC model */ + case 957: /* Legend HC */ + receiver_short_length = 14; + snwhiteopt = xstrdup("1"); + receiver_must_upper = 0; + /* This might be 8859-1 */ + receiver_charset = CET_CHARSET_MS_ANSI; + break; + case 291: /* GPSMAP 60CS, probably others */ + case 1095: /* GPS 72H */ + receiver_short_length = 10; + valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " +-"; + setshort_badchars(mkshort_handle, "\"$.,'!"); + break; + case 231: /* Quest */ + case 463: /* Quest 2 */ + receiver_must_upper = 0; + receiver_short_length = 30; + receiver_charset = CET_CHARSET_MS_ANSI; + break; + case 577: // Rino 530HCx Version 2.50 + receiver_must_upper = 0; + receiver_short_length = 14; + break; + case 429: // Streetpilot i3 + receiver_must_upper = 0; + receiver_charset = CET_CHARSET_MS_ANSI; + receiver_short_length = 30; + break; + case 484: // Forerunner 305 + receiver_short_length = 8; + break; + case 260: /* GPSMap 296 */ + default: + break; + } + break; + default: + break; + + } + + // If a user has specified a non-default character set, we'll trust + // them to sort our the wreckage of violating the Garmin protocol and + // ship characters to the device in that character set. + if (global_opts.charset != &cet_cs_vec_utf8) { + receiver_charset = global_opts.charset_name; + } + if (global_opts.debug_level > 0) { + fprintf(stderr, "Waypoint type: %d\n" + "Chosen waypoint length %d\n", + gps_waypt_type, receiver_short_length); + if (gps_category_type) { + fprintf(stderr, "Waypoint category type: %d\n", + gps_category_type); + } + } + + // Allow override of sent character set for internationalized GPSes. + if (global_opts.charset != &cet_cs_vec_utf8) { + receiver_charset = xstrdup(global_opts.charset_name); + } + + /* + * If the user provided a short_length, override the calculated value. + */ + if (snlen) { + setshort_length(mkshort_handle, atoi(snlen)); + } else { + setshort_length(mkshort_handle, receiver_short_length); + } + + if (snwhiteopt) { + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + } + + /* + * Until Garmins documents how to determine valid character space + * for the new models, we just release this safety check manually. + */ + if (receiver_must_upper) { + setshort_goodchars(mkshort_handle, valid_waypt_chars); + } else { + setshort_badchars(mkshort_handle, ""); + } + + setshort_mustupper(mkshort_handle, receiver_must_upper); + + if (receiver_charset) { + cet_convert_init(receiver_charset, 1); + } } static void -rd_init(const char *fname) +rd_init(const char* fname) { - if (setjmp(gdx_jmp_buf)) { - char *vec_opts = NULL; - const gdx_info *gi = gdx_get_info(); - gpx_vec = find_vec("gpx", &vec_opts); - gpx_vec->rd_init(gi->from_device.canon); - } else { - gpx_vec = NULL; - rw_init(fname); - } + if (setjmp(gdx_jmp_buf)) { + char* vec_opts = NULL; + const gdx_info* gi = gdx_get_info(); + gpx_vec = find_vec("gpx", &vec_opts); + gpx_vec->rd_init(gi->from_device.canon); + } else { + gpx_vec = NULL; + rw_init(fname); + } } static void rw_deinit(void) { - if (mkshort_handle) { - mkshort_del_handle(&mkshort_handle); - } + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } } static int -waypt_read_cb(int total_ct, GPS_PWay *way) +waypt_read_cb(int total_ct, GPS_PWay* way) { - static int i; + static int i; - if (global_opts.verbose_status) { - i++; - waypt_status_disp(total_ct, i); - } - return 0; + if (global_opts.verbose_status) { + i++; + waypt_status_disp(total_ct, i); + } + return 0; } static void waypt_read(void) { - int i,n; - GPS_PWay *way = NULL; - - if (getposn) { - waypoint *wpt = waypt_new(); - wpt->latitude = gps_save_lat; - wpt->longitude = gps_save_lon; - wpt->shortname = xstrdup("Position"); - if (gps_save_time) - wpt->creation_time = gps_save_time; - waypt_add(wpt); - return; - } - - if ((n = GPS_Command_Get_Waypoint(portname, &way, waypt_read_cb)) < 0) { - fatal(MYNAME ":Can't get waypoint from %s\n", portname); - } - - for (i = 0; i < n; i++) { - waypoint *wpt_tmp = waypt_new(); - - wpt_tmp->shortname = xstrdup(way[i]->ident); - wpt_tmp->description = xstrdup(way[i]->cmnt); - rtrim(wpt_tmp->shortname); - rtrim(wpt_tmp->description); - wpt_tmp->longitude = way[i]->lon; - wpt_tmp->latitude = way[i]->lat; - if (gps_waypt_type == 103) { - wpt_tmp->icon_descr = d103_symbol_from_icon_number( - way[i]->smbl); - } else { - int dyn = 0; - wpt_tmp->icon_descr = gt_find_desc_from_icon_number( - way[i]->smbl, PCX, &dyn); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = dyn; - } - /* - * If a unit doesn't store altitude info (i.e. a D103) - * gpsmem will default the alt to INT_MAX. Other units - * (I can't recall if it was the V (D109) hor the Vista (D108) - * return INT_MAX+1, contrary to the Garmin protocol doc which - * says they should report 1.0e25. So we'll try to trap - * all the cases here. Yes, libjeeps should probably - * do this and not us... - */ - if ((way[i]->alt == (float) (1U<<31)) || - (way[i]->alt == INT_MAX) || - (way[i]->alt >= (float) 1.0e20) - ) { - wpt_tmp->altitude = unknown_alt; - } else { - wpt_tmp->altitude = way[i]->alt; - } - if (way[i]->time_populated) { - wpt_tmp->creation_time = way[i]->time; - } + int i,n; + GPS_PWay* way = NULL; + + if (getposn) { + waypoint* wpt = waypt_new(); + wpt->latitude = gps_save_lat; + wpt->longitude = gps_save_lon; + wpt->shortname = xstrdup("Position"); + if (gps_save_time) { + wpt->creation_time = gps_save_time; + } + waypt_add(wpt); + return; + } + + if ((n = GPS_Command_Get_Waypoint(portname, &way, waypt_read_cb)) < 0) { + fatal(MYNAME ":Can't get waypoint from %s\n", portname); + } + + for (i = 0; i < n; i++) { + waypoint* wpt_tmp = waypt_new(); + + wpt_tmp->shortname = xstrdup(way[i]->ident); + wpt_tmp->description = xstrdup(way[i]->cmnt); + rtrim(wpt_tmp->shortname); + rtrim(wpt_tmp->description); + wpt_tmp->longitude = way[i]->lon; + wpt_tmp->latitude = way[i]->lat; + if (gps_waypt_type == 103) { + wpt_tmp->icon_descr = d103_symbol_from_icon_number( + way[i]->smbl); + } else { + int dyn = 0; + wpt_tmp->icon_descr = gt_find_desc_from_icon_number( + way[i]->smbl, PCX, &dyn); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = dyn; + } + /* + * If a unit doesn't store altitude info (i.e. a D103) + * gpsmem will default the alt to INT_MAX. Other units + * (I can't recall if it was the V (D109) hor the Vista (D108) + * return INT_MAX+1, contrary to the Garmin protocol doc which + * says they should report 1.0e25. So we'll try to trap + * all the cases here. Yes, libjeeps should probably + * do this and not us... + */ + if ((way[i]->alt == (float)(1U<<31)) || + (way[i]->alt == INT_MAX) || + (way[i]->alt >= (float) 1.0e20) + ) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = way[i]->alt; + } + if (way[i]->time_populated) { + wpt_tmp->creation_time = way[i]->time; + } #if SOON - garmin_fs_garmin_after_read(way[i], wpt_tmp, gps_waypt_type); -#endif - waypt_add(wpt_tmp); - GPS_Way_Del(&way[i]); - } - if (way) { - xfree(way); - } + garmin_fs_garmin_after_read(way[i], wpt_tmp, gps_waypt_type); +#endif + waypt_add(wpt_tmp); + GPS_Way_Del(&way[i]); + } + if (way) { + xfree(way); + } } static int lap_read_nop_cb(int n, struct GPS_SWay** dp) { - return 0; + return 0; } // returns 1 if the waypoint's start_time can be found // in the laps array, 0 otherwise -unsigned int checkWayPointIsAtSplit(waypoint *wpt, GPS_PLap *laps, int nlaps) +unsigned int checkWayPointIsAtSplit(waypoint* wpt, GPS_PLap* laps, int nlaps) { - int result = 0; - - if ((laps != NULL) && (nlaps > 0)) { - int i; - for (i=(nlaps-1); i >= 0; i--) { - GPS_PLap lap = laps[i]; - time_t delta = lap->start_time - wpt->creation_time; - if ((delta >= -1) && (delta <= 1)) { - result = 1; - break; - - // as an optimization this will stop going through - // the lap array when the negative delta gets too - // big. It assumes that laps is sorted by time in - // ascending order (which appears to be the case for - // Forerunners. Don't know about other devices. - } else if (delta < -1) { - break; - } - } + int result = 0; + + if ((laps != NULL) && (nlaps > 0)) { + int i; + for (i=(nlaps-1); i >= 0; i--) { + GPS_PLap lap = laps[i]; + time_t delta = lap->start_time - wpt->creation_time; + if ((delta >= -1) && (delta <= 1)) { + result = 1; + break; + + // as an optimization this will stop going through + // the lap array when the negative delta gets too + // big. It assumes that laps is sorted by time in + // ascending order (which appears to be the case for + // Forerunners. Don't know about other devices. + } else if (delta < -1) { + break; + } } + } - return result; + return result; } static void track_read(void) { - int32 ntracks; - GPS_PTrack *array; - route_head *trk_head = NULL; - int trk_num = 0; - int i; - char *trk_name = ""; - GPS_PLap* laps = NULL; - int nlaps = 0; - int next_is_new_trkseg = 0; - - if (gps_lap_type != -1) { - nlaps = GPS_Command_Get_Lap(portname, &laps, &lap_read_nop_cb); - } - - - ntracks = GPS_Command_Get_Track(portname, &array, waypt_read_cb); - - if ( ntracks <= 0 ) - return; - - for(i = 0; i < ntracks; i++) { - waypoint *wpt; - - /* - * This is probably always in slot zero, but the Garmin - * serial spec says these can appear anywhere. Toss them - * out so we don't treat it as an extraneous trackpoint. - */ - if (array[i]->ishdr) { - trk_name = array[i]->trk_ident; - if (!trk_name) - trk_name = ""; - } - - if (trk_head == NULL || array[i]->ishdr) { - trk_head = route_head_alloc(); - trk_head->rte_num = trk_num; - trk_head->rte_name = xstrdup(trk_name); - trk_num++; - track_add_head(trk_head); - } - - /* Need to do this here because fitness devices set tnew - * on a trackpoint without lat/lon. - */ - if (array[i]->tnew) - next_is_new_trkseg = 1; - - if (array[i]->no_latlon || array[i]->ishdr) { - continue; - } - wpt = waypt_new(); - - wpt->longitude = array[i]->lon; - wpt->latitude = array[i]->lat; - wpt->altitude = array[i]->alt; - wpt->heartrate = array[i]->heartrate; - wpt->cadence = array[i]->cadence; - wpt->shortname = xstrdup(array[i]->trk_ident); - wpt->creation_time = array[i]->Time; - wpt->wpt_flags.is_split = checkWayPointIsAtSplit(wpt, laps, - nlaps); - wpt->wpt_flags.new_trkseg = next_is_new_trkseg; - next_is_new_trkseg = 0; - - if (array[i]->dpth < 1.0e25f) - WAYPT_SET(wpt, depth, array[i]->dpth); - if (array[i]->temperature_populated) - WAYPT_SET(wpt, temperature, array[i]->temperature); - - track_add_wpt(trk_head, wpt); - } - - while(ntracks) { - GPS_Track_Del(&array[--ntracks]); - } - xfree(array); + int32 ntracks; + GPS_PTrack* array; + route_head* trk_head = NULL; + int trk_num = 0; + int i; + char* trk_name = ""; + GPS_PLap* laps = NULL; + int nlaps = 0; + int next_is_new_trkseg = 0; + + if (gps_lap_type != -1) { + nlaps = GPS_Command_Get_Lap(portname, &laps, &lap_read_nop_cb); + } + + + ntracks = GPS_Command_Get_Track(portname, &array, waypt_read_cb); + + if (ntracks <= 0) { + return; + } + + for (i = 0; i < ntracks; i++) { + waypoint* wpt; + + /* + * This is probably always in slot zero, but the Garmin + * serial spec says these can appear anywhere. Toss them + * out so we don't treat it as an extraneous trackpoint. + */ + if (array[i]->ishdr) { + trk_name = array[i]->trk_ident; + if (!trk_name) { + trk_name = ""; + } + } + + if (trk_head == NULL || array[i]->ishdr) { + trk_head = route_head_alloc(); + trk_head->rte_num = trk_num; + trk_head->rte_name = xstrdup(trk_name); + trk_num++; + track_add_head(trk_head); + } + + /* Need to do this here because fitness devices set tnew + * on a trackpoint without lat/lon. + */ + if (array[i]->tnew) { + next_is_new_trkseg = 1; + } + + if (array[i]->no_latlon || array[i]->ishdr) { + continue; + } + wpt = waypt_new(); + + wpt->longitude = array[i]->lon; + wpt->latitude = array[i]->lat; + wpt->altitude = array[i]->alt; + wpt->heartrate = array[i]->heartrate; + wpt->cadence = array[i]->cadence; + wpt->shortname = xstrdup(array[i]->trk_ident); + wpt->creation_time = array[i]->Time; + wpt->wpt_flags.is_split = checkWayPointIsAtSplit(wpt, laps, + nlaps); + wpt->wpt_flags.new_trkseg = next_is_new_trkseg; + next_is_new_trkseg = 0; + + if (array[i]->dpth < 1.0e25f) { + WAYPT_SET(wpt, depth, array[i]->dpth); + } + if (array[i]->temperature_populated) { + WAYPT_SET(wpt, temperature, array[i]->temperature); + } + + track_add_wpt(trk_head, wpt); + } + + while (ntracks) { + GPS_Track_Del(&array[--ntracks]); + } + xfree(array); } static void route_read(void) { - int32 nroutepts; - int i; - GPS_PWay *array; - /* TODO: Fixes warning but is it right? - * RJL: No, the warning isn't right; GCC's flow analysis is broken. - * still, it's good taste... - */ - route_head *rte_head = NULL; + int32 nroutepts; + int i; + GPS_PWay* array; + /* TODO: Fixes warning but is it right? + * RJL: No, the warning isn't right; GCC's flow analysis is broken. + * still, it's good taste... + */ + route_head* rte_head = NULL; - nroutepts = GPS_Command_Get_Route(portname, &array); + nroutepts = GPS_Command_Get_Route(portname, &array); // fprintf(stderr, "Routes %d\n", (int) nroutepts); #if 1 - for (i = 0; i < nroutepts; i++) { - if (array[i]->isrte) { - char *csrc = NULL; - /* What a horrible API has libjeeps for making this - * my problem. - */ - switch (array[i]->rte_prot) { - case 201: csrc = array[i]->rte_cmnt; break; - case 202: csrc = array[i]->rte_ident; break; - default: break; - } - rte_head = route_head_alloc(); - route_add_head(rte_head); - if (csrc) { - rte_head->rte_name = xstrdup(csrc); - } - } else { - if (array[i]->islink) { - continue; - } else { - waypoint *wpt_tmp = waypt_new(); - wpt_tmp->latitude = array[i]->lat; - wpt_tmp->longitude = array[i]->lon; - wpt_tmp->shortname = array[i]->ident; - route_add_wpt(rte_head, wpt_tmp); - } - } - } + for (i = 0; i < nroutepts; i++) { + if (array[i]->isrte) { + char* csrc = NULL; + /* What a horrible API has libjeeps for making this + * my problem. + */ + switch (array[i]->rte_prot) { + case 201: + csrc = array[i]->rte_cmnt; + break; + case 202: + csrc = array[i]->rte_ident; + break; + default: + break; + } + rte_head = route_head_alloc(); + route_add_head(rte_head); + if (csrc) { + rte_head->rte_name = xstrdup(csrc); + } + } else { + if (array[i]->islink) { + continue; + } else { + waypoint* wpt_tmp = waypt_new(); + wpt_tmp->latitude = array[i]->lat; + wpt_tmp->longitude = array[i]->lon; + wpt_tmp->shortname = array[i]->ident; + route_add_wpt(rte_head, wpt_tmp); + } + } + } #else - GPS_Fmt_Print_Route(array, nroutepts, stderr); + GPS_Fmt_Print_Route(array, nroutepts, stderr); #endif } @@ -555,88 +585,89 @@ static void lap_read_as_track(void) { - int32 ntracks; - GPS_PLap *array; - route_head *trk_head = NULL; - int trk_num = 0; - int index; - int i; - - ntracks = GPS_Command_Get_Lap(portname, &array, waypt_read_cb); - if ( ntracks <= 0 ) - return; - for (i = 0; i < ntracks; i++) { - waypoint *wpt; - if (array[i]->index == -1){ - index=i; - } else { - index=array[i]->index; - index=i; - } - - if ((trk_head == NULL) || (i == 0) || - /* D906 - last track:index is the track index */ - (array[i]->index == -1 && array[i]->track_index != 255) || - /* D10xx - no real separator, use begin/end time to guess */ - (abs(array[i-1]->start_time + array[i]->total_time/100-array[i]->start_time) > 2) - ) { - static struct tm * stmp; - stmp = gmtime(&array[i]->start_time); - trk_head = route_head_alloc(); - /*For D906, we would like to use the track_index in the last packet instead...*/ - trk_head->rte_num = ++trk_num; - trk_head->rte_name = xmalloc(32); - strftime(trk_head->rte_name, 32, "%Y-%m-%dT%H:%M:%SZ", stmp); - track_add_head(trk_head); - - wpt = waypt_new(); - - wpt->longitude = array[i]->begin_lon; - wpt->latitude = array[i]->begin_lat; - wpt->heartrate = array[i]->avg_heart_rate; - wpt->cadence = array[i]->avg_cadence; - wpt->speed = array[i]->max_speed; - wpt->creation_time = array[i]->start_time; - wpt->microseconds = 0; - - wpt->shortname = xmalloc(8); - sprintf(wpt->shortname, "#%d-0", index); - wpt->description = xmalloc(128); - sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d", - array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, - array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method); - - track_add_wpt(trk_head, wpt); - } -/*Allow even if no correct location, no skip if invalid */ -/* if (array[i]->no_latlon) { -* continue; -* } -*/ - wpt = waypt_new(); - - wpt->longitude = array[i]->end_lon; - wpt->latitude = array[i]->end_lat; - wpt->heartrate = array[i]->avg_heart_rate; - wpt->cadence = array[i]->avg_cadence; - wpt->speed = array[i]->max_speed; - wpt->creation_time = array[i]->start_time + array[i]->total_time/100; - wpt->microseconds = 10000*(array[i]->total_time % 100); - /*Add fields with no mapping in the description */ - wpt->shortname = xmalloc(8); - sprintf(wpt->shortname, "#%d", index); - wpt->description = xmalloc(128); - sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d (%f,%f)", - array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, - array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method, - array[i]->begin_lon, array[i]->begin_lat); - - track_add_wpt(trk_head, wpt); - } - while(ntracks) { - GPS_Lap_Del(&array[--ntracks]); - } - xfree(array); + int32 ntracks; + GPS_PLap* array; + route_head* trk_head = NULL; + int trk_num = 0; + int index; + int i; + + ntracks = GPS_Command_Get_Lap(portname, &array, waypt_read_cb); + if (ntracks <= 0) { + return; + } + for (i = 0; i < ntracks; i++) { + waypoint* wpt; + if (array[i]->index == -1) { + index=i; + } else { + index=array[i]->index; + index=i; + } + + if ((trk_head == NULL) || (i == 0) || + /* D906 - last track:index is the track index */ + (array[i]->index == -1 && array[i]->track_index != 255) || + /* D10xx - no real separator, use begin/end time to guess */ + (abs(array[i-1]->start_time + array[i]->total_time/100-array[i]->start_time) > 2) + ) { + static struct tm* stmp; + stmp = gmtime(&array[i]->start_time); + trk_head = route_head_alloc(); + /*For D906, we would like to use the track_index in the last packet instead...*/ + trk_head->rte_num = ++trk_num; + trk_head->rte_name = xmalloc(32); + strftime(trk_head->rte_name, 32, "%Y-%m-%dT%H:%M:%SZ", stmp); + track_add_head(trk_head); + + wpt = waypt_new(); + + wpt->longitude = array[i]->begin_lon; + wpt->latitude = array[i]->begin_lat; + wpt->heartrate = array[i]->avg_heart_rate; + wpt->cadence = array[i]->avg_cadence; + wpt->speed = array[i]->max_speed; + wpt->creation_time = array[i]->start_time; + wpt->microseconds = 0; + + wpt->shortname = xmalloc(8); + sprintf(wpt->shortname, "#%d-0", index); + wpt->description = xmalloc(128); + sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d", + array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, + array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method); + + track_add_wpt(trk_head, wpt); + } + /*Allow even if no correct location, no skip if invalid */ + /* if (array[i]->no_latlon) { + * continue; + * } + */ + wpt = waypt_new(); + + wpt->longitude = array[i]->end_lon; + wpt->latitude = array[i]->end_lat; + wpt->heartrate = array[i]->avg_heart_rate; + wpt->cadence = array[i]->avg_cadence; + wpt->speed = array[i]->max_speed; + wpt->creation_time = array[i]->start_time + array[i]->total_time/100; + wpt->microseconds = 10000*(array[i]->total_time % 100); + /*Add fields with no mapping in the description */ + wpt->shortname = xmalloc(8); + sprintf(wpt->shortname, "#%d", index); + wpt->description = xmalloc(128); + sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d (%f,%f)", + array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, + array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method, + array[i]->begin_lon, array[i]->begin_lat); + + track_add_wpt(trk_head, wpt); + } + while (ntracks) { + GPS_Lap_Del(&array[--ntracks]); + } + xfree(array); } #endif @@ -646,576 +677,614 @@ lap_read_as_track(void) * to the data type we use throughout. Yes, we do lose some data that way. */ static void -pvt2wpt(GPS_PPvt_Data pvt, waypoint *wpt) +pvt2wpt(GPS_PPvt_Data pvt, waypoint* wpt) { - double wptime, wptimes; - - wpt->altitude = pvt->alt; - wpt->latitude = pvt->lat; - wpt->longitude = pvt->lon; - WAYPT_SET(wpt,course,1); - WAYPT_SET(wpt,speed,1); - - wpt->course = 180 + DEG(atan2(-pvt->east, -pvt->north)); - - /* velocity in m/s */ - WAYPT_SET(wpt,speed, sqrt(pvt->north*pvt->north + pvt->east*pvt->east)); - // wpt->vs = pvt->up; - - /* - * The unit reports time in three fields: - * 1) The # of days to most recent Sun. since 1989-12-31 midnight UTC. - * 2) The number of seconds (fractions allowed) since that Sunday. - * 3) The number of leap seconds that offset the current UTC and GPS - * reference clocks. - */ - wptime = 631065600.0 + pvt->wn_days * 86400.0 + - pvt->tow - - pvt->leap_scnds; - wptimes = floor(wptime); - wpt->creation_time = wptimes; - wpt->microseconds = 1000000.0 * (wptime - wptimes); - - /* - * The Garmin spec fifteen different models that use a different - * table for 'fix' without a really good way to tell if the model - * we're talking to happens to be one of those...By inspection, - * it looks like even though the models (Summit, Legend, etc.) may - * be popular, it's older (2001 and earlier or so) versions that - * are affected and I think there are relatively few readers of - * the fix field anyway. Time will tell if this is a good plan. - */ - switch (pvt->fix) { - case 0: wpt->fix = fix_unknown;break; - case 1: wpt->fix = fix_none;break; - case 2: wpt->fix = fix_2d;break; - case 3: wpt->fix = fix_3d;break; - case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ - case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ - default: - /* undocumented type. */ - break; - } + double wptime, wptimes; + + wpt->altitude = pvt->alt; + wpt->latitude = pvt->lat; + wpt->longitude = pvt->lon; + WAYPT_SET(wpt,course,1); + WAYPT_SET(wpt,speed,1); + + wpt->course = 180 + DEG(atan2(-pvt->east, -pvt->north)); + + /* velocity in m/s */ + WAYPT_SET(wpt,speed, sqrt(pvt->north*pvt->north + pvt->east*pvt->east)); + // wpt->vs = pvt->up; + + /* + * The unit reports time in three fields: + * 1) The # of days to most recent Sun. since 1989-12-31 midnight UTC. + * 2) The number of seconds (fractions allowed) since that Sunday. + * 3) The number of leap seconds that offset the current UTC and GPS + * reference clocks. + */ + wptime = 631065600.0 + pvt->wn_days * 86400.0 + + pvt->tow + - pvt->leap_scnds; + wptimes = floor(wptime); + wpt->creation_time = wptimes; + wpt->microseconds = 1000000.0 * (wptime - wptimes); + + /* + * The Garmin spec fifteen different models that use a different + * table for 'fix' without a really good way to tell if the model + * we're talking to happens to be one of those...By inspection, + * it looks like even though the models (Summit, Legend, etc.) may + * be popular, it's older (2001 and earlier or so) versions that + * are affected and I think there are relatively few readers of + * the fix field anyway. Time will tell if this is a good plan. + */ + switch (pvt->fix) { + case 0: + wpt->fix = fix_unknown; + break; + case 1: + wpt->fix = fix_none; + break; + case 2: + wpt->fix = fix_2d; + break; + case 3: + wpt->fix = fix_3d; + break; + case 4: + wpt->fix = fix_dgps; + break; /* 2D_diff */ + case 5: + wpt->fix = fix_dgps; + break; /* 3D_diff */ + default: + /* undocumented type. */ + break; + } } -static gpsdevh *pvt_fd; +static gpsdevh* pvt_fd; static void -pvt_init(const char *fname) +pvt_init(const char* fname) { - rw_init(fname); - GPS_Command_Pvt_On(fname, &pvt_fd); + rw_init(fname); + GPS_Command_Pvt_On(fname, &pvt_fd); } -static waypoint * -pvt_read(posn_status *posn_status) +static waypoint* +pvt_read(posn_status* posn_status) { - waypoint *wpt = waypt_new(); - GPS_PPvt_Data pvt = GPS_Pvt_New(); - - if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) { - pvt2wpt(pvt, wpt); - GPS_Pvt_Del(&pvt); - - wpt->shortname = xstrdup("Position"); - - if (gps_errno && posn_status) { - posn_status->request_terminate = 1; - } - - return wpt; - } - - /* - * If the caller has not given us a better way to return the - * error, do it now. - */ - if (gps_errno) { - fatal(MYNAME ": Fatal error reading position.\n"); - } - - waypt_free(wpt); - GPS_Pvt_Del(&pvt); - - return NULL; + waypoint* wpt = waypt_new(); + GPS_PPvt_Data pvt = GPS_Pvt_New(); + + if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) { + pvt2wpt(pvt, wpt); + GPS_Pvt_Del(&pvt); + + wpt->shortname = xstrdup("Position"); + + if (gps_errno && posn_status) { + posn_status->request_terminate = 1; + } + + return wpt; + } + + /* + * If the caller has not given us a better way to return the + * error, do it now. + */ + if (gps_errno) { + fatal(MYNAME ": Fatal error reading position.\n"); + } + + waypt_free(wpt); + GPS_Pvt_Del(&pvt); + + return NULL; } static void data_read(void) { - if (gpx_vec) { - gpx_vec->read(); - return; - } - - if (poweroff) { - return; - } - - if (global_opts.masked_objective & WPTDATAMASK) - waypt_read(); - if (global_opts.masked_objective & TRKDATAMASK) - track_read(); - if (global_opts.masked_objective & RTEDATAMASK) - route_read(); - if (!(global_opts.masked_objective & - (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))) - fatal(MYNAME ": Nothing to do.\n"); + if (gpx_vec) { + gpx_vec->read(); + return; + } + + if (poweroff) { + return; + } + + if (global_opts.masked_objective & WPTDATAMASK) { + waypt_read(); + } + if (global_opts.masked_objective & TRKDATAMASK) { + track_read(); + } + if (global_opts.masked_objective & RTEDATAMASK) { + route_read(); + } + if (!(global_opts.masked_objective & + (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))) { + fatal(MYNAME ": Nothing to do.\n"); + } } static GPS_PWay sane_GPS_Way_New(void) { - GPS_PWay way; - way = GPS_Way_New(); - if (!way) { - fatal(MYNAME ":not enough memory\n"); - } - - /* - * Undo less than helpful defaults from Way_New. - */ - way->rte_ident[0] = 0; - way->rte_cmnt[0] = 0; - way->rte_link_subclass[0] = 0; - way->rte_link_ident[0] = 0; - way->city[0] = 0; - way->state[0] = 0; - way->facility[0] = 0; - way->addr[0] = 0; - way->cross_road[0] = 0; - way->cross_road[0] = 0; - way->dpth = 1.0e25f; - way->wpt_class = 0; // user waypoint by default. - - return way; + GPS_PWay way; + way = GPS_Way_New(); + if (!way) { + fatal(MYNAME ":not enough memory\n"); + } + + /* + * Undo less than helpful defaults from Way_New. + */ + way->rte_ident[0] = 0; + way->rte_cmnt[0] = 0; + way->rte_link_subclass[0] = 0; + way->rte_link_ident[0] = 0; + way->city[0] = 0; + way->state[0] = 0; + way->facility[0] = 0; + way->addr[0] = 0; + way->cross_road[0] = 0; + way->cross_road[0] = 0; + way->dpth = 1.0e25f; + way->wpt_class = 0; // user waypoint by default. + + return way; } -static int -waypt_write_cb(GPS_PWay *way) +static int +waypt_write_cb(GPS_PWay* way) { - static int i; - int n = waypt_count(); - - if (global_opts.verbose_status) { - i++; - waypt_status_disp(n, i); - } - return 0; + static int i; + int n = waypt_count(); + + if (global_opts.verbose_status) { + i++; + waypt_status_disp(n, i); + } + return 0; } -/* +/* * If we're using smart names, try to put the cache info in the * description. */ -const char * -get_gc_info(waypoint *wpt) +const char* +get_gc_info(waypoint* wpt) { - if (global_opts.smart_names) { - if (wpt->gc_data->type == gt_virtual) return "V "; - if (wpt->gc_data->type == gt_unknown) return "? "; - if (wpt->gc_data->type == gt_multi) return "Mlt "; - if (wpt->gc_data->type == gt_earth) return "EC "; - if (wpt->gc_data->type == gt_event) return "Ev "; - if (wpt->gc_data->container == gc_micro) return "M "; - if (wpt->gc_data->container == gc_small) return "S "; - } - return ""; + if (global_opts.smart_names) { + if (wpt->gc_data->type == gt_virtual) { + return "V "; + } + if (wpt->gc_data->type == gt_unknown) { + return "? "; + } + if (wpt->gc_data->type == gt_multi) { + return "Mlt "; + } + if (wpt->gc_data->type == gt_earth) { + return "EC "; + } + if (wpt->gc_data->type == gt_event) { + return "Ev "; + } + if (wpt->gc_data->container == gc_micro) { + return "M "; + } + if (wpt->gc_data->container == gc_small) { + return "S "; + } + } + return ""; } static int waypoint_prepare(void) { - int i; - int n = waypt_count(); - queue *elem, *tmp; - extern queue waypt_head; - int icon; - - tx_waylist = xcalloc(n,sizeof(*tx_waylist)); - - for (i = 0; i < n; i++) { - tx_waylist[i] = sane_GPS_Way_New(); - } - - i = 0; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wpt; - char *ident; - char *src = NULL; - char obuf[256]; - - wpt = (waypoint *) elem; - - if(wpt->description) src = wpt->description; - if(wpt->notes) src = wpt->notes; - - /* - * mkshort will do collision detection and namespace - * cleaning - */ - ident = mkshort(mkshort_handle, - global_opts.synthesize_shortnames ? src : - wpt->shortname); - /* Should not be a strcpy as 'ident' isn't really a C string, - * but rather a garmin "fixed length" buffer that's padded - * to the end with spaces. So this is NOT (strlen+1). - */ - memcpy(tx_waylist[i]->ident, ident, strlen(ident)); - - if (global_opts.synthesize_shortnames) { - xfree(ident); - } - tx_waylist[i]->ident[sizeof(tx_waylist[i]->ident)-1] = 0; - - // If we were explictly given a comment from GPX, use that. - // This logic really is horrible and needs to be untangled. - if (wpt->description && - global_opts.smart_names && !wpt->gc_data->diff) { - memcpy(tx_waylist[i]->cmnt, wpt->description, strlen(wpt->description)); - } else { - if (global_opts.smart_names && - wpt->gc_data->diff && wpt->gc_data->terr) { + int i; + int n = waypt_count(); + queue* elem, *tmp; + extern queue waypt_head; + int icon; + + tx_waylist = (struct GPS_SWay**) xcalloc(n,sizeof(*tx_waylist)); + + for (i = 0; i < n; i++) { + tx_waylist[i] = sane_GPS_Way_New(); + } + + i = 0; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint* wpt; + char* ident; + char* src = NULL; + char obuf[256]; + + wpt = (waypoint*) elem; + + if (wpt->description) { + src = wpt->description; + } + if (wpt->notes) { + src = wpt->notes; + } + + /* + * mkshort will do collision detection and namespace + * cleaning + */ + ident = mkshort(mkshort_handle, + global_opts.synthesize_shortnames ? src : + wpt->shortname); + /* Should not be a strcpy as 'ident' isn't really a C string, + * but rather a garmin "fixed length" buffer that's padded + * to the end with spaces. So this is NOT (strlen+1). + */ + memcpy(tx_waylist[i]->ident, ident, strlen(ident)); + + if (global_opts.synthesize_shortnames) { + xfree(ident); + } + tx_waylist[i]->ident[sizeof(tx_waylist[i]->ident)-1] = 0; + + // If we were explictly given a comment from GPX, use that. + // This logic really is horrible and needs to be untangled. + if (wpt->description && + global_opts.smart_names && !wpt->gc_data->diff) { + memcpy(tx_waylist[i]->cmnt, wpt->description, strlen(wpt->description)); + } else { + if (global_opts.smart_names && + wpt->gc_data->diff && wpt->gc_data->terr) { #if 0 -xasprintf(&src, "%s %s", &wpt->shortname[2], src); + xasprintf(&src, "%s %s", &wpt->shortname[2], src); #endif - snprintf(obuf, sizeof(obuf), "%s%d/%d %s", - get_gc_info(wpt), - wpt->gc_data->diff, wpt->gc_data->terr, - src); - memcpy(tx_waylist[i]->cmnt, obuf, strlen(obuf)); - } else { - memcpy(tx_waylist[i]->cmnt, src, strlen(src)); - } - } - - - - tx_waylist[i]->lon = wpt->longitude; - tx_waylist[i]->lat = wpt->latitude; - - if (deficon) { - icon = gt_find_icon_number_from_desc(deficon, PCX); - } else { - if (get_cache_icon(wpt)) { - icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); - } else { - icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); - } - } - - /* For units that support tiny numbers of waypoints, just - * overwrite that and go very literal. - */ - if (gps_waypt_type == 103) { - icon = d103_icon_number_from_symbol(wpt->icon_descr); - } - tx_waylist[i]->smbl = icon; - if (wpt->altitude == unknown_alt) { - tx_waylist[i]->alt_is_unknown = 1; - tx_waylist[i]->alt = 0; - } else { - tx_waylist[i]->alt = wpt->altitude; - } - if (wpt->creation_time) { - tx_waylist[i]->time = wpt->creation_time; - tx_waylist[i]->time_populated = 1; - } - if (category) { - tx_waylist[i]->category = 1 << (atoi(category) - 1); - } - if (categorybits) { - tx_waylist[i]->category = categorybits; - } + snprintf(obuf, sizeof(obuf), "%s%d/%d %s", + get_gc_info(wpt), + wpt->gc_data->diff, wpt->gc_data->terr, + src); + memcpy(tx_waylist[i]->cmnt, obuf, strlen(obuf)); + } else { + memcpy(tx_waylist[i]->cmnt, src, strlen(src)); + } + } + + + + tx_waylist[i]->lon = wpt->longitude; + tx_waylist[i]->lat = wpt->latitude; + + if (deficon) { + icon = gt_find_icon_number_from_desc(deficon, PCX); + } else { + if (get_cache_icon(wpt)) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } else { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + } + } + + /* For units that support tiny numbers of waypoints, just + * overwrite that and go very literal. + */ + if (gps_waypt_type == 103) { + icon = d103_icon_number_from_symbol(wpt->icon_descr); + } + tx_waylist[i]->smbl = icon; + if (wpt->altitude == unknown_alt) { + tx_waylist[i]->alt_is_unknown = 1; + tx_waylist[i]->alt = 0; + } else { + tx_waylist[i]->alt = wpt->altitude; + } + if (wpt->creation_time) { + tx_waylist[i]->time = wpt->creation_time; + tx_waylist[i]->time_populated = 1; + } + if (category) { + tx_waylist[i]->category = 1 << (atoi(category) - 1); + } + if (categorybits) { + tx_waylist[i]->category = categorybits; + } #if SOON - garmin_fs_garmin_before_write(wpt, tx_waylist[i], gps_waypt_type); + garmin_fs_garmin_before_write(wpt, tx_waylist[i], gps_waypt_type); #endif - i++; - } + i++; + } - return n; + return n; } static void waypoint_write(void) { - int i, n; - int32 ret; - - n = waypoint_prepare(); - - if ((ret = GPS_Command_Send_Waypoint(portname, tx_waylist, n, waypt_write_cb)) < 0) { - fatal(MYNAME ":communication error sending wayoints..\n"); - } - - for (i = 0; i < n; ++i) { - GPS_Way_Del(&tx_waylist[i]); - } - if (global_opts.verbose_status) { - fprintf(stdout, "\r\n"); - fflush(stdout); - } - xfree(tx_waylist); + int i, n; + int32 ret; + + n = waypoint_prepare(); + + if ((ret = GPS_Command_Send_Waypoint(portname, tx_waylist, n, waypt_write_cb)) < 0) { + fatal(MYNAME ":communication error sending wayoints..\n"); + } + + for (i = 0; i < n; ++i) { + GPS_Way_Del(&tx_waylist[i]); + } + if (global_opts.verbose_status) { + fprintf(stdout, "\r\n"); + fflush(stdout); + } + xfree(tx_waylist); } static void -route_hdr_pr(const route_head *rte) +route_hdr_pr(const route_head* rte) { - (*cur_tx_routelist_entry)->rte_num = rte->rte_num; - (*cur_tx_routelist_entry)->isrte = 1; - if (rte->rte_name) { - strncpy((*cur_tx_routelist_entry)->rte_ident, rte->rte_name, - sizeof ((*cur_tx_routelist_entry)->rte_ident)); - } + (*cur_tx_routelist_entry)->rte_num = rte->rte_num; + (*cur_tx_routelist_entry)->isrte = 1; + if (rte->rte_name) { + strncpy((*cur_tx_routelist_entry)->rte_ident, rte->rte_name, + sizeof((*cur_tx_routelist_entry)->rte_ident)); + } } static void -route_waypt_pr(const waypoint *wpt) +route_waypt_pr(const waypoint* wpt) { - GPS_PWay rte = *cur_tx_routelist_entry; - char *s, *d; - - /* - * As stupid as this is, libjeeps seems to want an empty - * waypoint between every link in a route that has nothing - * but the 'islink' member set. Rather than "fixing" libjeeps, - * we just double them up (sigh) and do that here. - */ - rte->islink = 1; - rte->lon = wpt->longitude; - rte->lat = wpt->latitude; - cur_tx_routelist_entry++; - rte = *cur_tx_routelist_entry; - - rte->lon = wpt->longitude; - rte->lat = wpt->latitude; - rte->smbl = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); - - // map class so unit doesn't duplicate routepoints as a waypoint. - rte->wpt_class = 0x80; - - if (wpt->altitude != unknown_alt) { - rte->alt = wpt->altitude; - } else { - rte->alt_is_unknown = 1; - rte->alt = 0; - } - - // Garmin protocol spec says no spaces, no lowercase, etc. in a route. - // enforce that here, since jeeps doesn't. - // - // This was strncpy(rte->ident, wpt->shortname, sizeof(rte->ident)); - d = rte->ident; - for (s = wpt->shortname; *s; s++) { - int c = *s; - if (receiver_must_upper && isalpha(c)) c = toupper(c); - if (strchr(valid_waypt_chars, c)) { - *d++ = c; - } - } - - rte->ident[sizeof(rte->ident)-1] = 0; - - if (wpt->description) { - strncpy(rte->cmnt, wpt->description, sizeof(rte->cmnt)); - rte->cmnt[sizeof(rte->cmnt)-1] = 0; - } else { - rte->cmnt[0] = 0; - } - cur_tx_routelist_entry++; + GPS_PWay rte = *cur_tx_routelist_entry; + char* s, *d; + + /* + * As stupid as this is, libjeeps seems to want an empty + * waypoint between every link in a route that has nothing + * but the 'islink' member set. Rather than "fixing" libjeeps, + * we just double them up (sigh) and do that here. + */ + rte->islink = 1; + rte->lon = wpt->longitude; + rte->lat = wpt->latitude; + cur_tx_routelist_entry++; + rte = *cur_tx_routelist_entry; + + rte->lon = wpt->longitude; + rte->lat = wpt->latitude; + rte->smbl = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + + // map class so unit doesn't duplicate routepoints as a waypoint. + rte->wpt_class = 0x80; + + if (wpt->altitude != unknown_alt) { + rte->alt = wpt->altitude; + } else { + rte->alt_is_unknown = 1; + rte->alt = 0; + } + + // Garmin protocol spec says no spaces, no lowercase, etc. in a route. + // enforce that here, since jeeps doesn't. + // + // This was strncpy(rte->ident, wpt->shortname, sizeof(rte->ident)); + d = rte->ident; + for (s = wpt->shortname; *s; s++) { + int c = *s; + if (receiver_must_upper && isalpha(c)) { + c = toupper(c); + } + if (strchr(valid_waypt_chars, c)) { + *d++ = c; + } + } + + rte->ident[sizeof(rte->ident)-1] = 0; + + if (wpt->description) { + strncpy(rte->cmnt, wpt->description, sizeof(rte->cmnt)); + rte->cmnt[sizeof(rte->cmnt)-1] = 0; + } else { + rte->cmnt[0] = 0; + } + cur_tx_routelist_entry++; } static void -route_noop(const route_head *wp) +route_noop(const route_head* wp) { } static void route_write(void) { - int i; - int n = 2 * route_waypt_count(); /* Doubled for the islink crap. */ + int i; + int n = 2 * route_waypt_count(); /* Doubled for the islink crap. */ - tx_routelist = xcalloc(n,sizeof(GPS_PWay)); - cur_tx_routelist_entry = tx_routelist; + tx_routelist = (struct GPS_SWay**) xcalloc(n,sizeof(GPS_PWay)); + cur_tx_routelist_entry = tx_routelist; - for (i = 0; i < n; i++) { - tx_routelist[i] = sane_GPS_Way_New(); - } + for (i = 0; i < n; i++) { + tx_routelist[i] = sane_GPS_Way_New(); + } - route_disp_all(route_hdr_pr, route_noop, route_waypt_pr); - GPS_Command_Send_Route(portname, tx_routelist, n); + route_disp_all(route_hdr_pr, route_noop, route_waypt_pr); + GPS_Command_Send_Route(portname, tx_routelist, n); } static void -track_hdr_pr(const route_head *trk_head) +track_hdr_pr(const route_head* trk_head) { - (*cur_tx_tracklist_entry)->ishdr = gpsTrue; - if ( trk_head->rte_name ) { - strncpy((*cur_tx_tracklist_entry)->trk_ident, trk_head->rte_name, sizeof((*cur_tx_tracklist_entry)->trk_ident)); - (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; - } else { - sprintf((*cur_tx_tracklist_entry)->trk_ident, "TRACK%02d", my_track_count); - } - cur_tx_tracklist_entry++; - my_track_count++; + (*cur_tx_tracklist_entry)->ishdr = gpsTrue; + if (trk_head->rte_name) { + strncpy((*cur_tx_tracklist_entry)->trk_ident, trk_head->rte_name, sizeof((*cur_tx_tracklist_entry)->trk_ident)); + (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; + } else { + sprintf((*cur_tx_tracklist_entry)->trk_ident, "TRACK%02d", my_track_count); + } + cur_tx_tracklist_entry++; + my_track_count++; } static void -track_waypt_pr(const waypoint *wpt) +track_waypt_pr(const waypoint* wpt) { - (*cur_tx_tracklist_entry)->lat = wpt->latitude; - (*cur_tx_tracklist_entry)->lon = wpt->longitude; - (*cur_tx_tracklist_entry)->alt = (wpt->altitude != unknown_alt) ? wpt->altitude : 1e25; - (*cur_tx_tracklist_entry)->Time = wpt->creation_time; - if ( wpt->shortname ) { - strncpy((*cur_tx_tracklist_entry)->trk_ident, wpt->shortname, sizeof((*cur_tx_tracklist_entry)->trk_ident)); - (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; - } - (*cur_tx_tracklist_entry)->tnew = wpt->wpt_flags.new_trkseg; - cur_tx_tracklist_entry++; + (*cur_tx_tracklist_entry)->lat = wpt->latitude; + (*cur_tx_tracklist_entry)->lon = wpt->longitude; + (*cur_tx_tracklist_entry)->alt = (wpt->altitude != unknown_alt) ? wpt->altitude : 1e25; + (*cur_tx_tracklist_entry)->Time = wpt->creation_time; + if (wpt->shortname) { + strncpy((*cur_tx_tracklist_entry)->trk_ident, wpt->shortname, sizeof((*cur_tx_tracklist_entry)->trk_ident)); + (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; + } + (*cur_tx_tracklist_entry)->tnew = wpt->wpt_flags.new_trkseg; + cur_tx_tracklist_entry++; } static int track_prepare(void) { - int i; - int32 n = track_waypt_count() + track_count(); + int i; + int32 n = track_waypt_count() + track_count(); - tx_tracklist = xcalloc(n, sizeof(GPS_PTrack)); - cur_tx_tracklist_entry = tx_tracklist; - for (i = 0; i < n; i++) { - tx_tracklist[i] = GPS_Track_New(); - } - my_track_count = 0; - track_disp_all(track_hdr_pr, route_noop, track_waypt_pr); + tx_tracklist = (struct GPS_STrack**) xcalloc(n, sizeof(GPS_PTrack)); + cur_tx_tracklist_entry = tx_tracklist; + for (i = 0; i < n; i++) { + tx_tracklist[i] = GPS_Track_New(); + } + my_track_count = 0; + track_disp_all(track_hdr_pr, route_noop, track_waypt_pr); - GPS_Prepare_Track_For_Device(&tx_tracklist, &n); + GPS_Prepare_Track_For_Device(&tx_tracklist, &n); - return n; + return n; } static void track_write(void) { - int i, n; - - n = track_prepare(); - GPS_Command_Send_Track(portname, tx_tracklist, n, (eraset)? 1 : 0); - - for (i = 0; i < n; i++) { - GPS_Track_Del(&tx_tracklist[i]); - } - xfree(tx_tracklist); + int i, n; + + n = track_prepare(); + GPS_Command_Send_Track(portname, tx_tracklist, n, (eraset)? 1 : 0); + + for (i = 0; i < n; i++) { + GPS_Track_Del(&tx_tracklist[i]); + } + xfree(tx_tracklist); } static void course_write(void) { - int i, n_trk, n_wpt; + int i, n_trk, n_wpt; - n_wpt = waypoint_prepare(); - n_trk = track_prepare(); + n_wpt = waypoint_prepare(); + n_trk = track_prepare(); - GPS_Command_Send_Track_As_Course(portname, tx_tracklist, n_trk, - tx_waylist, n_wpt, (eraset)? 1 : 0); + GPS_Command_Send_Track_As_Course(portname, tx_tracklist, n_trk, + tx_waylist, n_wpt, (eraset)? 1 : 0); - for (i = 0; i < n_wpt; ++i) { - GPS_Way_Del(&tx_waylist[i]); - } - xfree(tx_waylist); + for (i = 0; i < n_wpt; ++i) { + GPS_Way_Del(&tx_waylist[i]); + } + xfree(tx_waylist); - for (i = 0; i < n_trk; i++) { - GPS_Track_Del(&tx_tracklist[i]); - } - xfree(tx_tracklist); + for (i = 0; i < n_trk; i++) { + GPS_Track_Del(&tx_tracklist[i]); + } + xfree(tx_tracklist); } static void data_write(void) { - if (poweroff) { - return; - } - - /* If we have both trackpoints and waypoints and the device - * supports courses, combine them to a course. Otherwise, - * send tracks & waypoints separately. - */ - if ((global_opts.masked_objective & WPTDATAMASK) && - (global_opts.masked_objective & TRKDATAMASK) && - gps_course_transfer != -1) - { - course_write(); - } - else - { - if (global_opts.masked_objective & WPTDATAMASK) - waypoint_write(); - if (global_opts.masked_objective & TRKDATAMASK) - track_write(); - } - if (global_opts.masked_objective & RTEDATAMASK) - route_write(); + if (poweroff) { + return; + } + + /* If we have both trackpoints and waypoints and the device + * supports courses, combine them to a course. Otherwise, + * send tracks & waypoints separately. + */ + if ((global_opts.masked_objective & WPTDATAMASK) && + (global_opts.masked_objective & TRKDATAMASK) && + gps_course_transfer != -1) { + course_write(); + } else { + if (global_opts.masked_objective & WPTDATAMASK) { + waypoint_write(); + } + if (global_opts.masked_objective & TRKDATAMASK) { + track_write(); + } + } + if (global_opts.masked_objective & RTEDATAMASK) { + route_write(); + } } ff_vecs_t garmin_vecs = { - ff_type_serial, - FF_CAP_RW_ALL, - rd_init, - rw_init, - rw_deinit, - rw_deinit, - data_read, - data_write, - NULL, - garmin_args, - CET_CHARSET_ASCII, 0, - { pvt_init, pvt_read, rw_deinit, NULL, NULL, NULL } + ff_type_serial, + FF_CAP_RW_ALL, + rd_init, + rw_init, + rw_deinit, + rw_deinit, + data_read, + data_write, + NULL, + garmin_args, + CET_CHARSET_ASCII, 0, + { pvt_init, pvt_read, rw_deinit, NULL, NULL, NULL } }; -static const char *d103_icons[16] = { - "dot", - "house", - "gas", - "car", - "fish", - "boat", - "anchor", - "wreck", - "exit", - "skull", - "flag", - "camp", - "circle_x", - "deer", - "1st_aid", - "back-track" +static const char* d103_icons[16] = { + "dot", + "house", + "gas", + "car", + "fish", + "boat", + "anchor", + "wreck", + "exit", + "skull", + "flag", + "camp", + "circle_x", + "deer", + "1st_aid", + "back-track" }; -static const char * +static const char* d103_symbol_from_icon_number(unsigned int n) { - if (n <= 15) - return d103_icons[n]; - else - return "unknown"; + if (n <= 15) { + return d103_icons[n]; + } else { + return "unknown"; + } } -static int -d103_icon_number_from_symbol(const char *s) +static int +d103_icon_number_from_symbol(const char* s) { - unsigned int i; + unsigned int i; - if (NULL == s) { - return 0; - } + if (NULL == s) { + return 0; + } - for (i = 0; i < sizeof(d103_icons) / sizeof(d103_icons[0]); i++) { - if (0 == case_ignore_strcmp(s, d103_icons[i])) - return i; - } - return 0; + for (i = 0; i < sizeof(d103_icons) / sizeof(d103_icons[0]); i++) { + if (0 == case_ignore_strcmp(s, d103_icons[i])) { + return i; + } + } + return 0; } diff --git a/gpsbabel/garmin_device_xml.c b/gpsbabel/garmin_device_xml.c index 981883b2a..8630ada61 100644 --- a/gpsbabel/garmin_device_xml.c +++ b/gpsbabel/garmin_device_xml.c @@ -1,5 +1,5 @@ /* - Parse 'GarminDevice.xml' on a Garmin mass storage device (e.g. Zumo, + Parse 'GarminDevice.xml' on a Garmin mass storage device (e.g. Zumo, Nuvi, Colorado, etc. and return key device info. Copyright (C) 2008 Robert Lipe, robertlipe@gpsbabel.org @@ -20,7 +20,7 @@ */ -// References: +// References: // http://developer.garmin.com/web-device/garmin-mass-storage-mode-devices/ // http://developer.garmin.com/schemas/device/v2/ @@ -30,67 +30,82 @@ #define MYNAME "whatever" -static gdx_info *my_gdx_info; +static gdx_info* my_gdx_info; static int type; -static char *mountpoint, *base, *path, *ext; +static char* mountpoint, *base, *path, *ext; static xg_callback device_s, id_s, path_s, ext_s, base_s, dir_s; +jmp_buf gdx_jmp_buf; -void type_s(const char *args, const char **unused) { +void type_s(const char* args, const char** unused) +{ type = strcmp(args, "GPSData"); } -void device_s(const char *args, const char **unused) { +void device_s(const char* args, const char** unused) +{ if (my_gdx_info) { fatal(MYNAME ": More than one device type found in file.\n"); } - my_gdx_info = xcalloc(sizeof *my_gdx_info, 1); + my_gdx_info = (gdx_info*) xcalloc(sizeof *my_gdx_info, 1); my_gdx_info->device_desc = xstrdup(args); } -void id_s(const char *args, const char **unused) { +void id_s(const char* args, const char** unused) +{ my_gdx_info->device_id = xstrdup(args); } -void path_s(const char *args, const char **unused) { +void path_s(const char* args, const char** unused) +{ path = xstrdup(args); } -void ext_s(const char *args, const char **unused) { +void ext_s(const char* args, const char** unused) +{ ext = xstrdup(args); } -void base_s(const char *args, const char **unused) { +void base_s(const char* args, const char** unused) +{ base = xstrdup(args); } -void dir_s(const char *args, const char **unused) { - if (type) +void dir_s(const char* args, const char** unused) +{ + if (type) { return; + } if (0 == strcmp(args, "OutputFromUnit")) { xasprintf(&my_gdx_info->from_device.path, "%s%c%s", - mountpoint, GB_PATHSEP, path); - my_gdx_info->from_device.basename = xstrdup(base); - my_gdx_info->from_device.extension = xstrdup(ext); - xasprintf(&my_gdx_info->from_device.canon, "%s/%s.%s", - my_gdx_info->from_device.path, - my_gdx_info->from_device.basename, - my_gdx_info->from_device.extension); - } else - if (0 == strcmp(args, "InputToUnit")) { - xasprintf(&my_gdx_info->to_device.path, "%s%c%s", - mountpoint, GB_PATHSEP, path); + mountpoint, GB_PATHSEP, path); + my_gdx_info->from_device.basename = xstrdup(base); + my_gdx_info->from_device.extension = xstrdup(ext); + xasprintf(&my_gdx_info->from_device.canon, "%s/%s.%s", + my_gdx_info->from_device.path, + my_gdx_info->from_device.basename, + my_gdx_info->from_device.extension); + } else if (0 == strcmp(args, "InputToUnit")) { + xasprintf(&my_gdx_info->to_device.path, "%s%c%s", + mountpoint, GB_PATHSEP, path); my_gdx_info->to_device.basename = xstrdup(base); my_gdx_info->to_device.extension = xstrdup(ext); - } else - fatal(MYNAME ":Unknown direction '%s'\n", args); + } else { + fatal(MYNAME ":Unknown direction '%s'\n", args); + } - if (base) xfree(base) ; + if (base) { + xfree(base) ; + } base = NULL; - if (ext) xfree(ext) ; + if (ext) { + xfree(ext) ; + } ext = NULL; - if (path) xfree(path) ; + if (path) { + xfree(path) ; + } path = NULL; } @@ -102,13 +117,14 @@ static xg_tag_mapping gdx_map[] = { { ext_s, cb_cdata, "/Device/MassStorageMode/DataType/File/Location/FileExtension" }, { base_s, cb_cdata, "/Device/MassStorageMode/DataType/File/Location/BaseName" }, { dir_s, cb_cdata, "/Device/MassStorageMode/DataType/File/TransferDirection" }, - { 0, 0, NULL } + { 0, (xg_cb_type) 0, NULL } }; -const gdx_info * -gdx_read(const char *fname) { +const gdx_info* +gdx_read(const char* fname) +{ // Test file open-able before gb_open gets a chance to fatal(). - FILE *fin = fopen(fname, "r"); + FILE* fin = fopen(fname, "r"); if (fin) { fclose(fin); @@ -122,24 +138,26 @@ gdx_read(const char *fname) { // Look for the Device in the incoming NULL-terminated list of directories -const gdx_info * -gdx_find_file(char **dirlist) { - const gdx_info *gdx; +const gdx_info* +gdx_find_file(char** dirlist) +{ + const gdx_info* gdx; while (dirlist && *dirlist) { - char *tbuf; + char* tbuf; xasprintf(&tbuf, "%s/%s", *dirlist, "/Garmin/GarminDevice.xml"); mountpoint = *dirlist; gdx = gdx_read(tbuf); xfree(tbuf); if (gdx) { - longjmp(gdx_jmp_buf, 1); + longjmp(gdx_jmp_buf, 1); } dirlist++; } return NULL; } -const gdx_info * -gdx_get_info() { +const gdx_info* +gdx_get_info() +{ return my_gdx_info; } diff --git a/gpsbabel/garmin_device_xml.h b/gpsbabel/garmin_device_xml.h index ffc6b31af..1edd98ded 100644 --- a/gpsbabel/garmin_device_xml.h +++ b/gpsbabel/garmin_device_xml.h @@ -1,5 +1,5 @@ /* - Parse 'GarminDevice.xml' on a Garmin mass storage device (e.g. Zumo, + Parse 'GarminDevice.xml' on a Garmin mass storage device (e.g. Zumo, Nuvi, Colorado, etc. and return key device info. Copyright (C) 2008 Robert Lipe, robertlipe@gpsbabel.org @@ -24,113 +24,114 @@ * Describes a file on the unit. */ typedef struct { - char *path; - char *basename; - char *extension; - char *canon; // full name, when applicable. + char* path; + char* basename; + char* extension; + char* canon; // full name, when applicable. } gdx_file; /* * The interesting traits of this device. */ typedef struct { - const char *device_desc; - const char *device_id; - const char *device_mounted_path; // Not from the file; about the file. - gdx_file from_device; - gdx_file to_device; + const char* device_desc; + const char* device_id; + const char* device_mounted_path; // Not from the file; about the file. + gdx_file from_device; + gdx_file to_device; // gdx_file geocache_logs; } gdx_info; -const gdx_info* gdx_read(const char *fname); -const gdx_info * gdx_get_info(void); -const gdx_info * gdx_find_file(char **dirlist); +const gdx_info* gdx_read(const char* fname); +const gdx_info* gdx_get_info(void); +const gdx_info* gdx_find_file(char** dirlist); // This is so gross. By the time we know it's not a USB device // and could be one of our devices, we're so deep into the callstack -// that can't back out tracefully without bludgeoning most of the +// that can't back out tracefully without bludgeoning most of the // (Mac|Lin|Win) x (USB|Serial) matrix. Since we don't *really* want // to progress any further, we just longjump back to the caller... #include -jmp_buf gdx_jmp_buf; +extern jmp_buf gdx_jmp_buf; #if 0 /* * The file-level information. */ -static +static struct gpx_global { - gpx_global_entry name; - gpx_global_entry desc; - gpx_global_entry author; - gpx_global_entry email; - gpx_global_entry url; - gpx_global_entry urlname; - gpx_global_entry keywords; - /* time and bounds aren't here; they're recomputed. */ -} *gpx_global ; + gpx_global_entry name; + gpx_global_entry desc; + gpx_global_entry author; + gpx_global_entry email; + gpx_global_entry url; + gpx_global_entry urlname; + gpx_global_entry keywords; + /* time and bounds aren't here; they're recomputed. */ +}* gpx_global ; static void -gpx_add_to_global(gpx_global_entry *ge, char *cdata) +gpx_add_to_global(gpx_global_entry* ge, char* cdata) { - queue *elem, *tmp; - gpx_global_entry * gep; - - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gep = BASE_STRUCT(elem, gpx_global_entry, queue); - if (0 == strcmp(cdata, gep->tagdata)) - return; - } - - gep = xcalloc(sizeof(*gep), 1); - QUEUE_INIT(&gep->queue); - gep->tagdata = xstrdup(cdata); - ENQUEUE_TAIL(&ge->queue, &gep->queue); + queue* elem, *tmp; + gpx_global_entry* gep; + + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + if (0 == strcmp(cdata, gep->tagdata)) { + return; + } + } + + gep = xcalloc(sizeof(*gep), 1); + QUEUE_INIT(&gep->queue); + gep->tagdata = xstrdup(cdata); + ENQUEUE_TAIL(&ge->queue, &gep->queue); } static void -gpx_rm_from_global(gpx_global_entry *ge) +gpx_rm_from_global(gpx_global_entry* ge) { - queue *elem, *tmp; + queue* elem, *tmp; - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gpx_global_entry *g = (gpx_global_entry *) dequeue(elem); - xfree(g->tagdata); - xfree(g); - } + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gpx_global_entry* g = (gpx_global_entry*) dequeue(elem); + xfree(g->tagdata); + xfree(g); + } } static void -gpx_write_gdata(gpx_global_entry *ge, char *tag) +gpx_write_gdata(gpx_global_entry* ge, char* tag) { - queue *elem, *tmp; - gpx_global_entry * gep; - - if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { - return; - } - - gbfprintf(ofd, "<%s>", tag); - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gep = BASE_STRUCT(elem, gpx_global_entry, queue); - gbfprintf(ofd, "%s", gep->tagdata); - /* Some tags we just output once. */ - if ((0 == strcmp(tag, "url")) || - (0 == strcmp(tag, "email"))) { - break; - } - gbfprintf(ofd, " "); - } - gbfprintf(ofd, "\n", tag); + queue* elem, *tmp; + gpx_global_entry* gep; + + if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { + return; + } + + gbfprintf(ofd, "<%s>", tag); + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + gbfprintf(ofd, "%s", gep->tagdata); + /* Some tags we just output once. */ + if ((0 == strcmp(tag, "url")) || + (0 == strcmp(tag, "email"))) { + break; + } + gbfprintf(ofd, " "); + } + gbfprintf(ofd, "\n", tag); } typedef struct tag_mapping { - tag_type tag_type; /* enum from above for this tag */ - int tag_passthrough; /* true if we don't generate this */ - const char *tag_name; /* xpath-ish tag name */ - unsigned long crc; /* Crc32 of tag_name */ + tag_type tag_type; /* enum from above for this tag */ + int tag_passthrough; /* true if we don't generate this */ + const char* tag_name; /* xpath-ish tag name */ + unsigned long crc; /* Crc32 of tag_name */ } tag_mapping; /* @@ -140,29 +141,29 @@ typedef struct tag_mapping { */ tag_mapping tag_path_map[] = { - { tt_gpx, 0, "/gpx", 0UL }, - { tt_name, 0, "/gpx/name", 0UL }, - { tt_desc, 0, "/gpx/desc", 0UL }, - { tt_author, 0, "/gpx/author", 0UL }, - { tt_email, 0, "/gpx/email", 0UL }, - { tt_url, 0, "/gpx/url", 0UL }, - { tt_urlname, 0, "/gpx/urlname", 0UL }, - { tt_keywords, 0, "/gpx/keywords", 0UL }, - - { tt_wpt, 0, "/gpx/wpt", 0UL }, - { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, - { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, - { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, - { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, - { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, - { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, - { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, - { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ - { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ - { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, - { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, - - /* Double up the GPX 1.0 and GPX 1.1 styles */ + { tt_gpx, 0, "/gpx", 0UL }, + { tt_name, 0, "/gpx/name", 0UL }, + { tt_desc, 0, "/gpx/desc", 0UL }, + { tt_author, 0, "/gpx/author", 0UL }, + { tt_email, 0, "/gpx/email", 0UL }, + { tt_url, 0, "/gpx/url", 0UL }, + { tt_urlname, 0, "/gpx/urlname", 0UL }, + { tt_keywords, 0, "/gpx/keywords", 0UL }, + + { tt_wpt, 0, "/gpx/wpt", 0UL }, + { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, + { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, + { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, + { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, + { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, + { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, + { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, + { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ + { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ + { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, + { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, + + /* Double up the GPX 1.0 and GPX 1.1 styles */ #define GEOTAG(type,name) \ {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name, 0UL }, \ {type, 1, "/gpx/wpt/extensions/cache/" name, 0UL }, \ @@ -171,1216 +172,1213 @@ tag_mapping tag_path_map[] = { #define GARMIN_WPT_EXT "/gpx/wpt/extensions/gpxx:WaypointExtension" // GEOTAG( tt_cache, "cache"), - { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, - - GEOTAG( tt_cache_name, "name"), - GEOTAG( tt_cache_container, "container"), - GEOTAG( tt_cache_type, "type"), - GEOTAG( tt_cache_difficulty, "difficulty"), - GEOTAG( tt_cache_terrain, "terrain"), - GEOTAG( tt_cache_hint, "encoded_hints"), - GEOTAG( tt_cache_hint, "hints"), /* opencaching.de */ - GEOTAG( tt_cache_desc_short, "short_description"), - GEOTAG( tt_cache_desc_long, "long_description"), - GEOTAG( tt_cache_placer, "owner"), - { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, - { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, - { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, - { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, - { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, - { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, - - { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, - - { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, - { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, - { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, - { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, - { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, - { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, - { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, - { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, - { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, - { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, - { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, - { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, - { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, - - { tt_rte, 0, "/gpx/rte", 0UL }, - { tt_rte_name, 0, "/gpx/rte/name", 0UL }, - { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, - { tt_rte_number, 0, "/gpx/rte/number", 0UL }, - { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, - { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, - { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, - { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, - { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, - { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, - { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, - { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, - { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, - - { tt_trk, 0, "/gpx/trk", 0UL }, - { tt_trk_name, 0, "/gpx/trk/name", 0UL }, - { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, - { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, - { tt_trk_number, 0, "/gpx/trk/number", 0UL }, - { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, - { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, - { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, - { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, - { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, - { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, - { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, - { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, - { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, - { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, - { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, - - /* Common to tracks, routes, and waypts */ - { tt_fix, 0, "/gpx/wpt/fix", 0UL }, - { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, - { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, - { tt_sat, 0, "/gpx/wpt/sat", 0UL }, - { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, - { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, - { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, - { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, - { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, - { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, - { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, - { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, - { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, - { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, - { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, - {0, 0, NULL, 0UL} + { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, + + GEOTAG(tt_cache_name, "name"), + GEOTAG(tt_cache_container, "container"), + GEOTAG(tt_cache_type, "type"), + GEOTAG(tt_cache_difficulty, "difficulty"), + GEOTAG(tt_cache_terrain, "terrain"), + GEOTAG(tt_cache_hint, "encoded_hints"), + GEOTAG(tt_cache_hint, "hints"), /* opencaching.de */ + GEOTAG(tt_cache_desc_short, "short_description"), + GEOTAG(tt_cache_desc_long, "long_description"), + GEOTAG(tt_cache_placer, "owner"), + { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, + { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, + { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, + { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, + { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, + { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, + + { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, + + { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, + { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, + { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, + { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, + { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, + { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, + { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, + { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, + { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, + { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, + { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, + { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, + { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, + + { tt_rte, 0, "/gpx/rte", 0UL }, + { tt_rte_name, 0, "/gpx/rte/name", 0UL }, + { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, + { tt_rte_number, 0, "/gpx/rte/number", 0UL }, + { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, + { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, + { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, + { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, + { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, + { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, + { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, + { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, + { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, + + { tt_trk, 0, "/gpx/trk", 0UL }, + { tt_trk_name, 0, "/gpx/trk/name", 0UL }, + { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, + { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, + { tt_trk_number, 0, "/gpx/trk/number", 0UL }, + { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, + { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, + { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, + { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, + { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, + { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, + { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, + { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, + { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, + { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, + { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, + + /* Common to tracks, routes, and waypts */ + { tt_fix, 0, "/gpx/wpt/fix", 0UL }, + { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, + { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, + { tt_sat, 0, "/gpx/wpt/sat", 0UL }, + { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, + { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, + { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, + { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + {0, 0, NULL, 0UL} }; static tag_type -get_tag(const char *t, int *passthrough) +get_tag(const char* t, int* passthrough) { - tag_mapping *tm; - unsigned long tcrc = get_crc32_s(t); - - for (tm = tag_path_map; tm->tag_type != 0; tm++) { - if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { - *passthrough = tm->tag_passthrough; - return tm->tag_type; - } - } - *passthrough = 1; - return tt_unknown; + tag_mapping* tm; + unsigned long tcrc = get_crc32_s(t); + + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { + *passthrough = tm->tag_passthrough; + return tm->tag_type; + } + } + *passthrough = 1; + return tt_unknown; } static void prescan_tags(void) { - tag_mapping *tm; - for (tm = tag_path_map; tm->tag_type != 0; tm++) { - tm->crc = get_crc32_s(tm->tag_name); - } + tag_mapping* tm; + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + tm->crc = get_crc32_s(tm->tag_name); + } } static void -tag_gpx(const char **attrv) +tag_gpx(const char** attrv) { - const char **avp; - for (avp = &attrv[0]; *avp; avp += 2) { - if (strcmp(avp[0], "version") == 0) { - gpx_version = avp[1]; - } - else if (strcmp(avp[0], "src") == 0) { - gpx_creator = avp[1]; - } - /* - * Our handling of schemaLocation really is weird. - * If we see we have a "normal" GPX 1.1 header, on read, - * flip our default on write to use that and don't append - * it to the rest... - */ - else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { - if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { - if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) - xfree(xsi_schema_loc); - xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); - continue; - } - if (0 == strstr(xsi_schema_loc, avp[1])) { - xsi_schema_loc = xstrappend(xsi_schema_loc, " "); - xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); - } - } - } + const char** avp; + for (avp = &attrv[0]; *avp; avp += 2) { + if (strcmp(avp[0], "version") == 0) { + gpx_version = avp[1]; + } else if (strcmp(avp[0], "src") == 0) { + gpx_creator = avp[1]; + } + /* + * Our handling of schemaLocation really is weird. + * If we see we have a "normal" GPX 1.1 header, on read, + * flip our default on write to use that and don't append + * it to the rest... + */ + else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { + if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { + if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) { + xfree(xsi_schema_loc); + } + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); + continue; + } + if (0 == strstr(xsi_schema_loc, avp[1])) { + xsi_schema_loc = xstrappend(xsi_schema_loc, " "); + xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); + } + } + } } static void -tag_wpt(const char **attrv) +tag_wpt(const char** attrv) { - const char **avp = &attrv[0]; - - wpt_tmp = waypt_new(); - - cur_tag = NULL; - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->longitude); - } - avp+=2; - } - fs_ptr = &wpt_tmp->fs; + const char** avp = &attrv[0]; + + wpt_tmp = waypt_new(); + + cur_tag = NULL; + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->longitude); + } + avp+=2; + } + fs_ptr = &wpt_tmp->fs; } static void -tag_cache_desc(const char ** attrv) +tag_cache_desc(const char** attrv) { - const char **avp; - - cache_descr_is_html = 0; - for (avp = &attrv[0]; *avp; avp+=2) { - if (strcmp(avp[0], "html") == 0) { - if (strcmp(avp[1], "True") == 0) { - cache_descr_is_html = 1; - } - } - } + const char** avp; + + cache_descr_is_html = 0; + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "html") == 0) { + if (strcmp(avp[1], "True") == 0) { + cache_descr_is_html = 1; + } + } + } } static void -tag_gs_cache(const char **attrv) +tag_gs_cache(const char** attrv) { - const char **avp; - - for (avp = &attrv[0]; *avp; avp+=2) { - if (strcmp(avp[0], "id") == 0) { - wpt_tmp->gc_data.id = atoi(avp[1]); - } else if (strcmp(avp[0], "available") == 0) { - if (case_ignore_strcmp(avp[1], "True") == 0) { - wpt_tmp->gc_data.is_available = status_true; - } - else if (case_ignore_strcmp(avp[1], "False") == 0) { - wpt_tmp->gc_data.is_available = status_false; - } - } else if (strcmp(avp[0], "archived") == 0) { - if (case_ignore_strcmp(avp[1], "True") == 0) { - wpt_tmp->gc_data.is_archived = status_true; - } - else if (case_ignore_strcmp(avp[1], "False") == 0) { - wpt_tmp->gc_data.is_archived = status_false; - } - } - } + const char** avp; + + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "id") == 0) { + wpt_tmp->gc_data.id = atoi(avp[1]); + } else if (strcmp(avp[0], "available") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + wpt_tmp->gc_data.is_available = status_true; + } else if (case_ignore_strcmp(avp[1], "False") == 0) { + wpt_tmp->gc_data.is_available = status_false; + } + } else if (strcmp(avp[0], "archived") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + wpt_tmp->gc_data.is_archived = status_true; + } else if (case_ignore_strcmp(avp[1], "False") == 0) { + wpt_tmp->gc_data.is_archived = status_false; + } + } + } } static void -start_something_else(const char *el, const char **attrv) +start_something_else(const char* el, const char** attrv) { - const char **avp = attrv; - char **avcp = NULL; - int attr_count = 0; - xml_tag *new_tag; - fs_xml *fs_gpx; - - if ( !fs_ptr ) { - return; - } - - new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); - new_tag->tagname = xstrdup(el); - - /* count attributes */ - while (*avp) { - attr_count++; - avp++; - } - - /* copy attributes */ - avp = attrv; - new_tag->attributes = (char **)xcalloc(sizeof(char *),attr_count+1); - avcp = new_tag->attributes; - while (*avp) { - *avcp = xstrdup(*avp); - avcp++; - avp++; - } - *avcp = NULL; - - if ( cur_tag ) { - if ( cur_tag->child ) { - cur_tag = cur_tag->child; - while ( cur_tag->sibling ) { - cur_tag = cur_tag->sibling; - } - cur_tag->sibling = new_tag; - new_tag->parent = cur_tag->parent; - } - else { - cur_tag->child = new_tag; - new_tag->parent = cur_tag; - } - } - else { - fs_gpx = (fs_xml *)fs_chain_find( *fs_ptr, FS_GPX ); - - if ( fs_gpx && fs_gpx->tag ) { - cur_tag = fs_gpx->tag; - while ( cur_tag->sibling ) { - cur_tag = cur_tag->sibling; - } - cur_tag->sibling = new_tag; - new_tag->parent = NULL; - } - else { - fs_gpx = fs_xml_alloc(FS_GPX); - fs_gpx->tag = new_tag; - fs_chain_add( fs_ptr, (format_specific_data *)fs_gpx ); - new_tag->parent = NULL; - } - } - cur_tag = new_tag; + const char** avp = attrv; + char** avcp = NULL; + int attr_count = 0; + xml_tag* new_tag; + fs_xml* fs_gpx; + + if (!fs_ptr) { + return; + } + + new_tag = (xml_tag*)xcalloc(sizeof(xml_tag),1); + new_tag->tagname = xstrdup(el); + + /* count attributes */ + while (*avp) { + attr_count++; + avp++; + } + + /* copy attributes */ + avp = attrv; + new_tag->attributes = (char**)xcalloc(sizeof(char*),attr_count+1); + avcp = new_tag->attributes; + while (*avp) { + *avcp = xstrdup(*avp); + avcp++; + avp++; + } + *avcp = NULL; + + if (cur_tag) { + if (cur_tag->child) { + cur_tag = cur_tag->child; + while (cur_tag->sibling) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = cur_tag->parent; + } else { + cur_tag->child = new_tag; + new_tag->parent = cur_tag; + } + } else { + fs_gpx = (fs_xml*)fs_chain_find(*fs_ptr, FS_GPX); + + if (fs_gpx && fs_gpx->tag) { + cur_tag = fs_gpx->tag; + while (cur_tag->sibling) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = NULL; + } else { + fs_gpx = fs_xml_alloc(FS_GPX); + fs_gpx->tag = new_tag; + fs_chain_add(fs_ptr, (format_specific_data*)fs_gpx); + new_tag->parent = NULL; + } + } + cur_tag = new_tag; } static void end_something_else() { - if ( cur_tag ) { - cur_tag = cur_tag->parent; - } + if (cur_tag) { + cur_tag = cur_tag->parent; + } } static void -tag_log_wpt(const char **attrv) +tag_log_wpt(const char** attrv) { - waypoint * lwp_tmp; - const char **avp = &attrv[0]; - - /* create a new waypoint */ - lwp_tmp = waypt_new(); - - /* extract the lat/lon attributes */ - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &lwp_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &lwp_tmp->longitude); - } - avp+=2; - } - /* Make a new shortname. Since this is a groundspeak extension, - we assume that GCBLAH is the current shortname format and that - wpt_tmp refers to the currently parsed waypoint. Unfortunatley, - we need to keep track of log_wpt counts so we don't collide with - dupe shortnames. - */ - - if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { - /* copy of the shortname */ - lwp_tmp->shortname = xcalloc(7, 1); - sprintf(lwp_tmp->shortname, "%-4.4s%02d", - &wpt_tmp->shortname[2], logpoint_ct++); - - waypt_add(lwp_tmp); - } + waypoint* lwp_tmp; + const char** avp = &attrv[0]; + + /* create a new waypoint */ + lwp_tmp = waypt_new(); + + /* extract the lat/lon attributes */ + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->longitude); + } + avp+=2; + } + /* Make a new shortname. Since this is a groundspeak extension, + we assume that GCBLAH is the current shortname format and that + wpt_tmp refers to the currently parsed waypoint. Unfortunatley, + we need to keep track of log_wpt counts so we don't collide with + dupe shortnames. + */ + + if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { + /* copy of the shortname */ + lwp_tmp->shortname = xcalloc(7, 1); + sprintf(lwp_tmp->shortname, "%-4.4s%02d", + &wpt_tmp->shortname[2], logpoint_ct++); + + waypt_add(lwp_tmp); + } } static void -gpx_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) +gpx_start(void* data, const XML_Char* xml_el, const XML_Char** xml_attr) { - char *e; - char *ep; - int passthrough; - const char *el = xml_convert_to_char_string(xml_el); - const char **attr = xml_convert_attrs_to_char_string(xml_attr); - - vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); - e = current_tag.mem; - ep = e + strlen(e); - *ep++ = '/'; - strcpy(ep, el); - - - /* - * FIXME: Find out why a cdatastr[0] doesn't adequately reset the - * cdata handler. - */ - memset(cdatastr.mem, 0, cdatastr.size); - - switch (get_tag(current_tag.mem, &passthrough)) { - case tt_gpx: - tag_gpx(attr); - break; - case tt_wpt: - tag_wpt(attr); - break; - case tt_wpt_link: - if (0 == strcmp(attr[0], "href")) { - link_url = attr[1]; - } - break; - case tt_wpt_link_text: - link_text = cdatastr.mem; - break; - case tt_rte: - rte_head = route_head_alloc(); - route_add_head(rte_head); - fs_ptr = &rte_head->fs; - break; - case tt_rte_rtept: - tag_wpt(attr); - break; - case tt_trk: - trk_head = route_head_alloc(); - track_add_head(trk_head); - fs_ptr = &trk_head->fs; - break; - case tt_trk_trkseg_trkpt: - tag_wpt(attr); - break; - case tt_unknown: - start_something_else(el, attr); - return; - case tt_cache: - tag_gs_cache(attr); - break; - case tt_cache_log_wpt: - if (opt_logpoint) - tag_log_wpt(attr); - break; - case tt_cache_desc_long: - case tt_cache_desc_short: - tag_cache_desc(attr); - break; - case tt_cache_placer: - if (*attr && (0 == strcmp(attr[0], "id"))) { - wpt_tmp->gc_data.placer_id = atoi(attr[1]); - } - default: - break; - } - if (passthrough) { - start_something_else(el, attr); - } - xml_free_converted_string(el); - xml_free_converted_attrs(attr); + char* e; + char* ep; + int passthrough; + const char* el = xml_convert_to_char_string(xml_el); + const char** attr = xml_convert_attrs_to_char_string(xml_attr); + + vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); + e = current_tag.mem; + ep = e + strlen(e); + *ep++ = '/'; + strcpy(ep, el); + + + /* + * FIXME: Find out why a cdatastr[0] doesn't adequately reset the + * cdata handler. + */ + memset(cdatastr.mem, 0, cdatastr.size); + + switch (get_tag(current_tag.mem, &passthrough)) { + case tt_gpx: + tag_gpx(attr); + break; + case tt_wpt: + tag_wpt(attr); + break; + case tt_wpt_link: + if (0 == strcmp(attr[0], "href")) { + link_url = attr[1]; + } + break; + case tt_wpt_link_text: + link_text = cdatastr.mem; + break; + case tt_rte: + rte_head = route_head_alloc(); + route_add_head(rte_head); + fs_ptr = &rte_head->fs; + break; + case tt_rte_rtept: + tag_wpt(attr); + break; + case tt_trk: + trk_head = route_head_alloc(); + track_add_head(trk_head); + fs_ptr = &trk_head->fs; + break; + case tt_trk_trkseg_trkpt: + tag_wpt(attr); + break; + case tt_unknown: + start_something_else(el, attr); + return; + case tt_cache: + tag_gs_cache(attr); + break; + case tt_cache_log_wpt: + if (opt_logpoint) { + tag_log_wpt(attr); + } + break; + case tt_cache_desc_long: + case tt_cache_desc_short: + tag_cache_desc(attr); + break; + case tt_cache_placer: + if (*attr && (0 == strcmp(attr[0], "id"))) { + wpt_tmp->gc_data.placer_id = atoi(attr[1]); + } + default: + break; + } + if (passthrough) { + start_something_else(el, attr); + } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); } struct -gs_type_mapping{ - geocache_type type; - const char *name; + gs_type_mapping { + geocache_type type; + const char* name; } gs_type_map[] = { - { gt_traditional, "Traditional Cache" }, - { gt_traditional, "Traditional" }, /* opencaching.de */ - { gt_multi, "Multi-cache" }, - { gt_multi, "Multi" }, /* opencaching.de */ - { gt_virtual, "Virtual Cache" }, - { gt_virtual, "Virtual" }, /* opencaching.de */ - { gt_event, "Event Cache" }, - { gt_event, "Event" }, /* opencaching.de */ - { gt_webcam, "Webcam Cache" }, - { gt_webcam, "Webcam" }, /* opencaching.de */ - { gt_suprise, "Unknown Cache" }, - { gt_earth, "Earthcache" }, - { gt_earth, "Earth" }, /* opencaching.de */ - { gt_cito, "Cache In Trash Out Event" }, - { gt_letterbox, "Letterbox Hybrid" }, - { gt_locationless, "Locationless (Reverse) Cache" }, - { gt_ape, "Project APE Cache" }, - { gt_mega, "Mega-Event Cache" }, - - { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ + { gt_traditional, "Traditional Cache" }, + { gt_traditional, "Traditional" }, /* opencaching.de */ + { gt_multi, "Multi-cache" }, + { gt_multi, "Multi" }, /* opencaching.de */ + { gt_virtual, "Virtual Cache" }, + { gt_virtual, "Virtual" }, /* opencaching.de */ + { gt_event, "Event Cache" }, + { gt_event, "Event" }, /* opencaching.de */ + { gt_webcam, "Webcam Cache" }, + { gt_webcam, "Webcam" }, /* opencaching.de */ + { gt_suprise, "Unknown Cache" }, + { gt_earth, "Earthcache" }, + { gt_earth, "Earth" }, /* opencaching.de */ + { gt_cito, "Cache In Trash Out Event" }, + { gt_letterbox, "Letterbox Hybrid" }, + { gt_locationless, "Locationless (Reverse) Cache" }, + { gt_ape, "Project APE Cache" }, + { gt_mega, "Mega-Event Cache" }, + + { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ }; struct -gs_container_mapping{ - geocache_container type; - const char *name; + gs_container_mapping { + geocache_container type; + const char* name; } gs_container_map[] = { - { gc_other, "Unknown" }, - { gc_other, "Other" }, /* Synonym on read. */ - { gc_micro, "Micro" }, - { gc_regular, "Regular" }, - { gc_large, "Large" }, - { gc_small, "Small" }, - { gc_virtual, "Virtual" } + { gc_other, "Unknown" }, + { gc_other, "Other" }, /* Synonym on read. */ + { gc_micro, "Micro" }, + { gc_regular, "Regular" }, + { gc_large, "Large" }, + { gc_small, "Small" }, + { gc_virtual, "Virtual" } }; geocache_type -gs_mktype(const char *t) +gs_mktype(const char* t) { - int i; - int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { - return gs_type_map[i].type; - } - } - return gt_unknown; + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { + return gs_type_map[i].type; + } + } + return gt_unknown; } -const char * +const char* gs_get_cachetype(geocache_type t) { - int i; - int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); - - for (i = 0; i < sz; i++) { - if (t == gs_type_map[i].type) { - return gs_type_map[i].name; - } - } - return "Unknown"; + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_type_map[i].type) { + return gs_type_map[i].name; + } + } + return "Unknown"; } geocache_container -gs_mkcont(const char *t) +gs_mkcont(const char* t) { - int i; - int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { - return gs_container_map[i].type; - } - } - return gc_unknown; + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { + return gs_container_map[i].type; + } + } + return gc_unknown; } -const char * +const char* gs_get_container(geocache_container t) { - int i; - int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); - - for (i = 0; i < sz; i++) { - if (t == gs_container_map[i].type) { - return gs_container_map[i].name; - } - } - return "Unknown"; + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_container_map[i].type) { + return gs_container_map[i].name; + } + } + return "Unknown"; } -time_t -xml_parse_time( const char *cdatastr, int *microsecs ) +time_t +xml_parse_time(const char* cdatastr, int* microsecs) { - int off_hr = 0; - int off_min = 0; - int off_sign = 1; - char *offsetstr = NULL; - char *pointstr = NULL; - struct tm tm; - time_t rv = 0; - char *timestr = xstrdup( cdatastr ); - - memset(&tm, 0, sizeof(tm)); - - offsetstr = strchr( timestr, 'Z' ); - if ( offsetstr ) { - /* zulu time; offsets stay at defaults */ - *offsetstr = '\0'; - } else { - offsetstr = strchr( timestr, '+' ); - if ( offsetstr ) { - /* positive offset; parse it */ - *offsetstr = '\0'; - sscanf( offsetstr+1, "%d:%d", &off_hr, &off_min ); - } else { - offsetstr = strchr( timestr, 'T' ); - if ( offsetstr ) { - offsetstr = strchr( offsetstr, '-' ); - if ( offsetstr ) { - /* negative offset; parse it */ - *offsetstr = '\0'; - sscanf( offsetstr+1, "%d:%d", - &off_hr, &off_min ); - off_sign = -1; - } - } - } - } - - pointstr = strchr( timestr, '.' ); - if ( pointstr ) { - if (microsecs) { - double fsec; - sscanf(pointstr, "%le", &fsec); - /* Round to avoid FP jitter */ - *microsecs = .5 + (fsec * 1000000.0) ; - } - *pointstr = '\0'; - } - - sscanf(timestr, "%d-%d-%dT%d:%d:%d", - &tm.tm_year, - &tm.tm_mon, - &tm.tm_mday, - &tm.tm_hour, - &tm.tm_min, - &tm.tm_sec); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; - - rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; - - xfree(timestr); - - return rv; + int off_hr = 0; + int off_min = 0; + int off_sign = 1; + char* offsetstr = NULL; + char* pointstr = NULL; + struct tm tm; + time_t rv = 0; + char* timestr = xstrdup(cdatastr); + + memset(&tm, 0, sizeof(tm)); + + offsetstr = strchr(timestr, 'Z'); + if (offsetstr) { + /* zulu time; offsets stay at defaults */ + *offsetstr = '\0'; + } else { + offsetstr = strchr(timestr, '+'); + if (offsetstr) { + /* positive offset; parse it */ + *offsetstr = '\0'; + sscanf(offsetstr+1, "%d:%d", &off_hr, &off_min); + } else { + offsetstr = strchr(timestr, 'T'); + if (offsetstr) { + offsetstr = strchr(offsetstr, '-'); + if (offsetstr) { + /* negative offset; parse it */ + *offsetstr = '\0'; + sscanf(offsetstr+1, "%d:%d", + &off_hr, &off_min); + off_sign = -1; + } + } + } + } + + pointstr = strchr(timestr, '.'); + if (pointstr) { + if (microsecs) { + double fsec; + sscanf(pointstr, "%le", &fsec); + /* Round to avoid FP jitter */ + *microsecs = .5 + (fsec * 1000000.0) ; + } + *pointstr = '\0'; + } + + sscanf(timestr, "%d-%d-%dT%d:%d:%d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday, + &tm.tm_hour, + &tm.tm_min, + &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + + rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; + + xfree(timestr); + + return rv; } static void -gpx_end(void *data, const XML_Char *xml_el) +gpx_end(void* data, const XML_Char* xml_el) { - const char *el = xml_convert_to_char_string(xml_el); - char *s = strrchr(current_tag.mem, '/'); - float x; - char *cdatastrp = cdatastr.mem; - int passthrough; - static time_t gc_log_date; - tag_type tag; - - if (strcmp(s + 1, el)) { - fprintf(stderr, "Mismatched tag %s\n", el); - } - - tag = get_tag(current_tag.mem, &passthrough); - switch(tag) { - /* - * First, the tags that are file-global. - */ - case tt_name: - gpx_add_to_global(&gpx_global->name, cdatastrp); - break; - case tt_desc: - gpx_add_to_global(&gpx_global->desc, cdatastrp); - break; - case tt_author: - gpx_add_to_global(&gpx_global->author, cdatastrp); - break; - case tt_email: - gpx_add_to_global(&gpx_global->email, cdatastrp); - if (gpx_email == NULL) { - gpx_email = xstrdup(cdatastrp); - } - break; - case tt_url: - gpx_add_to_global(&gpx_global->url, cdatastrp); - break; - case tt_urlname: - gpx_add_to_global(&gpx_global->urlname, cdatastrp); - break; - case tt_keywords: - gpx_add_to_global(&gpx_global->keywords, cdatastrp); - break; - - /* - * Waypoint-specific tags. - */ - case tt_wpt: - waypt_add(wpt_tmp); - logpoint_ct = 0; - cur_tag = NULL; - wpt_tmp = NULL; - break; - case tt_cache_name: - if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); - wpt_tmp->notes = xstrdup(cdatastrp); - break; - case tt_cache_container: - wpt_tmp->gc_data.container = gs_mkcont(cdatastrp); - break; - case tt_cache_type: - wpt_tmp->gc_data.type = gs_mktype(cdatastrp); - break; - case tt_cache_difficulty: - sscanf(cdatastrp, "%f", &x); - wpt_tmp->gc_data.diff = x * 10; - break; - case tt_cache_hint: - rtrim(cdatastrp); - if (cdatastrp[0]) { - wpt_tmp->gc_data.hint = xstrdup(cdatastrp); - } - break; - case tt_cache_desc_long: - rtrim(cdatastrp); - if (cdatastrp[0]) { - wpt_tmp->gc_data.desc_long.is_html = cache_descr_is_html; - wpt_tmp->gc_data.desc_long.utfstring = xstrdup(cdatastrp); - } - break; - case tt_cache_desc_short: - rtrim(cdatastrp); - if (cdatastrp[0]) { - wpt_tmp->gc_data.desc_short.is_html = cache_descr_is_html; - wpt_tmp->gc_data.desc_short.utfstring = xstrdup(cdatastrp); - } - break; - case tt_cache_terrain: - sscanf(cdatastrp, "%f", &x); - wpt_tmp->gc_data.terr = x * 10; - break; - case tt_cache_placer: - wpt_tmp->gc_data.placer = xstrdup(cdatastrp); - break; - case tt_cache_log_date: - gc_log_date = xml_parse_time( cdatastrp, NULL ); - break; - /* - * "Found it" logs follow the date according to the schema, - * if this is the first "found it" for this waypt, just use the - * last date we saw in this log. - */ - case tt_cache_log_type: - if ((0 == strcmp(cdatastrp, "Found it")) && - (0 == wpt_tmp->gc_data.last_found)) { - wpt_tmp->gc_data.last_found = gc_log_date; - } - gc_log_date = 0; - break; - - /* - * Garmin-waypoint-specific tags. - */ - case tt_garmin_wpt_proximity: - case tt_garmin_wpt_temperature: - case tt_garmin_wpt_depth: - case tt_garmin_wpt_display_mode: - case tt_garmin_wpt_category: - case tt_garmin_wpt_addr: - case tt_garmin_wpt_city: - case tt_garmin_wpt_state: - case tt_garmin_wpt_country: - case tt_garmin_wpt_postal_code: - case tt_garmin_wpt_phone_nr: - garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); - break; - - /* - * Route-specific tags. - */ - case tt_rte_name: - rte_head->rte_name = xstrdup(cdatastrp); - break; - case tt_rte: - break; - case tt_rte_rtept: - route_add_wpt(rte_head, wpt_tmp); - wpt_tmp = NULL; - break; - case tt_rte_desc: - rte_head->rte_desc = xstrdup(cdatastrp); - break; - case tt_rte_number: - rte_head->rte_num = atoi(cdatastrp); - break; - /* - * Track-specific tags. - */ - case tt_trk_name: - trk_head->rte_name = xstrdup(cdatastrp); - break; - case tt_trk: - break; - case tt_trk_trkseg_trkpt: - track_add_wpt(trk_head, wpt_tmp); - wpt_tmp = NULL; - break; - case tt_trk_desc: - trk_head->rte_desc = xstrdup(cdatastrp); - break; - case tt_trk_number: - trk_head->rte_num = atoi(cdatastrp); - break; - case tt_trk_trkseg_trkpt_course: - WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); - break; - case tt_trk_trkseg_trkpt_speed: - WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); - break; - - /* - * Items that are actually in multiple categories. - */ - case tt_wpt_ele: - case tt_rte_rtept_ele: - case tt_trk_trkseg_trkpt_ele: - sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); - break; - case tt_wpt_name: - case tt_rte_rtept_name: - case tt_trk_trkseg_trkpt_name: - wpt_tmp->shortname = xstrdup(cdatastrp); - break; - case tt_wpt_sym: - case tt_rte_rtept_sym: - case tt_trk_trkseg_trkpt_sym: - wpt_tmp->icon_descr = xstrdup(cdatastrp); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - break; - case tt_wpt_time: - case tt_trk_trkseg_trkpt_time: - case tt_rte_rtept_time: - wpt_tmp->creation_time = xml_parse_time( cdatastrp, &wpt_tmp->microseconds ); - break; - case tt_wpt_cmt: - case tt_rte_rtept_cmt: - case tt_trk_trkseg_trkpt_cmt: - wpt_tmp->description = xstrdup(cdatastrp); - break; - case tt_wpt_desc: - case tt_trk_trkseg_trkpt_desc: - case tt_rte_rtept_desc: - if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); - wpt_tmp->notes = xstrdup(cdatastrp); - break; - case tt_pdop: - wpt_tmp->pdop = atof(cdatastrp); - break; - case tt_hdop: - wpt_tmp->hdop = atof(cdatastrp); - break; - case tt_vdop: - wpt_tmp->vdop = atof(cdatastrp); - break; - case tt_sat: - wpt_tmp->sat = atof(cdatastrp); - break; - case tt_fix: - wpt_tmp->fix = atoi(cdatastrp)-1; - if ( wpt_tmp->fix < fix_2d) { - if (!case_ignore_strcmp(cdatastrp, "none")) - wpt_tmp->fix = fix_none; - else if (!case_ignore_strcmp(cdatastrp, "dgps")) - wpt_tmp->fix = fix_dgps; - else if (!case_ignore_strcmp(cdatastrp, "pps")) - wpt_tmp->fix = fix_pps; - else - wpt_tmp->fix = fix_unknown; - } - break; - case tt_wpt_url: - case tt_trk_trkseg_trkpt_url: - case tt_rte_rtept_url: - wpt_tmp->url = xstrdup(cdatastrp); - break; - case tt_wpt_urlname: - case tt_trk_trkseg_trkpt_urlname: - case tt_rte_rtept_urlname: - wpt_tmp->url_link_text = xstrdup(cdatastrp); - break; - case tt_wpt_link: -//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: -//TODO: implement GPX 1.1 case tt_rte_rtept_link: - { - char *lt = link_text; - if (lt) { - lt = xstrdup(lrtrim(link_text)); - } - - waypt_add_url(wpt_tmp, xstrdup(link_url), lt); - link_text = NULL; - } - break; - case tt_unknown: - end_something_else(); - *s = 0; - return; - default: - break; - } - - if (passthrough) { - end_something_else(); - } - - *s = 0; - xml_free_converted_string(el); + const char* el = xml_convert_to_char_string(xml_el); + char* s = strrchr(current_tag.mem, '/'); + float x; + char* cdatastrp = cdatastr.mem; + int passthrough; + static time_t gc_log_date; + tag_type tag; + + if (strcmp(s + 1, el)) { + fprintf(stderr, "Mismatched tag %s\n", el); + } + + tag = get_tag(current_tag.mem, &passthrough); + switch (tag) { + /* + * First, the tags that are file-global. + */ + case tt_name: + gpx_add_to_global(&gpx_global->name, cdatastrp); + break; + case tt_desc: + gpx_add_to_global(&gpx_global->desc, cdatastrp); + break; + case tt_author: + gpx_add_to_global(&gpx_global->author, cdatastrp); + break; + case tt_email: + gpx_add_to_global(&gpx_global->email, cdatastrp); + if (gpx_email == NULL) { + gpx_email = xstrdup(cdatastrp); + } + break; + case tt_url: + gpx_add_to_global(&gpx_global->url, cdatastrp); + break; + case tt_urlname: + gpx_add_to_global(&gpx_global->urlname, cdatastrp); + break; + case tt_keywords: + gpx_add_to_global(&gpx_global->keywords, cdatastrp); + break; + + /* + * Waypoint-specific tags. + */ + case tt_wpt: + waypt_add(wpt_tmp); + logpoint_ct = 0; + cur_tag = NULL; + wpt_tmp = NULL; + break; + case tt_cache_name: + if (wpt_tmp->notes != NULL) { + xfree(wpt_tmp->notes); + } + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_cache_container: + wpt_tmp->gc_data.container = gs_mkcont(cdatastrp); + break; + case tt_cache_type: + wpt_tmp->gc_data.type = gs_mktype(cdatastrp); + break; + case tt_cache_difficulty: + sscanf(cdatastrp, "%f", &x); + wpt_tmp->gc_data.diff = x * 10; + break; + case tt_cache_hint: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.hint = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_long: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.desc_long.is_html = cache_descr_is_html; + wpt_tmp->gc_data.desc_long.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_short: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.desc_short.is_html = cache_descr_is_html; + wpt_tmp->gc_data.desc_short.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_terrain: + sscanf(cdatastrp, "%f", &x); + wpt_tmp->gc_data.terr = x * 10; + break; + case tt_cache_placer: + wpt_tmp->gc_data.placer = xstrdup(cdatastrp); + break; + case tt_cache_log_date: + gc_log_date = xml_parse_time(cdatastrp, NULL); + break; + /* + * "Found it" logs follow the date according to the schema, + * if this is the first "found it" for this waypt, just use the + * last date we saw in this log. + */ + case tt_cache_log_type: + if ((0 == strcmp(cdatastrp, "Found it")) && + (0 == wpt_tmp->gc_data.last_found)) { + wpt_tmp->gc_data.last_found = gc_log_date; + } + gc_log_date = 0; + break; + + /* + * Garmin-waypoint-specific tags. + */ + case tt_garmin_wpt_proximity: + case tt_garmin_wpt_temperature: + case tt_garmin_wpt_depth: + case tt_garmin_wpt_display_mode: + case tt_garmin_wpt_category: + case tt_garmin_wpt_addr: + case tt_garmin_wpt_city: + case tt_garmin_wpt_state: + case tt_garmin_wpt_country: + case tt_garmin_wpt_postal_code: + case tt_garmin_wpt_phone_nr: + garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); + break; + + /* + * Route-specific tags. + */ + case tt_rte_name: + rte_head->rte_name = xstrdup(cdatastrp); + break; + case tt_rte: + break; + case tt_rte_rtept: + route_add_wpt(rte_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_rte_desc: + rte_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_rte_number: + rte_head->rte_num = atoi(cdatastrp); + break; + /* + * Track-specific tags. + */ + case tt_trk_name: + trk_head->rte_name = xstrdup(cdatastrp); + break; + case tt_trk: + break; + case tt_trk_trkseg_trkpt: + track_add_wpt(trk_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_trk_desc: + trk_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_trk_number: + trk_head->rte_num = atoi(cdatastrp); + break; + case tt_trk_trkseg_trkpt_course: + WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); + break; + case tt_trk_trkseg_trkpt_speed: + WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); + break; + + /* + * Items that are actually in multiple categories. + */ + case tt_wpt_ele: + case tt_rte_rtept_ele: + case tt_trk_trkseg_trkpt_ele: + sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); + break; + case tt_wpt_name: + case tt_rte_rtept_name: + case tt_trk_trkseg_trkpt_name: + wpt_tmp->shortname = xstrdup(cdatastrp); + break; + case tt_wpt_sym: + case tt_rte_rtept_sym: + case tt_trk_trkseg_trkpt_sym: + wpt_tmp->icon_descr = xstrdup(cdatastrp); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case tt_wpt_time: + case tt_trk_trkseg_trkpt_time: + case tt_rte_rtept_time: + wpt_tmp->creation_time = xml_parse_time(cdatastrp, &wpt_tmp->microseconds); + break; + case tt_wpt_cmt: + case tt_rte_rtept_cmt: + case tt_trk_trkseg_trkpt_cmt: + wpt_tmp->description = xstrdup(cdatastrp); + break; + case tt_wpt_desc: + case tt_trk_trkseg_trkpt_desc: + case tt_rte_rtept_desc: + if (wpt_tmp->notes != NULL) { + xfree(wpt_tmp->notes); + } + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_pdop: + wpt_tmp->pdop = atof(cdatastrp); + break; + case tt_hdop: + wpt_tmp->hdop = atof(cdatastrp); + break; + case tt_vdop: + wpt_tmp->vdop = atof(cdatastrp); + break; + case tt_sat: + wpt_tmp->sat = atof(cdatastrp); + break; + case tt_fix: + wpt_tmp->fix = atoi(cdatastrp)-1; + if (wpt_tmp->fix < fix_2d) { + if (!case_ignore_strcmp(cdatastrp, "none")) { + wpt_tmp->fix = fix_none; + } else if (!case_ignore_strcmp(cdatastrp, "dgps")) { + wpt_tmp->fix = fix_dgps; + } else if (!case_ignore_strcmp(cdatastrp, "pps")) { + wpt_tmp->fix = fix_pps; + } else { + wpt_tmp->fix = fix_unknown; + } + } + break; + case tt_wpt_url: + case tt_trk_trkseg_trkpt_url: + case tt_rte_rtept_url: + wpt_tmp->url = xstrdup(cdatastrp); + break; + case tt_wpt_urlname: + case tt_trk_trkseg_trkpt_urlname: + case tt_rte_rtept_urlname: + wpt_tmp->url_link_text = xstrdup(cdatastrp); + break; + case tt_wpt_link: +//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: +//TODO: implement GPX 1.1 case tt_rte_rtept_link: + { + char* lt = link_text; + if (lt) { + lt = xstrdup(lrtrim(link_text)); + } + + waypt_add_url(wpt_tmp, xstrdup(link_url), lt); + link_text = NULL; + } + break; + case tt_unknown: + end_something_else(); + *s = 0; + return; + default: + break; + } + + if (passthrough) { + end_something_else(); + } + + *s = 0; + xml_free_converted_string(el); } #if ! HAVE_LIBEXPAT static void -gpx_rd_init(const char *fname) +gpx_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); } -static void -gpx_rd_deinit(void) +static void +gpx_rd_deinit(void) { } #else /* NO_EXPAT */ static void -gpx_cdata(void *dta, const XML_Char *xml_el, int len) +gpx_cdata(void* dta, const XML_Char* xml_el, int len) { - char *estr; - int *cdatalen; - char **cdata; - xml_tag *tmp_tag; - size_t slen = strlen(cdatastr.mem); - const char *s = xml_convert_to_char_string_n(xml_el, &len); - - vmem_realloc(&cdatastr, 1 + len + slen); - estr = ((char *) cdatastr.mem) + slen; - memcpy(estr, s, len); - estr[len] = 0; - - if (!cur_tag) - return; - - if ( cur_tag->child ) { - tmp_tag = cur_tag->child; - while ( tmp_tag->sibling ) { - tmp_tag = tmp_tag->sibling; - } - cdata = &(tmp_tag->parentcdata); - cdatalen = &(tmp_tag->parentcdatalen); - } - else { - cdata = &(cur_tag->cdata); - cdatalen = &(cur_tag->cdatalen); - } - estr = *cdata; - *cdata = xcalloc( *cdatalen + len + 1, 1); - if ( estr ) { - memcpy( *cdata, estr, *cdatalen); - xfree( estr ); - } - estr = *cdata + *cdatalen; - memcpy( estr, s, len ); - *(estr+len) = '\0'; - *cdatalen += len; - - xml_free_converted_string(s); + char* estr; + int* cdatalen; + char** cdata; + xml_tag* tmp_tag; + size_t slen = strlen(cdatastr.mem); + const char* s = xml_convert_to_char_string_n(xml_el, &len); + + vmem_realloc(&cdatastr, 1 + len + slen); + estr = ((char*) cdatastr.mem) + slen; + memcpy(estr, s, len); + estr[len] = 0; + + if (!cur_tag) { + return; + } + + if (cur_tag->child) { + tmp_tag = cur_tag->child; + while (tmp_tag->sibling) { + tmp_tag = tmp_tag->sibling; + } + cdata = &(tmp_tag->parentcdata); + cdatalen = &(tmp_tag->parentcdatalen); + } else { + cdata = &(cur_tag->cdata); + cdatalen = &(cur_tag->cdatalen); + } + estr = *cdata; + *cdata = xcalloc(*cdatalen + len + 1, 1); + if (estr) { + memcpy(*cdata, estr, *cdatalen); + xfree(estr); + } + estr = *cdata + *cdatalen; + memcpy(estr, s, len); + *(estr+len) = '\0'; + *cdatalen += len; + + xml_free_converted_string(s); } static void -gpx_rd_init(const char *fname) +gpx_rd_init(const char* fname) { - if ( fname[0] ) { - fd = gbfopen(fname, "r", MYNAME); - input_fname = fname; - } - else { - fd = NULL; - input_string = fname+1; - input_string_len = strlen(input_string); - input_fname = NULL; - } - - - file_time = 0; - current_tag = vmem_alloc(1, 0); - *((char *)current_tag.mem) = '\0'; - - prescan_tags(); - - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ": Cannot create XML Parser\n"); - } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - - cdatastr = vmem_alloc(1, 0); - *((char *)cdatastr.mem) = '\0'; - - if (!xsi_schema_loc) { - xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); - } - if (!xsi_schema_loc) { - fatal("gpx: Unable to allocate %ld bytes of memory.\n", - (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); - } - - if (NULL == gpx_global) { - gpx_global = xcalloc(sizeof(*gpx_global), 1); - QUEUE_INIT(&gpx_global->name.queue); - QUEUE_INIT(&gpx_global->desc.queue); - QUEUE_INIT(&gpx_global->author.queue); - QUEUE_INIT(&gpx_global->email.queue); - QUEUE_INIT(&gpx_global->url.queue); - QUEUE_INIT(&gpx_global->urlname.queue); - QUEUE_INIT(&gpx_global->keywords.queue); - } - - XML_SetElementHandler(psr, gpx_start, gpx_end); - XML_SetCharacterDataHandler(psr, gpx_cdata); - fs_ptr = NULL; + if (fname[0]) { + fd = gbfopen(fname, "r", MYNAME); + input_fname = fname; + } else { + fd = NULL; + input_string = fname+1; + input_string_len = strlen(input_string); + input_fname = NULL; + } + + + file_time = 0; + current_tag = vmem_alloc(1, 0); + *((char*)current_tag.mem) = '\0'; + + prescan_tags(); + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ": Cannot create XML Parser\n"); + } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + + cdatastr = vmem_alloc(1, 0); + *((char*)cdatastr.mem) = '\0'; + + if (!xsi_schema_loc) { + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); + } + if (!xsi_schema_loc) { + fatal("gpx: Unable to allocate %ld bytes of memory.\n", + (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); + } + + if (NULL == gpx_global) { + gpx_global = xcalloc(sizeof(*gpx_global), 1); + QUEUE_INIT(&gpx_global->name.queue); + QUEUE_INIT(&gpx_global->desc.queue); + QUEUE_INIT(&gpx_global->author.queue); + QUEUE_INIT(&gpx_global->email.queue); + QUEUE_INIT(&gpx_global->url.queue); + QUEUE_INIT(&gpx_global->urlname.queue); + QUEUE_INIT(&gpx_global->keywords.queue); + } + + XML_SetElementHandler(psr, gpx_start, gpx_end); + XML_SetCharacterDataHandler(psr, gpx_cdata); + fs_ptr = NULL; } -static -void -gpx_rd_deinit(void) +static +void +gpx_rd_deinit(void) { - vmem_free(¤t_tag); - vmem_free(&cdatastr); - /* - * Don't free schema_loc. It really is important that we preserve - * this across reads or else merges/copies of files with different - * schemas won't retain the headers. - * - * moved to gpx_exit - - if ( xsi_schema_loc ) { - xfree(xsi_schema_loc); - xsi_schema_loc = NULL; - } - */ - - if ( gpx_email ) { - xfree(gpx_email); - gpx_email = NULL; - } - if ( gpx_author ) { - xfree(gpx_author); - gpx_author = NULL; - } - if (fd) { - gbfclose(fd); - } - XML_ParserFree(psr); - psr = NULL; - wpt_tmp = NULL; - cur_tag = NULL; - input_fname = NULL; + vmem_free(¤t_tag); + vmem_free(&cdatastr); + /* + * Don't free schema_loc. It really is important that we preserve + * this across reads or else merges/copies of files with different + * schemas won't retain the headers. + * + * moved to gpx_exit + + if ( xsi_schema_loc ) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + */ + + if (gpx_email) { + xfree(gpx_email); + gpx_email = NULL; + } + if (gpx_author) { + xfree(gpx_author); + gpx_author = NULL; + } + if (fd) { + gbfclose(fd); + } + XML_ParserFree(psr); + psr = NULL; + wpt_tmp = NULL; + cur_tag = NULL; + input_fname = NULL; } #endif static void -gpx_wr_init(const char *fname) +gpx_wr_init(const char* fname) { - mkshort_handle = mkshort_new_handle(); + mkshort_handle = mkshort_new_handle(); - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void gpx_wr_deinit(void) { - gbfclose(ofd); - mkshort_del_handle(&mkshort_handle); + gbfclose(ofd); + mkshort_del_handle(&mkshort_handle); } void gpx_read(void) { #if HAVE_LIBEXPAT - int len; - int done = 0; - char *buf = xmalloc(MY_CBUF_SZ); - int result = 0; - int extra; - - while (!done) { - if ( fd ) { - /* - * The majority of this block (in fact, all but the - * call to XML_Parse) are a disgusting hack to - * correct defective GPX files that Geocaching.com - * issues as pocket queries. They contain escape - * characters as entities (�-) which makes - * them not validate which croaks expat and torments - * users. - * - * Look for '&' in the last maxentlength chars. If - * we find it, strip it, then read byte-at-a-time - * until we find a non-entity. - */ - char *badchar; - char *semi; - int maxentlength = 8; - len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); - done = gbfeof(fd) || !len; - buf[len] = '\0'; - if (len < maxentlength) { - maxentlength = len; - } - badchar = buf+len-maxentlength; - badchar = strchr( badchar, '&' ); - extra = maxentlength - 1; /* for terminator */ - while ( badchar && len < MY_CBUF_SZ-1) { - semi = strchr( badchar, ';'); - while ( extra && !semi ) { - len += gbfread( buf+len, 1, 1, fd); - buf[len]='\0'; - extra--; - if ( buf[len-1] == ';') - semi= buf+len-1; - } - badchar = strchr( badchar+1, '&' ); - } - { - char *hex="0123456789abcdef"; - badchar = strstr( buf, "&#x" ); - while ( badchar ) { - int val = 0; - char *hexit = badchar+3; - semi = strchr( badchar, ';' ); - if ( semi ) { - while (*hexit && *hexit != ';') { - char hc = isalpha(*hexit) ? tolower (*hexit) : *hexit; - val *= 16; - val += strchr( hex, hc)-hex; - hexit++; - } - - if ( val < 32 ) { - warning( MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)" ); - memmove( badchar, semi+1, strlen(semi+1)+1 ); - len -= (semi-badchar)+1; - badchar--; - } - } - badchar = strstr( badchar+1, "&#x" ); - } - } - result = XML_Parse(psr, buf, len, done); - } - else if (input_string) { - done = 0; - result = XML_Parse(psr, input_string, - input_string_len, done ); - done = 1; - } - else { - done = 1; - result = -1; - } - if (!result) { - fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", - (int) XML_GetCurrentLineNumber(psr), - input_fname ? input_fname : "unknown file", - XML_ErrorString(XML_GetErrorCode(psr))); - } - } - xfree(buf); + int len; + int done = 0; + char* buf = xmalloc(MY_CBUF_SZ); + int result = 0; + int extra; + + while (!done) { + if (fd) { + /* + * The majority of this block (in fact, all but the + * call to XML_Parse) are a disgusting hack to + * correct defective GPX files that Geocaching.com + * issues as pocket queries. They contain escape + * characters as entities (�-) which makes + * them not validate which croaks expat and torments + * users. + * + * Look for '&' in the last maxentlength chars. If + * we find it, strip it, then read byte-at-a-time + * until we find a non-entity. + */ + char* badchar; + char* semi; + int maxentlength = 8; + len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); + done = gbfeof(fd) || !len; + buf[len] = '\0'; + if (len < maxentlength) { + maxentlength = len; + } + badchar = buf+len-maxentlength; + badchar = strchr(badchar, '&'); + extra = maxentlength - 1; /* for terminator */ + while (badchar && len < MY_CBUF_SZ-1) { + semi = strchr(badchar, ';'); + while (extra && !semi) { + len += gbfread(buf+len, 1, 1, fd); + buf[len]='\0'; + extra--; + if (buf[len-1] == ';') { + semi= buf+len-1; + } + } + badchar = strchr(badchar+1, '&'); + } + { + char* hex="0123456789abcdef"; + badchar = strstr(buf, "&#x"); + while (badchar) { + int val = 0; + char* hexit = badchar+3; + semi = strchr(badchar, ';'); + if (semi) { + while (*hexit && *hexit != ';') { + char hc = isalpha(*hexit) ? tolower(*hexit) : *hexit; + val *= 16; + val += strchr(hex, hc)-hex; + hexit++; + } + + if (val < 32) { + warning(MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)"); + memmove(badchar, semi+1, strlen(semi+1)+1); + len -= (semi-badchar)+1; + badchar--; + } + } + badchar = strstr(badchar+1, "&#x"); + } + } + result = XML_Parse(psr, buf, len, done); + } else if (input_string) { + done = 0; + result = XML_Parse(psr, input_string, + input_string_len, done); + done = 1; + } else { + done = 1; + result = -1; + } + if (!result) { + fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", + (int) XML_GetCurrentLineNumber(psr), + input_fname ? input_fname : "unknown file", + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + xfree(buf); #endif /* HAVE_LIBEXPAT */ } static void -fprint_tag_and_attrs( char *prefix, char *suffix, xml_tag *tag ) +fprint_tag_and_attrs(char* prefix, char* suffix, xml_tag* tag) { - char **pa; - gbfprintf( ofd, "%s%s", prefix, tag->tagname ); - pa = tag->attributes; - if ( pa ) { - while ( *pa ) { - gbfprintf( ofd, " %s=\"%s\"", pa[0], pa[1] ); - pa += 2; - } - } - gbfprintf( ofd, "%s", suffix ); + char** pa; + gbfprintf(ofd, "%s%s", prefix, tag->tagname); + pa = tag->attributes; + if (pa) { + while (*pa) { + gbfprintf(ofd, " %s=\"%s\"", pa[0], pa[1]); + pa += 2; + } + } + gbfprintf(ofd, "%s", suffix); } static void -fprint_xml_chain( xml_tag *tag, const waypoint *wpt ) +fprint_xml_chain(xml_tag* tag, const waypoint* wpt) { - char *tmp_ent; - while ( tag ) { - if ( !tag->cdata && !tag->child ) { - fprint_tag_and_attrs( "<", " />", tag ); - } - else { - fprint_tag_and_attrs( "<", ">", tag ); - - if ( tag->cdata ) { - tmp_ent = xml_entitize( tag->cdata ); - gbfprintf( ofd, "%s", tmp_ent ); - xfree(tmp_ent); - } - if ( tag->child ) { - fprint_xml_chain(tag->child, wpt); - } - if ( wpt && wpt->gc_data.exported && - strcmp(tag->tagname, "groundspeak:cache" ) == 0 ) { - xml_write_time( ofd, wpt->gc_data.exported, 0, - "groundspeak:exported" ); - } - gbfprintf( ofd, "\n", tag->tagname); - } - if ( tag->parentcdata ) { - tmp_ent = xml_entitize(tag->parentcdata); - gbfprintf(ofd, "%s", tmp_ent ); - xfree(tmp_ent); - } - tag = tag->sibling; - } -} - -void free_gpx_extras( xml_tag *tag ) + char* tmp_ent; + while (tag) { + if (!tag->cdata && !tag->child) { + fprint_tag_and_attrs("<", " />", tag); + } else { + fprint_tag_and_attrs("<", ">", tag); + + if (tag->cdata) { + tmp_ent = xml_entitize(tag->cdata); + gbfprintf(ofd, "%s", tmp_ent); + xfree(tmp_ent); + } + if (tag->child) { + fprint_xml_chain(tag->child, wpt); + } + if (wpt && wpt->gc_data.exported && + strcmp(tag->tagname, "groundspeak:cache") == 0) { + xml_write_time(ofd, wpt->gc_data.exported, 0, + "groundspeak:exported"); + } + gbfprintf(ofd, "\n", tag->tagname); + } + if (tag->parentcdata) { + tmp_ent = xml_entitize(tag->parentcdata); + gbfprintf(ofd, "%s", tmp_ent); + xfree(tmp_ent); + } + tag = tag->sibling; + } +} + +void free_gpx_extras(xml_tag* tag) { - xml_tag *next = NULL; - char **ap; - - while ( tag ) { - if (tag->cdata) { - xfree(tag->cdata); - } - if (tag->child) { - free_gpx_extras(tag->child); - } - if (tag->parentcdata) { - xfree(tag->parentcdata); - } - if (tag->tagname) { - xfree(tag->tagname); - } - if (tag->attributes) { - ap = tag->attributes; - - while (*ap) - xfree(*ap++); - - xfree(tag->attributes); - } - - next = tag->sibling; - xfree(tag); - tag = next; - } + xml_tag* next = NULL; + char** ap; + + while (tag) { + if (tag->cdata) { + xfree(tag->cdata); + } + if (tag->child) { + free_gpx_extras(tag->child); + } + if (tag->parentcdata) { + xfree(tag->parentcdata); + } + if (tag->tagname) { + xfree(tag->tagname); + } + if (tag->attributes) { + ap = tag->attributes; + + while (*ap) { + xfree(*ap++); + } + + xfree(tag->attributes); + } + + next = tag->sibling; + xfree(tag); + tag = next; + } } /* * Handle the grossness of GPX 1.0 vs. 1.1 handling of linky links. */ static void -write_gpx_url(const waypoint *waypointp) +write_gpx_url(const waypoint* waypointp) { - char *tmp_ent; - - if (waypointp->url == NULL) { - return; - } - - if (gpx_wversion_num > 10) { - url_link *tail; - for (tail = (url_link *)&waypointp->url_next; tail; tail = tail->url_next) { - tmp_ent = xml_entitize(tail->url); - gbfprintf(ofd, " \n", - urlbase ? urlbase : "", tmp_ent); - write_optional_xml_entity(ofd, " ", "text", - tail->url_link_text); - gbfprintf(ofd, " \n"); - xfree(tmp_ent); - } - } else { - tmp_ent = xml_entitize(waypointp->url); - gbfprintf(ofd, " %s%s\n", - urlbase ? urlbase : "", tmp_ent); - write_optional_xml_entity(ofd, " ", "urlname", - waypointp->url_link_text); - xfree(tmp_ent); - } + char* tmp_ent; + + if (waypointp->url == NULL) { + return; + } + + if (gpx_wversion_num > 10) { + url_link* tail; + for (tail = (url_link*)&waypointp->url_next; tail; tail = tail->url_next) { + tmp_ent = xml_entitize(tail->url); + gbfprintf(ofd, " \n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "text", + tail->url_link_text); + gbfprintf(ofd, " \n"); + xfree(tmp_ent); + } + } else { + tmp_ent = xml_entitize(waypointp->url); + gbfprintf(ofd, " %s%s\n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "urlname", + waypointp->url_link_text); + xfree(tmp_ent); + } } /* @@ -1389,385 +1387,398 @@ write_gpx_url(const waypoint *waypointp) * Order counts. */ static void -gpx_write_common_acc(const waypoint *waypointp, const char *indent) +gpx_write_common_acc(const waypoint* waypointp, const char* indent) { - char *fix = NULL; - - switch (waypointp->fix) { - case fix_2d: - fix = "2d"; - break; - case fix_3d: - fix = "3d"; - break; - case fix_dgps: - fix = "dgps"; - break; - case fix_pps: - fix = "pps"; - break; - case fix_none: - fix = "none"; - break; - /* GPX spec says omit if we don't know. */ - case fix_unknown: - default: - break; - } - if (fix) { - gbfprintf(ofd, "%s%s\n", indent, fix); - } - if (waypointp->sat > 0) { - gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); - } - if (waypointp->hdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); - } - if (waypointp->vdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); - } - if (waypointp->pdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); - } + char* fix = NULL; + + switch (waypointp->fix) { + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + case fix_none: + fix = "none"; + break; + /* GPX spec says omit if we don't know. */ + case fix_unknown: + default: + break; + } + if (fix) { + gbfprintf(ofd, "%s%s\n", indent, fix); + } + if (waypointp->sat > 0) { + gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); + } + if (waypointp->hdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); + } + if (waypointp->vdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); + } + if (waypointp->pdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); + } } static void -gpx_write_common_position(const waypoint *waypointp, const char *indent) +gpx_write_common_position(const waypoint* waypointp, const char* indent) { - if (waypointp->altitude != unknown_alt) { - gbfprintf(ofd, "%s%f\n", - indent, waypointp->altitude); - } - if (waypointp->creation_time) { - xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); - } + if (waypointp->altitude != unknown_alt) { + gbfprintf(ofd, "%s%f\n", + indent, waypointp->altitude); + } + if (waypointp->creation_time) { + xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); + } } static void -gpx_write_common_description(const waypoint *waypointp, const char *indent, - const char *oname) +gpx_write_common_description(const waypoint* waypointp, const char* indent, + const char* oname) { - write_optional_xml_entity(ofd, indent, "name", oname); - write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); - if (waypointp->notes && waypointp->notes[0]) - write_xml_entity(ofd, indent, "desc", waypointp->notes); - else - write_optional_xml_entity(ofd, indent, "desc", waypointp->description); - write_gpx_url(waypointp); - write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); + write_optional_xml_entity(ofd, indent, "name", oname); + write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); + if (waypointp->notes && waypointp->notes[0]) { + write_xml_entity(ofd, indent, "desc", waypointp->notes); + } else { + write_optional_xml_entity(ofd, indent, "desc", waypointp->description); + } + write_gpx_url(waypointp); + write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); } static void -gpx_waypt_pr(const waypoint *waypointp) +gpx_waypt_pr(const waypoint* waypointp) { - const char *oname; - char *odesc; - fs_xml *fs_gpx; - garmin_fs_t *gmsd; /* gARmIN sPECIAL dATA */ - - /* - * Desparation time, try very hard to get a good shortname - */ - odesc = waypointp->notes; - if (!odesc) { - odesc = waypointp->description; - } - if (!odesc) { - odesc = waypointp->shortname; - } - - oname = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, odesc) : - waypointp->shortname; - - gbfprintf(ofd, "\n", - waypointp->latitude, - waypointp->longitude); - - gpx_write_common_position(waypointp, " "); - gpx_write_common_description(waypointp, " ", oname); - gpx_write_common_acc(waypointp, " "); - - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - gmsd = GMSD_FIND(waypointp); - if ( fs_gpx ) { - if (! gmsd) fprint_xml_chain( fs_gpx->tag, waypointp ); - } - if (gmsd && (gpx_wversion_num > 10)) { - /* MapSource doesn't accepts extensions from 1.0 */ - garmin_fs_xml_fprint(ofd, waypointp); - } - gbfprintf(ofd, "\n"); + const char* oname; + char* odesc; + fs_xml* fs_gpx; + garmin_fs_t* gmsd; /* gARmIN sPECIAL dATA */ + + /* + * Desparation time, try very hard to get a good shortname + */ + odesc = waypointp->notes; + if (!odesc) { + odesc = waypointp->description; + } + if (!odesc) { + odesc = waypointp->shortname; + } + + oname = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, odesc) : + waypointp->shortname; + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", oname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml*)fs_chain_find(waypointp->fs, FS_GPX); + gmsd = GMSD_FIND(waypointp); + if (fs_gpx) { + if (! gmsd) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } + } + if (gmsd && (gpx_wversion_num > 10)) { + /* MapSource doesn't accepts extensions from 1.0 */ + garmin_fs_xml_fprint(ofd, waypointp); + } + gbfprintf(ofd, "\n"); } static void -gpx_track_hdr(const route_head *rte) +gpx_track_hdr(const route_head* rte) { - fs_xml *fs_gpx; - - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "name", rte->rte_name); - write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); - if (rte->rte_num) { - gbfprintf(ofd, "%d\n", rte->rte_num); - } - gbfprintf(ofd, "\n"); - - fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, NULL ); - } + fs_xml* fs_gpx; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, "%d\n", rte->rte_num); + } + gbfprintf(ofd, "\n"); + + fs_gpx = (fs_xml*)fs_chain_find(rte->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, NULL); + } } static void -gpx_track_disp(const waypoint *waypointp) +gpx_track_disp(const waypoint* waypointp) { - fs_xml *fs_gpx; - - gbfprintf(ofd, "\n", - waypointp->latitude, - waypointp->longitude); - - gpx_write_common_position(waypointp, " "); - - /* These were accidentally removed from 1.1 */ - if (gpx_wversion_num == 10) { - if WAYPT_HAS(waypointp, course) { - gbfprintf(ofd, " %f\n", - waypointp->course); - } - if WAYPT_HAS(waypointp, speed) { - gbfprintf(ofd, " %f\n", - waypointp->speed); - } - } - - /* GPX doesn't require a name on output, so if we made one up - * on input, we might as well say nothing. - */ - gpx_write_common_description(waypointp, " ", - waypointp->wpt_flags.shortname_is_synthetic ? - NULL : waypointp->shortname); - gpx_write_common_acc(waypointp, " "); - - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, waypointp ); - } - - gbfprintf(ofd, "\n"); + fs_xml* fs_gpx; + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + + /* These were accidentally removed from 1.1 */ + if (gpx_wversion_num == 10) { + if WAYPT_HAS(waypointp, course) { + gbfprintf(ofd, " %f\n", + waypointp->course); + } + if WAYPT_HAS(waypointp, speed) { + gbfprintf(ofd, " %f\n", + waypointp->speed); + } + } + + /* GPX doesn't require a name on output, so if we made one up + * on input, we might as well say nothing. + */ + gpx_write_common_description(waypointp, " ", + waypointp->wpt_flags.shortname_is_synthetic ? + NULL : waypointp->shortname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml*)fs_chain_find(waypointp->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } + + gbfprintf(ofd, "\n"); } static void -gpx_track_tlr(const route_head *rte) +gpx_track_tlr(const route_head* rte) { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void gpx_track_pr() { - track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); + track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); } static void -gpx_route_hdr(const route_head *rte) +gpx_route_hdr(const route_head* rte) { - fs_xml *fs_gpx; - - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "name", rte->rte_name); - write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); - if (rte->rte_num) { - gbfprintf(ofd, " %d\n", rte->rte_num); - } - - fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, NULL ); - } + fs_xml* fs_gpx; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, " %d\n", rte->rte_num); + } + + fs_gpx = (fs_xml*)fs_chain_find(rte->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, NULL); + } } static void -gpx_route_disp(const waypoint *waypointp) +gpx_route_disp(const waypoint* waypointp) { - fs_xml *fs_gpx; + fs_xml* fs_gpx; - gbfprintf(ofd, " \n", - waypointp->latitude, - waypointp->longitude); + gbfprintf(ofd, " \n", + waypointp->latitude, + waypointp->longitude); - gpx_write_common_position(waypointp, " "); - gpx_write_common_description(waypointp, " ", waypointp->shortname); - gpx_write_common_acc(waypointp, " "); + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", waypointp->shortname); + gpx_write_common_acc(waypointp, " "); - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, waypointp ); - } + fs_gpx = (fs_xml*)fs_chain_find(waypointp->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } - gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void -gpx_route_tlr(const route_head *rte) +gpx_route_tlr(const route_head* rte) { - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void gpx_route_pr() { - /* output routes */ - route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); + /* output routes */ + route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); } static void -gpx_waypt_bound_calc(const waypoint *waypointp) +gpx_waypt_bound_calc(const waypoint* waypointp) { - waypt_add_to_bounds(&all_bounds, waypointp); + waypt_add_to_bounds(&all_bounds, waypointp); } static void gpx_write_bounds(void) { - waypt_init_bounds(&all_bounds); - - waypt_disp_all(gpx_waypt_bound_calc); - route_disp_all(NULL, NULL, gpx_waypt_bound_calc); - track_disp_all(NULL, NULL, gpx_waypt_bound_calc); - - if (waypt_bounds_valid(&all_bounds)) { - gbfprintf(ofd, "\n", - all_bounds.min_lat, all_bounds.min_lon, - all_bounds.max_lat, all_bounds.max_lon); - } + waypt_init_bounds(&all_bounds); + + waypt_disp_all(gpx_waypt_bound_calc); + route_disp_all(NULL, NULL, gpx_waypt_bound_calc); + track_disp_all(NULL, NULL, gpx_waypt_bound_calc); + + if (waypt_bounds_valid(&all_bounds)) { + gbfprintf(ofd, "\n", + all_bounds.min_lat, all_bounds.min_lon, + all_bounds.max_lat, all_bounds.max_lon); + } } static void gpx_write(void) { - time_t now = 0; - int short_length; - - gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; - - if (gpx_wversion_num <= 0) { - fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); - } - - now = current_time(); - - short_length = atoi(snlen); - - if (suppresswhite) { - setshort_whitespace_ok(mkshort_handle, 0); - } - - setshort_length(mkshort_handle, short_length); - - gbfprintf(ofd, "\n", global_opts.charset_name); - gbfprintf(ofd, "\n", xsi_schema_loc); - } else { - gbfprintf(ofd, - "xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", - gpx_wversion[0], gpx_wversion[2], - gpx_wversion[0], gpx_wversion[2]); - } - - if (gpx_wversion_num > 10) { - gbfprintf(ofd, "\n"); - } - gpx_write_gdata(&gpx_global->name, "name"); - gpx_write_gdata(&gpx_global->desc, "desc"); - /* In GPX 1.1, author changed from a string to a PersonType. - * since it's optional, we just drop it instead of rewriting it. - */ - if (gpx_wversion_num < 11) { - gpx_write_gdata(&gpx_global->author, "author"); - } - gpx_write_gdata(&gpx_global->email, "email"); - gpx_write_gdata(&gpx_global->url, "url"); - gpx_write_gdata(&gpx_global->urlname, "urlname"); - xml_write_time( ofd, now, 0, "time" ); - gpx_write_gdata(&gpx_global->keywords, "keywords"); - - gpx_write_bounds(); - - if (gpx_wversion_num > 10) { - gbfprintf(ofd, "\n"); - } - - waypt_disp_all(gpx_waypt_pr); - gpx_route_pr(); - gpx_track_pr(); - - gbfprintf(ofd, "\n"); + time_t now = 0; + int short_length; + + gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; + + if (gpx_wversion_num <= 0) { + fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); + } + + now = current_time(); + + short_length = atoi(snlen); + + if (suppresswhite) { + setshort_whitespace_ok(mkshort_handle, 0); + } + + setshort_length(mkshort_handle, short_length); + + gbfprintf(ofd, "\n", global_opts.charset_name); + gbfprintf(ofd, "\n", xsi_schema_loc); + } else { + gbfprintf(ofd, + "xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", + gpx_wversion[0], gpx_wversion[2], + gpx_wversion[0], gpx_wversion[2]); + } + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + gpx_write_gdata(&gpx_global->name, "name"); + gpx_write_gdata(&gpx_global->desc, "desc"); + /* In GPX 1.1, author changed from a string to a PersonType. + * since it's optional, we just drop it instead of rewriting it. + */ + if (gpx_wversion_num < 11) { + gpx_write_gdata(&gpx_global->author, "author"); + } + gpx_write_gdata(&gpx_global->email, "email"); + gpx_write_gdata(&gpx_global->url, "url"); + gpx_write_gdata(&gpx_global->urlname, "urlname"); + xml_write_time(ofd, now, 0, "time"); + gpx_write_gdata(&gpx_global->keywords, "keywords"); + + gpx_write_bounds(); + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + + waypt_disp_all(gpx_waypt_pr); + gpx_route_pr(); + gpx_track_pr(); + + gbfprintf(ofd, "\n"); } static void gpx_free_gpx_global(void) { - gpx_rm_from_global(&gpx_global->name); - gpx_rm_from_global(&gpx_global->desc); - gpx_rm_from_global(&gpx_global->author); - gpx_rm_from_global(&gpx_global->email); - gpx_rm_from_global(&gpx_global->url); - gpx_rm_from_global(&gpx_global->urlname); - gpx_rm_from_global(&gpx_global->keywords); - xfree(gpx_global); + gpx_rm_from_global(&gpx_global->name); + gpx_rm_from_global(&gpx_global->desc); + gpx_rm_from_global(&gpx_global->author); + gpx_rm_from_global(&gpx_global->email); + gpx_rm_from_global(&gpx_global->url); + gpx_rm_from_global(&gpx_global->urlname); + gpx_rm_from_global(&gpx_global->keywords); + xfree(gpx_global); } static void gpx_exit(void) { - if ( xsi_schema_loc ) { - xfree(xsi_schema_loc); - xsi_schema_loc = NULL; - } - - if (gpx_global) { - gpx_free_gpx_global(); - gpx_global = NULL; - } + if (xsi_schema_loc) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + + if (gpx_global) { + gpx_free_gpx_global(); + gpx_global = NULL; + } } static arglist_t gpx_args[] = { - { "snlen", &snlen, "Length of generated shortnames", - "32", ARGTYPE_INT, "1", NULL }, - { "suppresswhite", &suppresswhite, - "No whitespace in generated shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logpoint", &opt_logpoint, - "Create waypoints from geocache log entries", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "urlbase", &urlbase, "Base URL for link tag in output", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - { "gpxver", &gpx_wversion, "Target GPX version for output", - "1.0", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "snlen", &snlen, "Length of generated shortnames", + "32", ARGTYPE_INT, "1", NULL + }, + { + "suppresswhite", &suppresswhite, + "No whitespace in generated shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logpoint", &opt_logpoint, + "Create waypoints from geocache log entries", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "urlbase", &urlbase, "Base URL for link tag in output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "gpxver", &gpx_wversion, "Target GPX version for output", + "1.0", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t gpx_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - gpx_rd_init, - gpx_wr_init, - gpx_rd_deinit, - gpx_wr_deinit, - gpx_read, - gpx_write, - gpx_exit, - gpx_args, - CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + gpx_rd_init, + gpx_wr_init, + gpx_rd_deinit, + gpx_wr_deinit, + gpx_read, + gpx_write, + gpx_exit, + gpx_args, + CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ }; #endif diff --git a/gpsbabel/garmin_fit.c b/gpsbabel/garmin_fit.c new file mode 100644 index 000000000..146972fd2 --- /dev/null +++ b/gpsbabel/garmin_fit.c @@ -0,0 +1,370 @@ +/* + + Support for FIT track files. + + Copyright (C) 2011 Paul Brook, paul@nowt.org + Copyright (C) 2003-2011 Robert Lipe, robertlipe@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include + +#define MYNAME "fit" + + +static +arglist_t fit_args[] = { + ARG_TERMINATOR +}; + +typedef struct { + int id; + int size; + int type; +} fit_field_t; + +typedef struct { + int endian; + int global_id; + int num_fields; + fit_field_t* fields; +} fit_message_def; + +static struct { + int len; + int endian; + route_head* track; + gbuint32 last_timestamp; + fit_message_def message_def[16]; +} fit_data; + +static gbfile* fin; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +fit_rd_init(const char* fname) +{ + fin = gbfopen_le(fname, "rb", MYNAME); +} + +static void +fit_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +fit_parse_header(void) +{ + int len; + int ver; + char sig[4]; + + len = gbfgetc(fin); + if (len == EOF || len < 12) { + fatal(MYNAME ": Bad header\n"); + } + ver = gbfgetc(fin); + if (ver == EOF || (ver >> 4) > 1) + fatal(MYNAME ": Unsupported protocol version %d.%d\n", + ver >> 4, ver & 0xf); + // profile version + ver = gbfgetuint16(fin); + // data length + fit_data.len = gbfgetuint32(fin); + // File signature + is_fatal(gbfread(sig, 4, 1, fin) != 1, + MYNAME ": Unexpected end of file\n"); + if (sig[0] != '.' || sig[1] != 'F' || sig[2] != 'I' || sig[3] != 'T') { + fatal(MYNAME ": .FIT signature missing\n"); + } +} + +static gbuint8 +fit_getuint8(void) +{ + int val; + + if (fit_data.len == 0) { + fatal(MYNAME ": record truncated\n"); + } + val = gbfgetc(fin); + if (val == EOF) { + fatal(MYNAME ": unexpected end of file\n"); + } + fit_data.len--; + return (gbuint8)val; + +} + +static gbuint16 +fit_getuint16(void) +{ + char buf[2]; + + if (fit_data.len < 2) { + fatal(MYNAME ": record truncated\n"); + } + is_fatal(gbfread(buf, 2, 1, fin) != 1, + MYNAME ": unexpected end of file\n"); + fit_data.len -= 2; + if (fit_data.endian) { + return be_read16(buf); + } else { + return le_read16(buf); + } + +} + +static gbuint32 +fit_getuint32(void) +{ + char buf[4]; + + if (fit_data.len < 4) { + fatal(MYNAME ": record truncated\n"); + } + is_fatal(gbfread(buf, 4, 1, fin) != 1, + MYNAME ": unexpected end of file\n"); + fit_data.len -= 4; + if (fit_data.endian) { + return be_read32(buf); + } else { + return le_read32(buf); + } + +} + +static void +fit_parse_definition_message(gbuint8 header) +{ + int local_id = header & 0x1f; + fit_message_def* def = &fit_data.message_def[local_id]; + int i; + + if (def->fields) { + free(def->fields); + } + + is_fatal(fit_getuint8() != 0, + MYNAME ": Definition message reserved bits not zero\n"); + def->endian = fit_getuint8(); + if (def->endian > 1) { + fatal(MYNAME ": Bad endian field\n"); + } + fit_data.endian = def->endian; + def->global_id = fit_getuint16(); + def->num_fields = fit_getuint8(); + if (def->num_fields == 0) { + def->fields = (fit_field_t*) xmalloc(sizeof(fit_field_t)); + return; + } + def->fields = (fit_field_t*) xmalloc(def->num_fields * sizeof(fit_field_t)); + for (i = 0; i < def->num_fields; i++) { + def->fields[i].id = fit_getuint8(); + def->fields[i].size = fit_getuint8(); + def->fields[i].type = fit_getuint8(); + } +} + +static gbuint32 +fit_read_field(fit_field_t* f) +{ + int i; + + switch (f->type) { + case 1: // sint8 + case 2: // uint8 + is_fatal(f->size != 1, + MYNAME ": Bad field size in data message\n"); + return fit_getuint8(); + case 0x83: // sint16 + case 0x84: // uint16 + is_fatal(f->size != 2, + MYNAME ": Bad field size in data message\n"); + return fit_getuint16(); + case 0x85: // sint32 + case 0x86: // uint32 + is_fatal(f->size != 4, + MYNAME ": Bad field size in data message\n"); + return fit_getuint32(); + default: // Ignore everything else for now. + for (i = 0; i < f->size; i++) { + fit_getuint8(); + } + return -1; + } +} + +static void +fit_parse_data(fit_message_def* def, int time_offset) +{ + fit_field_t* f; + gbuint32 timestamp = fit_data.last_timestamp + time_offset; + gbuint32 val; + gbint32 lat = 0x7fffffff; + gbint32 lon = 0x7fffffff; + gbuint16 alt = 0xffff; + gbuint16 speed = 0xffff; + gbuint8 heartrate = 0xff; + gbuint8 cadence = 0xff; + gbuint16 power = 0xffff; + gbint8 temperature = 0x7f; + int i; + waypoint* waypt; + + for (i = 0; i < def->num_fields; i++) { + f = &def->fields[i]; + val = fit_read_field(f); + if (f->id == 253) { + fit_data.last_timestamp = timestamp = val; + } else { + switch (def->global_id) { + case 20: // record mesage + switch (f->id) { + case 0: + lat = val; + break; + case 1: + lon = val; + break; + case 2: + alt = val; + break; + case 3: + heartrate = val; + break; + case 4: + cadence = val; + break; + case 6: + speed = val; + break; + case 7: + power = val; + break; + case 13: + temperature = val; + break; + } + } + } + } + switch (def->global_id) { + case 20: // record mesage + if (lat == 0x7fffffff || lon == 0x7fffffff) { + break; + } + + waypt = waypt_new(); + waypt->latitude = (lat / (float)0x7fffffff) * 180; + waypt->longitude = (lon / (float)0x7fffffff) * 180; + if (alt != 0xffff) { + waypt->altitude = (alt / 5.0) - 500; + } + waypt->creation_time = timestamp + 631065600; + if (speed != 0xffff) { + WAYPT_SET(waypt, speed, speed / 1000.0f); + } + if (heartrate != 0xff) { + waypt->heartrate = heartrate; + } + if (cadence != 0xff) { + waypt->cadence = cadence; + } + if (power != 0xffff) { + waypt->power = power; + } + if (temperature != 0x7f) { + WAYPT_SET(waypt, temperature, temperature); + } + track_add_wpt(fit_data.track, waypt); + break; + } +} + +static void +fit_parse_data_message(gbuint8 header) +{ + int local_id = header & 0x1f; + fit_message_def* def = &fit_data.message_def[local_id]; + fit_parse_data(def, 0); +} + +static void +fit_parse_compressed_message(gbuint8 header) +{ + int local_id = (header >> 5) & 3; + fit_message_def* def = &fit_data.message_def[local_id]; + fit_parse_data(def, header & 0x1f); +} + +static void +fit_parse_record(void) +{ + gbuint8 header; + + header = fit_getuint8(); + if (header & 0x80) { + fit_parse_compressed_message(header); + } else if (header & 0x40) { + fit_parse_definition_message(header); + } else { + fit_parse_data_message(header); + } +} + +static void +fit_read(void) +{ + fit_parse_header(); + + fit_data.track = route_head_alloc(); + track_add_head(fit_data.track); + while (fit_data.len) { + fit_parse_record(); + } +} + +/**************************************************************************/ + +// capabilities below means: we can only read and write waypoints +// please change this depending on your new module + +ff_vecs_t format_fit_vecs = { + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + fit_rd_init, + NULL, + fit_rd_deinit, + NULL, + fit_read, + NULL, + NULL, + fit_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ +}; +/**************************************************************************/ diff --git a/gpsbabel/garmin_fs.c b/gpsbabel/garmin_fs.c index 04727478e..1ff788268 100644 --- a/gpsbabel/garmin_fs.c +++ b/gpsbabel/garmin_fs.c @@ -1,7 +1,7 @@ /* - + Implementation of special data used by Garmin products. - + Copyright (C) 2006, 2007, 2008 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -33,391 +33,461 @@ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \ "xsi:schemaLocation=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3 " \ "http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd" - -garmin_fs_t * + +garmin_fs_t* garmin_fs_alloc(const int protocol) { - garmin_fs_t *result = NULL; - - result = (garmin_fs_t *)xcalloc(1, sizeof(*result)); - result->fs.type = FS_GMSD; - result->fs.copy = (fs_copy) garmin_fs_copy; - result->fs.destroy = garmin_fs_destroy; - result->fs.convert = garmin_fs_convert; - result->fs.next = NULL; - - result->protocol = protocol; - - return result; + garmin_fs_t* result = NULL; + + result = (garmin_fs_t*)xcalloc(1, sizeof(*result)); + result->fs.type = FS_GMSD; + result->fs.copy = (fs_copy) garmin_fs_copy; + result->fs.destroy = garmin_fs_destroy; + result->fs.convert = garmin_fs_convert; + result->fs.next = NULL; + + result->protocol = protocol; + + return result; } -void -garmin_fs_destroy(void *fs) +void +garmin_fs_destroy(void* fs) { - garmin_fs_t *data = (garmin_fs_t *) fs; - if (data != NULL) - { - garmin_ilink_t *ilinks; - - if (data->addr != NULL) xfree(data->addr); - if (data->cc != NULL) xfree(data->cc); - if (data->city != NULL) xfree(data->city); - if (data->country != NULL) xfree(data->country); - if (data->cross_road != NULL) xfree(data->cross_road); - if (data->facility != NULL) xfree(data->facility); - if (data->phone_nr != NULL) xfree(data->phone_nr); - if (data->phone_nr2 != NULL) xfree(data->phone_nr2); - if (data->fax_nr != NULL) xfree(data->fax_nr); - if (data->email != NULL) xfree(data->email); - if (data->postal_code != NULL) xfree(data->postal_code); - if (data->state != NULL) xfree(data->state); - - if ((ilinks = data->ilinks) != NULL) { - ilinks->ref_count--; - if (ilinks->ref_count <= 0) { - while (ilinks != NULL) { - garmin_ilink_t *tmp = ilinks; - ilinks = ilinks->next; - xfree(tmp); - } - } - } - xfree(data); - } + garmin_fs_t* data = (garmin_fs_t*) fs; + if (data != NULL) { + garmin_ilink_t* ilinks; + + if (data->addr != NULL) { + xfree(data->addr); + } + if (data->cc != NULL) { + xfree(data->cc); + } + if (data->city != NULL) { + xfree(data->city); + } + if (data->country != NULL) { + xfree(data->country); + } + if (data->cross_road != NULL) { + xfree(data->cross_road); + } + if (data->facility != NULL) { + xfree(data->facility); + } + if (data->phone_nr != NULL) { + xfree(data->phone_nr); + } + if (data->phone_nr2 != NULL) { + xfree(data->phone_nr2); + } + if (data->fax_nr != NULL) { + xfree(data->fax_nr); + } + if (data->email != NULL) { + xfree(data->email); + } + if (data->postal_code != NULL) { + xfree(data->postal_code); + } + if (data->state != NULL) { + xfree(data->state); + } + + if ((ilinks = data->ilinks) != NULL) { + ilinks->ref_count--; + if (ilinks->ref_count <= 0) { + while (ilinks != NULL) { + garmin_ilink_t* tmp = ilinks; + ilinks = ilinks->next; + xfree(tmp); + } + } + } + xfree(data); + } } -void garmin_fs_copy(garmin_fs_t **dest, garmin_fs_t *src) +void garmin_fs_copy(garmin_fs_t** dest, garmin_fs_t* src) { - if (src == NULL) - { - *dest = NULL; - return; - } - *dest = (garmin_fs_t *) xmalloc(sizeof(*src)); - - /* do not copy interlinks, only increment the refrence counter */ - if (src->ilinks != NULL) src->ilinks->ref_count++; - - memcpy(*dest, src, sizeof(*src)); - - (*dest)->addr = (src->addr != NULL) ? xstrdup(src->addr) : NULL; - (*dest)->cc = (src->cc != NULL) ? xstrdup(src->cc) : NULL; - (*dest)->city = (src->city != NULL) ? xstrdup(src->city) : NULL; - (*dest)->country = (src->country != NULL) ? xstrdup(src->country) : NULL; - (*dest)->cross_road = (src->cross_road != NULL) ? xstrdup(src->cross_road) : NULL; - (*dest)->facility = (src->facility != NULL) ? xstrdup(src->facility) : NULL; - (*dest)->phone_nr = (src->phone_nr != NULL) ? xstrdup(src->phone_nr) : NULL; - (*dest)->phone_nr2 = (src->phone_nr2 != NULL) ? xstrdup(src->phone_nr2) : NULL; - (*dest)->fax_nr = (src->fax_nr != NULL) ? xstrdup(src->fax_nr) : NULL; - (*dest)->email = (src->email != NULL) ? xstrdup(src->email) : NULL; - (*dest)->postal_code = (src->postal_code != NULL) ? xstrdup(src->postal_code) : NULL; - (*dest)->state = (src->state != NULL) ? xstrdup(src->state) : NULL; + if (src == NULL) { + *dest = NULL; + return; + } + *dest = (garmin_fs_t*) xmalloc(sizeof(*src)); + + /* do not copy interlinks, only increment the refrence counter */ + if (src->ilinks != NULL) { + src->ilinks->ref_count++; + } + + memcpy(*dest, src, sizeof(*src)); + + (*dest)->addr = (src->addr != NULL) ? xstrdup(src->addr) : NULL; + (*dest)->cc = (src->cc != NULL) ? xstrdup(src->cc) : NULL; + (*dest)->city = (src->city != NULL) ? xstrdup(src->city) : NULL; + (*dest)->country = (src->country != NULL) ? xstrdup(src->country) : NULL; + (*dest)->cross_road = (src->cross_road != NULL) ? xstrdup(src->cross_road) : NULL; + (*dest)->facility = (src->facility != NULL) ? xstrdup(src->facility) : NULL; + (*dest)->phone_nr = (src->phone_nr != NULL) ? xstrdup(src->phone_nr) : NULL; + (*dest)->phone_nr2 = (src->phone_nr2 != NULL) ? xstrdup(src->phone_nr2) : NULL; + (*dest)->fax_nr = (src->fax_nr != NULL) ? xstrdup(src->fax_nr) : NULL; + (*dest)->email = (src->email != NULL) ? xstrdup(src->email) : NULL; + (*dest)->postal_code = (src->postal_code != NULL) ? xstrdup(src->postal_code) : NULL; + (*dest)->state = (src->state != NULL) ? xstrdup(src->state) : NULL; } -void garmin_fs_convert(void *fs) +void garmin_fs_convert(void* fs) { - garmin_fs_t *gmsd = (garmin_fs_t *) fs; - - if (gmsd->addr) gmsd->addr = cet_convert_string(gmsd->addr); - if (gmsd->cc) gmsd->cc = cet_convert_string(gmsd->cc); - if (gmsd->city) gmsd->city = cet_convert_string(gmsd->city); - if (gmsd->country) gmsd->country = cet_convert_string(gmsd->country); - if (gmsd->cross_road) gmsd->cross_road = cet_convert_string(gmsd->cross_road); - if (gmsd->facility) gmsd->facility = cet_convert_string(gmsd->facility); - if (gmsd->phone_nr) gmsd->phone_nr = cet_convert_string(gmsd->phone_nr); - if (gmsd->phone_nr2) gmsd->phone_nr2 = cet_convert_string(gmsd->phone_nr2); - if (gmsd->fax_nr) gmsd->fax_nr = cet_convert_string(gmsd->fax_nr); - if (gmsd->email) gmsd->email = cet_convert_string(gmsd->email); - if (gmsd->postal_code) gmsd->postal_code = cet_convert_string(gmsd->postal_code); - if (gmsd->state) gmsd->state = cet_convert_string(gmsd->state); + garmin_fs_t* gmsd = (garmin_fs_t*) fs; + + if (gmsd->addr) { + gmsd->addr = cet_convert_string(gmsd->addr); + } + if (gmsd->cc) { + gmsd->cc = cet_convert_string(gmsd->cc); + } + if (gmsd->city) { + gmsd->city = cet_convert_string(gmsd->city); + } + if (gmsd->country) { + gmsd->country = cet_convert_string(gmsd->country); + } + if (gmsd->cross_road) { + gmsd->cross_road = cet_convert_string(gmsd->cross_road); + } + if (gmsd->facility) { + gmsd->facility = cet_convert_string(gmsd->facility); + } + if (gmsd->phone_nr) { + gmsd->phone_nr = cet_convert_string(gmsd->phone_nr); + } + if (gmsd->phone_nr2) { + gmsd->phone_nr2 = cet_convert_string(gmsd->phone_nr2); + } + if (gmsd->fax_nr) { + gmsd->fax_nr = cet_convert_string(gmsd->fax_nr); + } + if (gmsd->email) { + gmsd->email = cet_convert_string(gmsd->email); + } + if (gmsd->postal_code) { + gmsd->postal_code = cet_convert_string(gmsd->postal_code); + } + if (gmsd->state) { + gmsd->state = cet_convert_string(gmsd->state); + } } /* GPX - out */ -void -garmin_fs_xml_fprint(gbfile *ofd, const waypoint *waypt) +void +garmin_fs_xml_fprint(gbfile* ofd, const waypoint* waypt) { - const char *phone, *addr; - garmin_fs_t *gmsd = GMSD_FIND(waypt); - - if (gmsd == NULL) return; - - /* Find out if there is at least one field set */ - addr = GMSD_GET(addr, ""); - if (! *addr) addr = GMSD_GET(city, ""); - if (! *addr) addr = GMSD_GET(country, ""); - if (! *addr) addr = GMSD_GET(postal_code, ""); - if (! *addr) addr = GMSD_GET(state, ""); - - phone = GMSD_GET(phone_nr, ""); - - if (*addr || *phone || - (gmsd->flags.category && gmsd->category) || - WAYPT_HAS(waypt, depth) || - WAYPT_HAS(waypt, proximity) || - WAYPT_HAS(waypt, temperature) || - gmsd->flags.display) - { - int space = 1; - - gbfprintf(ofd, "%*s\n", space++ * 2, ""); - gbfprintf(ofd, "%*s\n", space++ * 2, "", GARMIN_GPX_EXT_REFERENCE); - if WAYPT_HAS(waypt, proximity) - gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->proximity); - if WAYPT_HAS(waypt, temperature) - gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->temperature); - if WAYPT_HAS(waypt, depth) - gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->depth); - if (gmsd->flags.display) - { - char *cx; - switch(gmsd->display) - { - case gt_display_mode_symbol: - cx = "SymbolOnly"; - break; - case gt_display_mode_symbol_and_comment: - cx = "SymbolAndDescription"; - break; - default: - cx = "SymbolAndName"; - break; - } - gbfprintf(ofd, "%*s%s\n", space * 2, "", cx); - } - if (gmsd->flags.category && gmsd->category) - { - int i; - gbuint16 cx = gmsd->category; - gbfprintf(ofd, "%*s\n", space++ * 2, ""); - for (i = 0; i < 16; i++) - { - if (cx & 1) - gbfprintf(ofd, "%*sCategory %d\n", space*2, "", i+1); - cx = cx >> 1; - } - gbfprintf(ofd, "%*s\n", --space * 2, ""); - } - if (*addr) { - char *str, *tmp; - gbfprintf(ofd, "%*s\n", space++ * 2, ""); - - if ((str = GMSD_GET(addr, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - if ((str = GMSD_GET(city, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - if ((str = GMSD_GET(state, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - if ((str = GMSD_GET(country, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - if ((str = GMSD_GET(postal_code, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - - gbfprintf(ofd, "%*s\n", --space * 2, ""); - } - - if (*phone) { - char *tmp = xml_entitize(phone); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - - gbfprintf(ofd, "%*s\n", --space * 2, ""); - gbfprintf(ofd, "%*s\n", --space * 2, ""); - } - + const char* phone, *addr; + garmin_fs_t* gmsd = GMSD_FIND(waypt); + + if (gmsd == NULL) { + return; + } + + /* Find out if there is at least one field set */ + addr = GMSD_GET(addr, ""); + if (! *addr) { + addr = GMSD_GET(city, ""); + } + if (! *addr) { + addr = GMSD_GET(country, ""); + } + if (! *addr) { + addr = GMSD_GET(postal_code, ""); + } + if (! *addr) { + addr = GMSD_GET(state, ""); + } + + phone = GMSD_GET(phone_nr, ""); + + if (*addr || *phone || + (gmsd->flags.category && gmsd->category) || + WAYPT_HAS(waypt, depth) || + WAYPT_HAS(waypt, proximity) || + WAYPT_HAS(waypt, temperature) || + gmsd->flags.display) { + int space = 1; + + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + gbfprintf(ofd, "%*s\n", space++ * 2, "", GARMIN_GPX_EXT_REFERENCE); + if WAYPT_HAS(waypt, proximity) { + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->proximity); + } + if WAYPT_HAS(waypt, temperature) { + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->temperature); + } + if WAYPT_HAS(waypt, depth) { + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->depth); + } + if (gmsd->flags.display) { + char* cx; + switch (gmsd->display) { + case gt_display_mode_symbol: + cx = "SymbolOnly"; + break; + case gt_display_mode_symbol_and_comment: + cx = "SymbolAndDescription"; + break; + default: + cx = "SymbolAndName"; + break; + } + gbfprintf(ofd, "%*s%s\n", space * 2, "", cx); + } + if (gmsd->flags.category && gmsd->category) { + int i; + gbuint16 cx = gmsd->category; + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + for (i = 0; i < 16; i++) { + if (cx & 1) { + gbfprintf(ofd, "%*sCategory %d\n", space*2, "", i+1); + } + cx = cx >> 1; + } + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + if (*addr) { + char* str, *tmp; + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + + if ((str = GMSD_GET(addr, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(city, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(state, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(country, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(postal_code, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + + if (*phone) { + char* tmp = xml_entitize(phone); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + + gbfprintf(ofd, "%*s\n", --space * 2, ""); + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + } void -garmin_fs_xml_convert(const int base_tag, int tag, const char *cdatastr, waypoint *waypt) +garmin_fs_xml_convert(const int base_tag, int tag, const char* cdatastr, waypoint* waypt) { - garmin_fs_t *gmsd; - - gmsd = GMSD_FIND(waypt); - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); - } - - tag -= base_tag; -/* - tt_garmin_waypt_extension, -> 0 - tt_garmin_proximity, -> 1 - tt_garmin_temperature,-> 2 - tt_garmin_depth, -> 3 - tt_garmin_display_mode, -> 4 - tt_garmin_categories, -> 5 - tt_garmin_category, -> 6 - tt_garmin_addr, -> 7 - tt_garmin_city, -> 8 - tt_garmin_state, -> 9 - tt_garmin_country, -> 10 - tt_garmin_postal_code, -> 11 - tt_garmin_phone_nr, -> 12 -*/ - switch(tag) { - case 1: - if (*cdatastr) WAYPT_SET(waypt, proximity, atof(cdatastr)); - break; - case 2: - if (*cdatastr) WAYPT_SET(waypt, temperature, atof(cdatastr)); - break; - case 3: - if (*cdatastr) WAYPT_SET(waypt, depth, atof(cdatastr)); - break; - case 4: - if (case_ignore_strcmp(cdatastr, "SymbolOnly") == 0) { - GMSD_SET(display, gt_display_mode_symbol); - } - else if (case_ignore_strcmp(cdatastr, "SymbolAndDescription") == 0) { - GMSD_SET(display, gt_display_mode_symbol_and_comment); - } - else { - GMSD_SET(display, gt_display_mode_symbol_and_name); - } - break; - case 6: - if ( ! garmin_fs_merge_category(cdatastr, waypt)) - warning(MYNAME ": Unable to convert category \"%s \"!\n", cdatastr); - break; - case 7: - GMSD_SETSTR(addr, cdatastr); - break; - case 8: - GMSD_SETSTR(city, cdatastr); - break; - case 9: - GMSD_SETSTR(state, cdatastr); - break; - case 10: - GMSD_SETSTR(country, cdatastr); - break; - case 11: - GMSD_SETSTR(postal_code, cdatastr); - break; - case 12: - GMSD_SETSTR(phone_nr, cdatastr); - break; - } + garmin_fs_t* gmsd; + + gmsd = GMSD_FIND(waypt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&waypt->fs, (format_specific_data*) gmsd); + } + + tag -= base_tag; + /* + tt_garmin_waypt_extension, -> 0 + tt_garmin_proximity, -> 1 + tt_garmin_temperature,-> 2 + tt_garmin_depth, -> 3 + tt_garmin_display_mode, -> 4 + tt_garmin_categories, -> 5 + tt_garmin_category, -> 6 + tt_garmin_addr, -> 7 + tt_garmin_city, -> 8 + tt_garmin_state, -> 9 + tt_garmin_country, -> 10 + tt_garmin_postal_code, -> 11 + tt_garmin_phone_nr, -> 12 + */ + switch (tag) { + case 1: + if (*cdatastr) { + WAYPT_SET(waypt, proximity, atof(cdatastr)); + } + break; + case 2: + if (*cdatastr) { + WAYPT_SET(waypt, temperature, atof(cdatastr)); + } + break; + case 3: + if (*cdatastr) { + WAYPT_SET(waypt, depth, atof(cdatastr)); + } + break; + case 4: + if (case_ignore_strcmp(cdatastr, "SymbolOnly") == 0) { + GMSD_SET(display, gt_display_mode_symbol); + } else if (case_ignore_strcmp(cdatastr, "SymbolAndDescription") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_comment); + } else { + GMSD_SET(display, gt_display_mode_symbol_and_name); + } + break; + case 6: + if (! garmin_fs_merge_category(cdatastr, waypt)) { + warning(MYNAME ": Unable to convert category \"%s \"!\n", cdatastr); + } + break; + case 7: + GMSD_SETSTR(addr, cdatastr); + break; + case 8: + GMSD_SETSTR(city, cdatastr); + break; + case 9: + GMSD_SETSTR(state, cdatastr); + break; + case 10: + GMSD_SETSTR(country, cdatastr); + break; + case 11: + GMSD_SETSTR(postal_code, cdatastr); + break; + case 12: + GMSD_SETSTR(phone_nr, cdatastr); + break; + } } -unsigned char -garmin_fs_convert_category(const char *category_name, gbuint16 *category) +unsigned char +garmin_fs_convert_category(const char* category_name, gbuint16* category) { - int i; - int cat = 0; - - if ((case_ignore_strncmp(category_name, "Category ", 9) == 0) && - (1 == sscanf(category_name + 9, "%d", &i)) && - (i >= 1) && (i <= 16)) { - cat = (1 << --i); - } - else if (global_opts.inifile != NULL) { - for (i = 0; i < 16; i++) { - char *c; - char key[3]; - - snprintf(key, sizeof(key), "%d", i + 1); - c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); - if ((c != NULL) && (case_ignore_strcmp(c, category_name) == 0)) { - cat = (1 << i); - break; - } - } - } - if (cat == 0) { - return 0; - } - else { - *category = cat; - return 1; - } + int i; + int cat = 0; + + if ((case_ignore_strncmp(category_name, "Category ", 9) == 0) && + (1 == sscanf(category_name + 9, "%d", &i)) && + (i >= 1) && (i <= 16)) { + cat = (1 << --i); + } else if (global_opts.inifile != NULL) { + for (i = 0; i < 16; i++) { + char* c; + char key[3]; + + snprintf(key, sizeof(key), "%d", i + 1); + c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); + if ((c != NULL) && (case_ignore_strcmp(c, category_name) == 0)) { + cat = (1 << i); + break; + } + } + } + if (cat == 0) { + return 0; + } else { + *category = cat; + return 1; + } } unsigned char -garmin_fs_merge_category(const char *category_name, waypoint *waypt) +garmin_fs_merge_category(const char* category_name, waypoint* waypt) { - gbuint16 cat; - garmin_fs_t *gmsd; - - if (!garmin_fs_convert_category(category_name, &cat)) { - return 0; - } - - gmsd = GMSD_FIND(waypt); - cat = cat | ( GMSD_GET(category, 0) ); - - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); - } - GMSD_SET(category, cat); - return 1; + gbuint16 cat; + garmin_fs_t* gmsd; + + if (!garmin_fs_convert_category(category_name, &cat)) { + return 0; + } + + gmsd = GMSD_FIND(waypt); + cat = cat | (GMSD_GET(category, 0)); + + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&waypt->fs, (format_specific_data*) gmsd); + } + GMSD_SET(category, cat); + return 1; } -void -garmin_fs_garmin_after_read(const GPS_PWay way, waypoint *wpt, const int protoid) +void +garmin_fs_garmin_after_read(const GPS_PWay way, waypoint* wpt, const int protoid) { - garmin_fs_t *gmsd = NULL; - - gmsd = garmin_fs_alloc(protoid); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - /* nothing happens until gmsd is allocated some lines above */ - - /* !!! class needs protocol specific conversion !!! (ToDo) - GMSD_SET(wpt_class, way[i]->wpt_class); - */ - /* flagged data fields */ - GMSD_SET(display, gt_switch_display_mode_value(way->dspl, gps_waypt_type, 1)); - if (way->category != 0) GMSD_SET(category, way->category); - if (way->dst < 1.0e25f) WAYPT_SET(wpt, proximity, way->dst); - if (way->temperature_populated) WAYPT_SET(wpt, temperature, way->temperature); - if (way->dpth < 1.0e25f) WAYPT_SET(wpt, depth, way->dpth); - GMSD_SETNSTR(cc, way->cc, sizeof(way->cc)); - GMSD_SETNSTR(state, way->state, sizeof(way->state)); - GMSD_SETSTR(city, way->city); - GMSD_SETSTR(facility, way->facility); - GMSD_SETSTR(cross_road, way->cross_road); - GMSD_SETSTR(addr, way->addr); + garmin_fs_t* gmsd = NULL; + + gmsd = garmin_fs_alloc(protoid); + fs_chain_add(&wpt->fs, (format_specific_data*) gmsd); + + /* nothing happens until gmsd is allocated some lines above */ + + /* !!! class needs protocol specific conversion !!! (ToDo) + GMSD_SET(wpt_class, way[i]->wpt_class); + */ + /* flagged data fields */ + GMSD_SET(display, gt_switch_display_mode_value(way->dspl, gps_waypt_type, 1)); + if (way->category != 0) { + GMSD_SET(category, way->category); + } + if (way->dst < 1.0e25f) { + WAYPT_SET(wpt, proximity, way->dst); + } + if (way->temperature_populated) { + WAYPT_SET(wpt, temperature, way->temperature); + } + if (way->dpth < 1.0e25f) { + WAYPT_SET(wpt, depth, way->dpth); + } + GMSD_SETNSTR(cc, way->cc, sizeof(way->cc)); + GMSD_SETNSTR(state, way->state, sizeof(way->state)); + GMSD_SETSTR(city, way->city); + GMSD_SETSTR(facility, way->facility); + GMSD_SETSTR(cross_road, way->cross_road); + GMSD_SETSTR(addr, way->addr); } -void -garmin_fs_garmin_before_write(const waypoint *wpt, GPS_PWay way, const int protoid) +void +garmin_fs_garmin_before_write(const waypoint* wpt, GPS_PWay way, const int protoid) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - - if (gmsd == NULL) return; - - /* ToDo: protocol specific conversion of class - way[i]->wpt_class = GMSD_GET(wpt_class, way[i]->wpt_class); - */ - way->dspl = gt_switch_display_mode_value( - GMSD_GET(display, way->dspl), gps_waypt_type, 0); - way->category = GMSD_GET(category, way->category); - way->dpth = WAYPT_GET(wpt, depth, way->dpth); - way->dst = WAYPT_GET(wpt, proximity, way->dpth); - way->temperature = WAYPT_GET(wpt, temperature, way->temperature); - - GMSD_GETNSTR(cc, way->cc, sizeof(way->cc)); - GMSD_GETNSTR(city, way->city, sizeof(way->city)); - GMSD_GETNSTR(state, way->state, sizeof(way->state)); - GMSD_GETNSTR(facility, way->facility, sizeof(way->facility)); - GMSD_GETNSTR(cross_road, way->cross_road, sizeof(way->cross_road)); - GMSD_GETNSTR(addr, way->addr, sizeof(way->addr)); + garmin_fs_t* gmsd = GMSD_FIND(wpt); + + if (gmsd == NULL) { + return; + } + + /* ToDo: protocol specific conversion of class + way[i]->wpt_class = GMSD_GET(wpt_class, way[i]->wpt_class); + */ + way->dspl = gt_switch_display_mode_value( + GMSD_GET(display, way->dspl), gps_waypt_type, 0); + way->category = GMSD_GET(category, way->category); + way->dpth = WAYPT_GET(wpt, depth, way->dpth); + way->dst = WAYPT_GET(wpt, proximity, way->dpth); + way->temperature = WAYPT_GET(wpt, temperature, way->temperature); + + GMSD_GETNSTR(cc, way->cc, sizeof(way->cc)); + GMSD_GETNSTR(city, way->city, sizeof(way->city)); + GMSD_GETNSTR(state, way->state, sizeof(way->state)); + GMSD_GETNSTR(facility, way->facility, sizeof(way->facility)); + GMSD_GETNSTR(cross_road, way->cross_road, sizeof(way->cross_road)); + GMSD_GETNSTR(addr, way->addr, sizeof(way->addr)); } diff --git a/gpsbabel/garmin_fs.h b/gpsbabel/garmin_fs.h index 568faa849..c3f994d0e 100644 --- a/gpsbabel/garmin_fs.h +++ b/gpsbabel/garmin_fs.h @@ -1,7 +1,7 @@ /* - + Implementation of special data used by Garmin products. - + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -59,83 +59,82 @@ #define GMSD_GETNSTR(a,b,c) if (gmsd && gmsd->flags.a) strncpy((b),gmsd->a,(c)) typedef struct garmin_ilink_s { - int ref_count; - double lat, lon, alt; - struct garmin_ilink_s *next; + int ref_count; + double lat, lon, alt; + struct garmin_ilink_s* next; } garmin_ilink_t; typedef struct { - unsigned int icon:1; - unsigned int wpt_class:1; - unsigned int display:1; - unsigned int category:1; - unsigned int city:1; - unsigned int state:1; - unsigned int facility:1; - unsigned int cc:1; - unsigned int cross_road:1; - unsigned int addr:1; - unsigned int country:1; - unsigned int phone_nr:1; - unsigned int phone_nr2:1; - unsigned int fax_nr:1; - unsigned int postal_code:1; - unsigned int email:1; + unsigned int icon:1; + unsigned int wpt_class:1; + unsigned int display:1; + unsigned int category:1; + unsigned int city:1; + unsigned int state:1; + unsigned int facility:1; + unsigned int cc:1; + unsigned int cross_road:1; + unsigned int addr:1; + unsigned int country:1; + unsigned int phone_nr:1; + unsigned int phone_nr2:1; + unsigned int fax_nr:1; + unsigned int postal_code:1; + unsigned int email:1; #ifdef GMSD_EXPERIMENTAL - unsigned int subclass:1; + unsigned int subclass:1; #endif } garmin_fs_flags_t; -typedef struct garmin_fs_s -{ - format_specific_data fs; - garmin_fs_flags_t flags; - - int protocol; /* ... used by device (-1 is MapSource) */ - - gbint32 icon; - int wpt_class; - gbint32 display; - gbint16 category; - char *city; /* city name */ - char *facility; /* facility name */ - char *state; /* state */ - char *cc; /* country code */ - char *cross_road; /* Intersection road label */ - char *addr; /* address + number */ - char *country; /* country */ - char *phone_nr; /* phone number */ - char *phone_nr2; /* phone number (2) */ - char *fax_nr; /* fax number */ - char *postal_code; /* postal code */ - char *email; /* email address */ - garmin_ilink_t *ilinks; +typedef struct garmin_fs_s { + format_specific_data fs; + garmin_fs_flags_t flags; + + int protocol; /* ... used by device (-1 is MapSource) */ + + gbint32 icon; + int wpt_class; + gbint32 display; + gbint16 category; + char* city; /* city name */ + char* facility; /* facility name */ + char* state; /* state */ + char* cc; /* country code */ + char* cross_road; /* Intersection road label */ + char* addr; /* address + number */ + char* country; /* country */ + char* phone_nr; /* phone number */ + char* phone_nr2; /* phone number (2) */ + char* fax_nr; /* fax number */ + char* postal_code; /* postal code */ + char* email; /* email address */ + garmin_ilink_t* ilinks; #ifdef GMSD_EXPERIMENTAL - char subclass[22]; + char subclass[22]; #endif } garmin_fs_t, *garmin_fs_p; -garmin_fs_t *garmin_fs_alloc(const int protocol); -void garmin_fs_destroy(void *fs); -void garmin_fs_copy(garmin_fs_t **dest, garmin_fs_t *src); -void garmin_fs_convert(void *fs); -char *garmin_fs_xstrdup(const char *src, size_t size); +garmin_fs_t* garmin_fs_alloc(const int protocol); +void garmin_fs_destroy(void* fs); +void garmin_fs_copy(garmin_fs_t** dest, garmin_fs_t* src); +void garmin_fs_convert(void* fs); +char* garmin_fs_xstrdup(const char* src, size_t size); /* for GPX */ -void garmin_fs_xml_convert(const int base_tag, int tag, const char *cdatastr, waypoint *waypt); -void garmin_fs_xml_fprint(gbfile *ofd, const waypoint *waypt); +void garmin_fs_xml_convert(const int base_tag, int tag, const char* cdatastr, waypoint* waypt); +void garmin_fs_xml_fprint(gbfile* ofd, const waypoint* waypt); /* common garmin_fs utilities */ /* ..convert_category: returns 1=OK; 0=Unable to convert category */ -unsigned char garmin_fs_convert_category(const char *category_name, gbuint16 *category); +unsigned char garmin_fs_convert_category(const char* category_name, gbuint16* category); /* ..merge_category: returns 1=OK; 0=Unable to convert category */ -unsigned char garmin_fs_merge_category(const char *category_name, waypoint *waypt); +unsigned char garmin_fs_merge_category(const char* category_name, waypoint* waypt); #define GMSD_SECTION_CATEGORIES "Garmin Categories" -void garmin_fs_garmin_after_read(const GPS_PWay way, waypoint *wpt, const int protoid); -void garmin_fs_garmin_before_write(const waypoint *wpt, GPS_PWay way, const int protoid); +void garmin_fs_garmin_after_read(const GPS_PWay way, waypoint* wpt, const int protoid); +void garmin_fs_garmin_before_write(const waypoint* wpt, GPS_PWay way, const int protoid); #endif diff --git a/gpsbabel/garmin_gpi.c b/gpsbabel/garmin_gpi.c index a45938991..89ccee49b 100644 --- a/gpsbabel/garmin_gpi.c +++ b/gpsbabel/garmin_gpi.c @@ -1,7 +1,7 @@ /* Support for Garmin Points of Interest (.gpi files) - + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + /* History: @@ -38,7 +38,7 @@ * 2008/03/22: add options "speed" and "proximity" (default values) and "sleep" ToDo: - + * Display mode ("Symbol & Name") ??? not in gpi ??? * support category from GMSD "Garmin Special Data" */ @@ -68,117 +68,141 @@ #define GPI_ADDR_POSTAL_CODE 8 #define GPI_ADDR_ADDR 16 -static char *opt_cat, *opt_pos, *opt_notes, *opt_hide_bitmap, *opt_descr, *opt_bitmap; -static char *opt_unique, *opt_alerts, *opt_units, *opt_speed, *opt_proximity, *opt_sleep; +static char* opt_cat, *opt_pos, *opt_notes, *opt_hide_bitmap, *opt_descr, *opt_bitmap; +static char* opt_unique, *opt_alerts, *opt_units, *opt_speed, *opt_proximity, *opt_sleep; static double defspeed, defproximity; static int alerts; static arglist_t garmin_gpi_args[] = { - {"alerts", &opt_alerts, "Enable alerts on speed or proximity distance", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"bitmap", &opt_bitmap, "Use specified bitmap on output", - NULL, ARGTYPE_FILE, ARG_NOMINMAX}, - {"category", &opt_cat, "Default category on output", - "My points", ARGTYPE_STRING, ARG_NOMINMAX}, - {"hide", &opt_hide_bitmap, "Don't show gpi bitmap on device", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"descr", &opt_descr, "Write description to address field", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"notes", &opt_notes, "Write notes to address field", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"position", &opt_pos, "Write position to address field", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"proximity", &opt_proximity, "Default proximity", - NULL, ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"sleep", &opt_sleep, "After output job done sleep n second(s)", - NULL, ARGTYPE_INT, "1", NULL}, - {"speed", &opt_speed, "Default speed", - NULL, ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"unique", &opt_unique, "Create unique waypoint names (default = yes)", - "Y", ARGTYPE_BOOL, ARG_NOMINMAX}, - {"units", &opt_units, "Units used for names with @speed ('s'tatute or 'm'etric)", - "m", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "alerts", &opt_alerts, "Enable alerts on speed or proximity distance", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "bitmap", &opt_bitmap, "Use specified bitmap on output", + NULL, ARGTYPE_FILE, ARG_NOMINMAX + }, + { + "category", &opt_cat, "Default category on output", + "My points", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "hide", &opt_hide_bitmap, "Don't show gpi bitmap on device", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "descr", &opt_descr, "Write description to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "notes", &opt_notes, "Write notes to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "position", &opt_pos, "Write position to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "proximity", &opt_proximity, "Default proximity", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "sleep", &opt_sleep, "After output job done sleep n second(s)", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "speed", &opt_speed, "Default speed", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "unique", &opt_unique, "Create unique waypoint names (default = yes)", + "Y", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "units", &opt_units, "Units used for names with @speed ('s'tatute or 'm'etric)", + "m", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; typedef struct { - int D2; - char S3[9]; /* "GRMRECnn" */ - time_t crdate; /* creation date and time */ - char POI[4]; /* "POI" */ - char S8[3]; - char *group; - char *category; + int D2; + char S3[9]; /* "GRMRECnn" */ + time_t crdate; /* creation date and time */ + char POI[4]; /* "POI" */ + char S8[3]; + char* group; + char* category; } reader_data_t; typedef struct writer_data_s { - queue Q; - int ct; - int sz; - int alert; - bounds bds; - struct writer_data_s *top_left; - struct writer_data_s *top_right; - struct writer_data_s *buttom_left; - struct writer_data_s *buttom_right; + queue Q; + int ct; + int sz; + int alert; + bounds bds; + struct writer_data_s* top_left; + struct writer_data_s* top_right; + struct writer_data_s* buttom_left; + struct writer_data_s* buttom_right; } writer_data_t; typedef struct gpi_waypt_data_s { - int sz; - char *addr; - char *postal_code; + int sz; + char* addr; + char* postal_code; } gpi_waypt_data_t; - + typedef struct { - gbint32 size; - gbint16 res1; - gbint16 res2; - gbint32 image_offset; - gbint32 header_size; - gbint32 width; - gbint32 height; - gbint16 planes; - gbint16 bpp; - gbint32 compression_type; - gbint32 image_data_size; - gbint32 resolution_h; - gbint32 resolution_v; - gbint32 used_colors; - gbint32 important_colors; + gbint32 size; + gbint16 res1; + gbint16 res2; + gbint32 image_offset; + gbint32 header_size; + gbint32 width; + gbint32 height; + gbint16 planes; + gbint16 bpp; + gbint32 compression_type; + gbint32 image_data_size; + gbint32 resolution_h; + gbint32 resolution_v; + gbint32 used_colors; + gbint32 important_colors; } bmp_header_t; typedef struct { - gbint16 index; - gbint16 height; - gbint16 width; - gbint16 line_sz; - gbint16 bpp; - gbint16 fixed_0; - gbint32 image_size; - gbint32 fixed_2c; - gbint32 flag1; - gbint32 tr_color; - gbint32 flag2; - gbint32 size_2c; + gbint16 index; + gbint16 height; + gbint16 width; + gbint16 line_sz; + gbint16 bpp; + gbint16 fixed_0; + gbint32 image_size; + gbint32 fixed_2c; + gbint32 flag1; + gbint32 tr_color; + gbint32 flag2; + gbint32 size_2c; } gpi_bitmap_header_t; typedef struct { - int sz; - int alerts; - short mask; - char addr_is_dynamic; - char *addr; - char *city; - char *country; - char *phone_nr; - char *postal_code; - char *state; + int sz; + int alerts; + short mask; + char addr_is_dynamic; + char* addr; + char* city; + char* country; + char* phone_nr; + char* postal_code; + char* state; } gpi_waypt_t; -static gbfile *fin, *fout; +static gbfile* fin, *fout; static gbint16 codepage; /* code-page, i.e. 1252 */ -static reader_data_t *rdata; -static writer_data_t *wdata; +static reader_data_t* rdata; +static writer_data_t* wdata; static short_handle short_h; static char units; static time_t gpi_timestamp = 0; @@ -195,212 +219,230 @@ static time_t gpi_timestamp = 0; *******************************************************************************/ /* look for or initialize GMSD */ -static garmin_fs_t * -gpi_gmsd_init(waypoint *wpt) +static garmin_fs_t* +gpi_gmsd_init(waypoint* wpt) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - if (wpt == NULL) { - fatal(MYNAME ": Error in file structure.\n"); - } - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - return gmsd; + garmin_fs_t* gmsd = GMSD_FIND(wpt); + if (wpt == NULL) { + fatal(MYNAME ": Error in file structure.\n"); + } + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data*) gmsd); + } + return gmsd; } /* read a standard string with or without 'EN' (or whatever) header */ -static char * -gpi_read_string(const char *field) +static char* +gpi_read_string(const char* field) { - int l1; - char *res = NULL; - - l1 = gbfgetint16(fin); - if (l1 > 0) { - short l2; - char first; - - first = gbfgetc(fin); - if (first == 0) { - char en[2]; - - is_fatal((gbfgetc(fin) != 0), - MYNAME ": Error reading field '%s'!", field); - - gbfread(en, 1, sizeof(en), fin); - l2 = gbfgetint16(fin); - is_fatal((l2 + 4 != l1), - MYNAME ": Error out of sync (wrong size %d/%d) on field '%s'!", l1, l2, field); - - if ((en[0] < 'A') || (en[0] > 'Z') || (en[1] < 'A') || (en[1] > 'Z')) - fatal(MYNAME ": Invalid country code!\n"); - res = xmalloc(l2 + 1); - res[l2] = '\0'; - PP; - if (l2 > 0) - gbfread(res, 1, l2, fin); - } - else { - res = xmalloc(l1 + 1); - *res = first; - *(res + l1) = '\0'; - PP; - l1--; - if (l1 > 0) - gbfread(res + 1, 1, l1, fin); - - } - } + int l1; + char* res = NULL; + + l1 = gbfgetint16(fin); + if (l1 > 0) { + short l2; + char first; + + first = gbfgetc(fin); + if (first == 0) { + char en[2]; + + is_fatal((gbfgetc(fin) != 0), + MYNAME ": Error reading field '%s'!", field); + + gbfread(en, 1, sizeof(en), fin); + l2 = gbfgetint16(fin); + is_fatal((l2 + 4 != l1), + MYNAME ": Error out of sync (wrong size %d/%d) on field '%s'!", l1, l2, field); + + if ((en[0] < 'A') || (en[0] > 'Z') || (en[1] < 'A') || (en[1] > 'Z')) { + fatal(MYNAME ": Invalid country code!\n"); + } + res = (char*) xmalloc(l2 + 1); + res[l2] = '\0'; + PP; + if (l2 > 0) { + gbfread(res, 1, l2, fin); + } + } else { + res = (char*) xmalloc(l1 + 1); + *res = first; + *(res + l1) = '\0'; + PP; + l1--; + if (l1 > 0) { + gbfread(res + 1, 1, l1, fin); + } + + } + } #ifdef GPI_DBG - dbginfo("%s: %s\n", field, (res == NULL) ? "" : res); + dbginfo("%s: %s\n", field, (res == NULL) ? "" : res); #endif - return res; + return res; } static void read_header(void) { - int len, i; + int len, i; #ifdef GPI_DBG - struct tm tm; - char stime[32]; -#endif + struct tm tm; + char stime[32]; +#endif - i = gbfgetint32(fin); - if (i != 0) i = gbfgetint32(fin); - rdata->D2 = gbfgetint32(fin); + i = gbfgetint32(fin); + if (i != 0) { + i = gbfgetint32(fin); + } + rdata->D2 = gbfgetint32(fin); - gbfread(&rdata->S3, 1, sizeof(rdata->S3) - 1, fin); /* GRMRECnn */ - if (strncmp(rdata->S3, "GRMREC", 6) != 0) - fatal(MYNAME ": No GPI file!\n"); + gbfread(&rdata->S3, 1, sizeof(rdata->S3) - 1, fin); /* GRMRECnn */ + if (strncmp(rdata->S3, "GRMREC", 6) != 0) { + fatal(MYNAME ": No GPI file!\n"); + } - PP; - rdata->crdate = gbfgetint32(fin); + PP; + rdata->crdate = gbfgetint32(fin); #ifdef GPI_DBG - tm = *localtime(&rdata->crdate); - tm.tm_year += 20; /* !!! */ - tm.tm_mday -= 1; /* !!! */ - strftime(stime, sizeof(stime), "%Y/%m/%d %H:%M:%S", &tm); - dbginfo("crdate = %lu (%s)\n", rdata->crdate, stime); -#endif - - (void) gbfgetint16(fin); /* 0 */ - - len = gbfgetint16(fin); - gbfseek(fin, len, SEEK_CUR); /* "my.gpi" */ - - i = gbfgetint32(fin); /* 1 */ - (void) gbfgetint32(fin); /* 12 */ - /* There are two dwords next. On most typical files, they're - * "1" and "12". On files from garminoneline.de/extras/poi, the - * next two words are "15" and "5" and there's 17 additional bytes - * that I can't identify. So hardcode a seek here for now. - */ - if (i == 15) { - gbfseek(fin, 17, SEEK_CUR); - } - - gbfread(&rdata->POI, 1, sizeof(rdata->POI) - 1, fin); - if (strcmp(rdata->POI, "POI") != 0) - fatal(MYNAME ": Wrong or unsupported GPI file!\n"); - - for (i = 0; i < 3; i++) (void)gbfgetc(fin); - gbfread(&rdata->S8, 1, sizeof(rdata->S8) - 1, fin); - - codepage = gbfgetint16(fin); - (void) gbfgetint16(fin); /* typically 0, but 0x11 in + tm = *localtime(&rdata->crdate); + tm.tm_year += 20; /* !!! */ + tm.tm_mday -= 1; /* !!! */ + strftime(stime, sizeof(stime), "%Y/%m/%d %H:%M:%S", &tm); + dbginfo("crdate = %lu (%s)\n", rdata->crdate, stime); +#endif + + (void) gbfgetint16(fin); /* 0 */ + + len = gbfgetint16(fin); + gbfseek(fin, len, SEEK_CUR); /* "my.gpi" */ + + i = gbfgetint32(fin); /* 1 */ + (void) gbfgetint32(fin); /* 12 */ + /* There are two dwords next. On most typical files, they're + * "1" and "12". On files from garminoneline.de/extras/poi, the + * next two words are "15" and "5" and there's 17 additional bytes + * that I can't identify. So hardcode a seek here for now. + */ + if (i == 15) { + gbfseek(fin, 17, SEEK_CUR); + } + + gbfread(&rdata->POI, 1, sizeof(rdata->POI) - 1, fin); + if (strcmp(rdata->POI, "POI") != 0) { + fatal(MYNAME ": Wrong or unsupported GPI file!\n"); + } + + for (i = 0; i < 3; i++) { + (void)gbfgetc(fin); + } + gbfread(&rdata->S8, 1, sizeof(rdata->S8) - 1, fin); + + codepage = gbfgetint16(fin); + (void) gbfgetint16(fin); /* typically 0, but 0x11 in Garminonline.de files. */ #ifdef GPI_DBG - PP; - dbginfo("< leaving header\n"); -#endif + PP; + dbginfo("< leaving header\n"); +#endif } /* gpi tag handler */ -static int read_tag(const char *caller, const int tag, waypoint *wpt); +static int read_tag(const char* caller, const int tag, waypoint* wpt); /* read a single poi with all options */ static void -read_poi(const int sz) +read_poi(const int sz, const int tag) { - int pos, len; - waypoint *wpt; - + int pos, len; + waypoint* wpt; + #ifdef GPI_DBG - PP; - dbginfo("> reading poi (size %d)\n", sz); -#endif - PP; - len = gbfgetint32(fin); /* sub-header size */ + PP; + dbginfo("> reading poi (size %d)\n", sz); +#endif + PP; + len = 0; + if (tag == 0x80002) { + len = gbfgetint32(fin); /* sub-header size */ + } #ifdef GPI_DBG - dbginfo("poi sublen = %1$d (0x%1$x)\n", len); -#endif - pos = gbftell(fin); - - wpt = waypt_new(); - wpt->icon_descr = DEFAULT_ICON; - - wpt->latitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); - wpt->longitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); - - (void) gbfgetint16(fin); /* ? always 1 ? */ - (void) gbfgetc(fin); /* seems to 1 when extra options present */ - - wpt->shortname = gpi_read_string("Shortname"); - - while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { - int tag = gbfgetint32(fin); - if (! read_tag("read_poi", tag, wpt)) break; - } - - if (wpt->notes && !wpt->description) wpt->description = xstrdup(wpt->notes); - if (wpt->description && !wpt->notes) wpt->notes = xstrdup(wpt->description); - - waypt_add(wpt); + dbginfo("poi sublen = %1$d (0x%1$x)\n", len); +#endif + pos = gbftell(fin); + + wpt = waypt_new(); + wpt->icon_descr = DEFAULT_ICON; + + wpt->latitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); + wpt->longitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); + + (void) gbfgetint16(fin); /* ? always 1 ? */ + (void) gbfgetc(fin); /* seems to 1 when extra options present */ + wpt->shortname = gpi_read_string("Shortname"); + + while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { + int tag = gbfgetint32(fin); + if (! read_tag("read_poi", tag, wpt)) { + break; + } + } + + if (wpt->notes && !wpt->description) { + wpt->description = xstrdup(wpt->notes); + } + if (wpt->description && !wpt->notes) { + wpt->notes = xstrdup(wpt->description); + } + + waypt_add(wpt); #ifdef GPI_DBG - PP; - dbginfo("< leaving poi\n"); -#endif + PP; + dbginfo("< leaving poi\n"); +#endif } /* read poi's following a group header */ static void read_poi_list(const int sz) { - int pos, i; - - pos = gbftell(fin); + int pos, i; + + pos = gbftell(fin); #ifdef GPI_DBG - PP; - dbginfo("> reading poi list (-> %1$x / %1$d )\n", pos + sz); + PP; + dbginfo("> reading poi list (-> %1$x / %1$d )\n", pos + sz); #endif - PP; - i = gbfgetint32(fin); /* mostly 23 (0x17) */ + PP; + i = gbfgetint32(fin); /* mostly 23 (0x17) */ #ifdef GPI_DBG - dbginfo("list sublen = %1$d (0x%1$x)\n", i); -#endif - (void) gbfgetint32(fin); /* max-lat */ - (void) gbfgetint32(fin); /* max-lon */ - (void) gbfgetint32(fin); /* min-lat */ - (void) gbfgetint32(fin); /* min-lon */ - - (void) gbfgetc(fin); /* three unknown bytes */ - (void) gbfgetc(fin); /* ? should be zero ? */ - (void) gbfgetc(fin); - - (void) gbfgetint32(fin); /* ? const 0x1000100 ? */ - - while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { - int tag = gbfgetint32(fin); - if (! read_tag("read_poi_list", tag, NULL)) return; - } + dbginfo("list sublen = %1$d (0x%1$x)\n", i); +#endif + (void) gbfgetint32(fin); /* max-lat */ + (void) gbfgetint32(fin); /* max-lon */ + (void) gbfgetint32(fin); /* min-lat */ + (void) gbfgetint32(fin); /* min-lon */ + + (void) gbfgetc(fin); /* three unknown bytes */ + (void) gbfgetc(fin); /* ? should be zero ? */ + (void) gbfgetc(fin); + + (void) gbfgetint32(fin); /* ? const 0x1000100 ? */ + + while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { + int tag = gbfgetint32(fin); + if (! read_tag("read_poi_list", tag, NULL)) { + return; + } + } #ifdef GPI_DBG - PP; - dbginfo("< leaving poi list\n"); + PP; + dbginfo("< leaving poi list\n"); #endif } @@ -408,229 +450,250 @@ read_poi_list(const int sz) static void read_poi_group(const int sz, const int tag) { - int pos; + int pos; - pos = gbftell(fin); + pos = gbftell(fin); #ifdef GPI_DBG - PP; - dbginfo("> reading poi group (-> %1$x / %1$d)\n", pos + sz); + PP; + dbginfo("> reading poi group (-> %1$x / %1$d)\n", pos + sz); #endif - if (tag == 0x80009) { - int subsz; - - PP; - subsz = gbfgetint32(fin); /* ? offset to category data ? */ + if (tag == 0x80009) { + int subsz; + + PP; + subsz = gbfgetint32(fin); /* ? offset to category data ? */ #ifdef GPI_DBG - dbginfo("group sublen = %d (-> %x / %d)\n", subsz, pos + subsz + 4, pos + subsz + 4); + dbginfo("group sublen = %d (-> %x / %d)\n", subsz, pos + subsz + 4, pos + subsz + 4); #endif - } - if (rdata->group) xfree(rdata->group); /* currently unused */ - rdata->group = gpi_read_string("Group"); - - while (gbftell(fin) < (gbsize_t)(pos + sz)) { - int subtag = gbfgetint32(fin); - if (! read_tag("read_poi_group", subtag, NULL)) break; - } - + } + if (rdata->group) { + xfree(rdata->group); /* currently unused */ + } + rdata->group = gpi_read_string("Group"); + + while (gbftell(fin) < (gbsize_t)(pos + sz)) { + int subtag = gbfgetint32(fin); + if (! read_tag("read_poi_group", subtag, NULL)) { + break; + } + } + #ifdef GPI_DBG - PP; - dbginfo("< leaving poi group\n"); + PP; + dbginfo("< leaving poi group\n"); #endif } // TODO: 'tag' is probably not a 32 bit value. // most likely it's a pair of 16's: the first pair is the tag number. // if the second 16 is "eight", then it's an -// extended thingy and it has a 4-byte extended record length (total number -// of bytes for all record fields and all nested records, starting after the +// extended thingy and it has a 4-byte extended record length (total number +// of bytes for all record fields and all nested records, starting after the // length field) /* gpi tag handler */ static int -read_tag(const char *caller, const int tag, waypoint *wpt) +read_tag(const char* caller, const int tag, waypoint* wpt) { - int pos, sz, dist; - double speed; - short mask; - char *str; - garmin_fs_t *gmsd; - - sz = gbfgetint32(fin); - pos = gbftell(fin); - + int pos, sz, dist; + double speed; + short mask; + char* str; + garmin_fs_t* gmsd; + + sz = gbfgetint32(fin); + pos = gbftell(fin); + #ifdef GPI_DBG - PP; - dbginfo("%s: tag = 0x%x (size %d)\n", caller, tag, sz); + PP; + dbginfo("%s: tag = 0x%x (size %d)\n", caller, tag, sz); #endif - if ((tag >= 0x80000) && (tag <= 0x800ff)) sz += 4; - - switch(tag) { - case 0x3: /* size = 12 */ - case 0x80003: /* size = 12 */ - - dist = gbfgetint16(fin); /* proximity distance in meters */ - speed = (double)gbfgetint16(fin) / 100; /* speed in meters per second */ - - if (dist > 0) WAYPT_SET(wpt, proximity, dist); - if (speed > 0) { - /* speed isn't part of a normal waypoint - WAYPT_SET(wpt, speed, speed); - */ - if ((wpt->shortname == NULL) || (! strchr(wpt->shortname, '@'))) { - if (units == 's') speed = MPS_TO_MPH(speed); - else speed = MPS_TO_KPH(speed); - xasprintf(&str, "%s@%.f", wpt->shortname ? wpt->shortname : "WPT", speed); - if (wpt->shortname) xfree(wpt->shortname); - wpt->shortname = str; - } - } - - (void) gbfgetint32(fin); - (void) gbfgetint32(fin); - break; - - case 0x4: /* size = 2 ? */ - case 0x6: /* size = 2 ? */ - break; - - case 0x5: /* group bitmap */ - break; - - case 0x7: - (void) gbfgetint16(fin); /* category number */ - if (rdata->category) xfree(rdata->category); - rdata->category = gpi_read_string("Category"); - break; - - case 0xa: - wpt->description = gpi_read_string("Description"); - break; - - case 0xe: /* ? notes or description / or both ? */ - mask = gbfgetc(fin); - if (mask == 0x01) { - str = gpi_read_string("Notes"); - } - else if (mask == 0x32) { - str = gpi_read_string("Notes"); - } - else break; - - if (wpt->description) wpt->notes = str; - else wpt->description = str; - break; - - case 0x80002: - read_poi(sz); - break; - - case 0x80008: - read_poi_list(sz); - break; - - case 0x9: /* ? older versions / no category data ? */ - case 0x80009: /* current POI loader */ - read_poi_group(sz, tag); - break; - - case 0x8000b: /* address (street/city...) */ - (void) gbfgetint32(fin); - case 0xb: /* as seen in German POI files. */ - PP; - mask = gbfgetint16(fin); /* address fields mask */ + if ((tag >= 0x80000) && (tag <= 0x800ff)) { + sz += 4; + } + + switch (tag) { + case 0x3: /* size = 12 */ + case 0x80003: /* size = 12 */ + + dist = gbfgetint16(fin); /* proximity distance in meters */ + speed = (double)gbfgetint16(fin) / 100; /* speed in meters per second */ + + if (dist > 0) { + WAYPT_SET(wpt, proximity, dist); + } + if (speed > 0) { + /* speed isn't part of a normal waypoint + WAYPT_SET(wpt, speed, speed); + */ + if ((wpt->shortname == NULL) || (! strchr(wpt->shortname, '@'))) { + if (units == 's') { + speed = MPS_TO_MPH(speed); + } else { + speed = MPS_TO_KPH(speed); + } + xasprintf(&str, "%s@%.f", wpt->shortname ? wpt->shortname : "WPT", speed); + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = str; + } + } + + (void) gbfgetint32(fin); + (void) gbfgetint32(fin); + break; + + case 0x4: /* size = 2 ? */ + case 0x6: /* size = 2 ? */ + break; + + case 0x5: /* group bitmap */ + break; + + case 0x7: + (void) gbfgetint16(fin); /* category number */ + if (rdata->category) { + xfree(rdata->category); + } + rdata->category = gpi_read_string("Category"); + break; + + case 0xa: + wpt->description = gpi_read_string("Description"); + break; + + case 0xe: /* ? notes or description / or both ? */ + mask = gbfgetc(fin); + if (mask == 0x01) { + str = gpi_read_string("Notes"); + } else if (mask == 0x32) { + str = gpi_read_string("Notes"); + } else { + break; + } + + if (wpt->description) { + wpt->notes = str; + } else { + wpt->description = str; + } + break; + + case 0x2: + case 0x80002: + read_poi(sz, tag); + break; + + case 0x80008: + read_poi_list(sz); + break; + + case 0x9: /* ? older versions / no category data ? */ + case 0x80009: /* current POI loader */ + read_poi_group(sz, tag); + break; + + case 0x8000b: /* address (street/city...) */ + (void) gbfgetint32(fin); + case 0xb: /* as seen in German POI files. */ + PP; + mask = gbfgetint16(fin); /* address fields mask */ #ifdef GPI_DBG - dbginfo("GPI Address field mask: %d (0x%02x)\n", mask, mask); + dbginfo("GPI Address field mask: %d (0x%02x)\n", mask, mask); #endif - if ((mask & GPI_ADDR_CITY) && (str = gpi_read_string("City"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(city, str); - } - if ((mask & GPI_ADDR_COUNTRY) && (str = gpi_read_string("Country"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(country, str); - } - if ((mask & GPI_ADDR_STATE) && (str = gpi_read_string("State"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(state, str); - } - if ((mask & GPI_ADDR_POSTAL_CODE) && (str = gpi_read_string("Postal code"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(postal_code, str); - } - if ((mask & GPI_ADDR_ADDR) && (str = gpi_read_string("Street address"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(addr, str); - } - break; - - case 0xc: - mask = gbfgetint16(fin); - if ((mask & 1) && (str = gpi_read_string("Phone"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(phone_nr, str); - } - if ((mask & 2) && (str = gpi_read_string("Phone2"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(phone_nr2, str); - } - if ((mask & 4) && (str = gpi_read_string("Fax"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(fax_nr, str); - } - if ((mask & 8) && (str = gpi_read_string("Email"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(email, str); - } - if ((mask & 0x10) && (str = gpi_read_string("Link"))) { - waypt_add_url(wpt, xstrdup(str), xstrdup(str)); - } - break; - - case 0x8000c: /* phone-number */ - (void) gbfgetint32(fin); - PP; - - mask = gbfgetint16(fin); /* phone fields mask */ + if ((mask & GPI_ADDR_CITY) && (str = gpi_read_string("City"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(city, str); + } + if ((mask & GPI_ADDR_COUNTRY) && (str = gpi_read_string("Country"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(country, str); + } + if ((mask & GPI_ADDR_STATE) && (str = gpi_read_string("State"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(state, str); + } + if ((mask & GPI_ADDR_POSTAL_CODE) && (str = gpi_read_string("Postal code"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(postal_code, str); + } + if ((mask & GPI_ADDR_ADDR) && (str = gpi_read_string("Street address"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(addr, str); + } + break; + + case 0xc: + mask = gbfgetint16(fin); + if ((mask & 1) && (str = gpi_read_string("Phone"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(phone_nr, str); + } + if ((mask & 2) && (str = gpi_read_string("Phone2"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(phone_nr2, str); + } + if ((mask & 4) && (str = gpi_read_string("Fax"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(fax_nr, str); + } + if ((mask & 8) && (str = gpi_read_string("Email"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(email, str); + } + if ((mask & 0x10) && (str = gpi_read_string("Link"))) { + waypt_add_url(wpt, xstrdup(str), str); + } + break; + + case 0x8000c: /* phone-number */ + (void) gbfgetint32(fin); + PP; + + mask = gbfgetint16(fin); /* phone fields mask */ #ifdef GPI_DBG - dbginfo("GPI Phone field mask: %d (0x%02x)\n", mask, mask); + dbginfo("GPI Phone field mask: %d (0x%02x)\n", mask, mask); #endif - if ((mask & 1) && (str = gpi_read_string("Phone"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(phone_nr, str); - } - break; - - case 0x80012: /* ? sounds / images ? */ - break; - - /* Images? Seen in http://geepeeex.com/Stonepages.gpi */ - case 0xd: - break; - - case 0x11: - case 0x80007: - /* Looks like some kind of calendar information. */ + if ((mask & 1) && (str = gpi_read_string("Phone"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(phone_nr, str); + } + break; + + case 0x80012: /* ? sounds / images ? */ + break; + + /* Images? Seen in http://geepeeex.com/Stonepages.gpi */ + case 0xd: + break; + + case 0x11: + case 0x80007: + /* Looks like some kind of calendar information. */ #ifdef GPI_DBG - { - int x; - unsigned char *b = xmalloc(sz); - fprintf(stderr, "Tag: %x\n", tag); - gbfread(b, 1, sz, fin); - fprintf(stderr, "\n"); - for (x = 0; x < sz; x++) - fprintf(stderr, "%02x ", b[x]); - fprintf(stderr, "\n"); - for (x = 0; x < sz; x++) - fprintf(stderr, "%c", isalnum(b[x]) ? b[x] : '.'); - fprintf(stderr, "\n"); - } + { + int x; + unsigned char* b = xmalloc(sz); + fprintf(stderr, "Tag: %x\n", tag); + gbfread(b, 1, sz, fin); + fprintf(stderr, "\n"); + for (x = 0; x < sz; x++) { + fprintf(stderr, "%02x ", b[x]); + } + fprintf(stderr, "\n"); + for (x = 0; x < sz; x++) { + fprintf(stderr, "%c", isalnum(b[x]) ? b[x] : '.'); + } + fprintf(stderr, "\n"); + } #endif // GPI_DBG - break; - default: - warning(MYNAME ": Unknown tag (0x%x). Please report!\n", tag); - return 0; - } - gbfseek(fin, pos + sz, SEEK_SET); - return 1; + break; + default: + warning(MYNAME ": Unknown tag (0x%x). Please report!\n", tag); + return 0; + } + gbfseek(fin, pos + sz, SEEK_SET); + return 1; } /******************************************************************************* @@ -638,605 +701,704 @@ read_tag(const char *caller, const int tag, waypoint *wpt) *******************************************************************************/ static void -write_string(const char *str, const char long_format) +write_string(const char* str, const char long_format) { - int len; - - len = strlen(str); - if (long_format) { - gbfputint32(len + 4, fout); - gbfwrite("EN", 1, 2, fout); - } - gbfputint16(len, fout); - gbfwrite(str, 1, len, fout); + int len; + + len = strlen(str); + if (long_format) { + gbfputint32(len + 4, fout); + gbfwrite("EN", 1, 2, fout); + } + gbfputint16(len, fout); + gbfwrite(str, 1, len, fout); } static int -compare_wpt_cb(const queue *a, const queue *b) +compare_wpt_cb(const queue* a, const queue* b) { - const waypoint *wa = (waypoint *) a; - const waypoint *wb = (waypoint *) b; - - return strcmp(wa->shortname, wb->shortname); + const waypoint* wa = (waypoint*) a; + const waypoint* wb = (waypoint*) b; + + return strcmp(wa->shortname, wb->shortname); } static char -compare_strings(const char *s1, const char *s2) +compare_strings(const char* s1, const char* s2) { - if (s1 == s2) return 0; - else if (s1) { - if (s2) return strcmp(s1, s2); - else return 1; - } - else return 1; + if (s1 == s2) { + return 0; + } else if (s1) { + if (s2) { + return strcmp(s1, s2); + } else { + return 1; + } + } else { + return 1; + } } -static writer_data_t * +static writer_data_t* wdata_alloc() { - writer_data_t *res; + writer_data_t* res; - res = xcalloc(1, sizeof(*res)); - QUEUE_INIT(&res->Q); - waypt_init_bounds(&res->bds); + res = (writer_data_t*) xcalloc(1, sizeof(*res)); + QUEUE_INIT(&res->Q); + waypt_init_bounds(&res->bds); - return res; + return res; } static void -wdata_free(writer_data_t *data) +wdata_free(writer_data_t* data) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - - if (wpt->extra_data) { - gpi_waypt_t *dt = (gpi_waypt_t *) wpt->extra_data; - if (dt->addr_is_dynamic) xfree(dt->addr); - xfree(dt); - } - waypt_free(wpt); - } - - if (data->top_left) wdata_free(data->top_left); - if (data->top_right) wdata_free(data->top_right); - if (data->buttom_left) wdata_free(data->buttom_left); - if (data->buttom_right) wdata_free(data->buttom_right); - - xfree(data); + queue* elem, *tmp; + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint* wpt = (waypoint*)elem; + + if (wpt->extra_data) { + gpi_waypt_t* dt = (gpi_waypt_t*) wpt->extra_data; + if (dt->addr_is_dynamic) { + xfree(dt->addr); + } + xfree(dt); + } + waypt_free(wpt); + } + + if (data->top_left) { + wdata_free(data->top_left); + } + if (data->top_right) { + wdata_free(data->top_right); + } + if (data->buttom_left) { + wdata_free(data->buttom_left); + } + if (data->buttom_right) { + wdata_free(data->buttom_right); + } + + xfree(data); } static void -wdata_add_wpt(writer_data_t *data, waypoint *wpt) +wdata_add_wpt(writer_data_t* data, waypoint* wpt) { - data->ct++; - ENQUEUE_TAIL(&data->Q, &wpt->Q); - waypt_add_to_bounds(&data->bds, wpt); + data->ct++; + ENQUEUE_TAIL(&data->Q, &wpt->Q); + waypt_add_to_bounds(&data->bds, wpt); } static void -wdata_check(writer_data_t *data) +wdata_check(writer_data_t* data) { - queue *elem, *tmp; - double center_lat, center_lon; - - if ((data->ct <= WAYPOINTS_PER_BLOCK) || - /* avoid endless loop for points (more than WAYPOINTS_PER_BLOCK) - at same coordinates */ - ((data->bds.min_lat >= data->bds.max_lat) && (data->bds.min_lon >= data->bds.max_lon))) { - if (data->ct > 1) - sortqueue(&data->Q, compare_wpt_cb); - return; - } - - /* compute the (mean) center of current bounds */ - - center_lat = center_lon = 0; - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - waypoint *wpt = (waypoint *) elem; - center_lat += wpt->latitude; - center_lon += wpt->longitude; - } - center_lat /= data->ct; - center_lon /= data->ct; - - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - waypoint *wpt = (waypoint *) elem; - writer_data_t **ref; - - if (wpt->latitude < center_lat) { - if (wpt->longitude < center_lon) - ref = &data->buttom_left; - else - ref = &data->buttom_right; - } else { - if (wpt->longitude < center_lon) - ref = &data->top_left; - else - ref = &data->top_right; - } - - if (*ref == NULL) *ref = wdata_alloc(); - - data->ct--; - dequeue(&wpt->Q); - - wdata_add_wpt(*ref, wpt); - } - - if (data->top_left) wdata_check(data->top_left); - if (data->top_right) wdata_check(data->top_right); - if (data->buttom_left) wdata_check(data->buttom_left); - if (data->buttom_right) wdata_check(data->buttom_right); + queue* elem, *tmp; + double center_lat, center_lon; + + if ((data->ct <= WAYPOINTS_PER_BLOCK) || + /* avoid endless loop for points (more than WAYPOINTS_PER_BLOCK) + at same coordinates */ + ((data->bds.min_lat >= data->bds.max_lat) && (data->bds.min_lon >= data->bds.max_lon))) { + if (data->ct > 1) { + sortqueue(&data->Q, compare_wpt_cb); + } + return; + } + + /* compute the (mean) center of current bounds */ + + center_lat = center_lon = 0; + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint* wpt = (waypoint*) elem; + center_lat += wpt->latitude; + center_lon += wpt->longitude; + } + center_lat /= data->ct; + center_lon /= data->ct; + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint* wpt = (waypoint*) elem; + writer_data_t** ref; + + if (wpt->latitude < center_lat) { + if (wpt->longitude < center_lon) { + ref = &data->buttom_left; + } else { + ref = &data->buttom_right; + } + } else { + if (wpt->longitude < center_lon) { + ref = &data->top_left; + } else { + ref = &data->top_right; + } + } + + if (*ref == NULL) { + *ref = wdata_alloc(); + } + + data->ct--; + dequeue(&wpt->Q); + + wdata_add_wpt(*ref, wpt); + } + + if (data->top_left) { + wdata_check(data->top_left); + } + if (data->top_right) { + wdata_check(data->top_right); + } + if (data->buttom_left) { + wdata_check(data->buttom_left); + } + if (data->buttom_right) { + wdata_check(data->buttom_right); + } } static int -wdata_compute_size(writer_data_t *data) +wdata_compute_size(writer_data_t* data) { - queue *elem, *tmp; - int res; - - res = 23; /* bounds, ... of tag 0x80008 */ - - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - waypoint *wpt = (waypoint *) elem; - gpi_waypt_t *dt; - garmin_fs_t *gmsd; - char *str; - - res += 12; /* tag/sz/sub-sz */ - res += 19; /* poi fixed size */ - res += strlen(wpt->shortname); - if (! opt_hide_bitmap) res += 10; /* tag(4) */ - - dt = xcalloc(1, sizeof(*dt)); - wpt->extra_data = dt; - - if (alerts) { - char *pos; - - if ((pos = strchr(wpt->shortname, '@'))) { - double speed, scale; - if (units == 's') scale = MPH_TO_MPS(1); - else scale = KPH_TO_MPS(1); - parse_speed(pos + 1, &speed, scale, MYNAME); - if (speed > 0) WAYPT_SET(wpt, speed, speed); -#if 0 - if (pos > wpt->shortname) wpt->shortname[pos - wpt->shortname] = '\0'; + queue* elem, *tmp; + int res; + + res = 23; /* bounds, ... of tag 0x80008 */ + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint* wpt = (waypoint*) elem; + gpi_waypt_t* dt; + garmin_fs_t* gmsd; + char* str; + + res += 12; /* tag/sz/sub-sz */ + res += 19; /* poi fixed size */ + res += strlen(wpt->shortname); + if (! opt_hide_bitmap) { + res += 10; /* tag(4) */ + } + + dt = (gpi_waypt_t*) xcalloc(1, sizeof(*dt)); + wpt->extra_data = dt; + + if (alerts) { + char* pos; + + if ((pos = strchr(wpt->shortname, '@'))) { + double speed, scale; + if (units == 's') { + scale = MPH_TO_MPS(1); + } else { + scale = KPH_TO_MPS(1); + } + parse_speed(pos + 1, &speed, scale, MYNAME); + if (speed > 0) { + WAYPT_SET(wpt, speed, speed); + } +#if 0 + if (pos > wpt->shortname) { + wpt->shortname[pos - wpt->shortname] = '\0'; + } #endif - } - else if ((opt_speed) && (! WAYPT_HAS(wpt, speed))) - WAYPT_SET(wpt, speed, defspeed); - - if ((opt_proximity) && (! WAYPT_HAS(wpt, proximity))) - WAYPT_SET(wpt, proximity, defproximity); - - if ((WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) || - (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0))) { - data->alert = 1; - dt->alerts++; - res += 20; /* tag(3) */ - } - } - - str = NULL; - if (opt_descr) { - if (wpt->description && *wpt->description) - str = xstrdup(wpt->description); - } - else if (opt_notes) { - if (wpt->notes && *wpt->notes) - str = xstrdup(wpt->notes); - } - else if (opt_pos) - str = pretty_deg_format(wpt->latitude, wpt->longitude, 's', " ", 0); - - - if (str) { - dt->addr_is_dynamic = 1; - dt->addr = str; - dt->mask |= GPI_ADDR_ADDR; - dt->sz += (8 + strlen(dt->addr)); - } - - if ((gmsd = GMSD_FIND(wpt))) { - if ((dt->mask == 0) && ((dt->addr = GMSD_GET(addr, NULL)))) { - dt->mask |= GPI_ADDR_ADDR; - dt->sz += (8 + strlen(dt->addr)); - } - if ((dt->city = GMSD_GET(city, NULL))) { - dt->mask |= GPI_ADDR_CITY; - dt->sz += (8 + strlen(dt->city)); - } - if ((dt->country = GMSD_GET(country, NULL))) { - dt->mask |= GPI_ADDR_COUNTRY; - dt->sz += (8 + strlen(dt->country)); - } - if ((dt->state = GMSD_GET(state, NULL))) { - dt->mask |= GPI_ADDR_STATE; - dt->sz += (8 + strlen(dt->state)); - } - if ((dt->postal_code = GMSD_GET(postal_code, NULL))) { - dt->mask |= GPI_ADDR_POSTAL_CODE; - dt->sz += (2 + strlen(dt->postal_code)); /* short form */ - } - - if ((dt->phone_nr = GMSD_GET(phone_nr, NULL))) - res += (12 + 4 + strlen(dt->phone_nr)); - } - if (dt->mask) dt->sz += 2; /* + mask (two bytes) */ - if (dt->sz) res += (dt->sz + 12); /* + header size */ - - str = wpt->description; - if (! str) str = wpt->notes; + } else if ((opt_speed) && (! WAYPT_HAS(wpt, speed))) { + WAYPT_SET(wpt, speed, defspeed); + } + + if ((opt_proximity) && (! WAYPT_HAS(wpt, proximity))) { + WAYPT_SET(wpt, proximity, defproximity); + } + + if ((WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) || + (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0))) { + data->alert = 1; + dt->alerts++; + res += 20; /* tag(3) */ + } + } + + str = NULL; + if (opt_descr) { + if (wpt->description && *wpt->description) { + str = xstrdup(wpt->description); + } + } else if (opt_notes) { + if (wpt->notes && *wpt->notes) { + str = xstrdup(wpt->notes); + } + } else if (opt_pos) { + str = pretty_deg_format(wpt->latitude, wpt->longitude, 's', " ", 0); + } + + + if (str) { + dt->addr_is_dynamic = 1; + dt->addr = str; + dt->mask |= GPI_ADDR_ADDR; + dt->sz += (8 + strlen(dt->addr)); + } + + if ((gmsd = GMSD_FIND(wpt))) { + if ((dt->mask == 0) && ((dt->addr = GMSD_GET(addr, NULL)))) { + dt->mask |= GPI_ADDR_ADDR; + dt->sz += (8 + strlen(dt->addr)); + } + if ((dt->city = GMSD_GET(city, NULL))) { + dt->mask |= GPI_ADDR_CITY; + dt->sz += (8 + strlen(dt->city)); + } + if ((dt->country = GMSD_GET(country, NULL))) { + dt->mask |= GPI_ADDR_COUNTRY; + dt->sz += (8 + strlen(dt->country)); + } + if ((dt->state = GMSD_GET(state, NULL))) { + dt->mask |= GPI_ADDR_STATE; + dt->sz += (8 + strlen(dt->state)); + } + if ((dt->postal_code = GMSD_GET(postal_code, NULL))) { + dt->mask |= GPI_ADDR_POSTAL_CODE; + dt->sz += (2 + strlen(dt->postal_code)); /* short form */ + } + + if ((dt->phone_nr = GMSD_GET(phone_nr, NULL))) { + res += (12 + 4 + strlen(dt->phone_nr)); + } + } + if (dt->mask) { + dt->sz += 2; /* + mask (two bytes) */ + } + if (dt->sz) { + res += (dt->sz + 12); /* + header size */ + } + + str = wpt->description; + if (! str) { + str = wpt->notes; + } // if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; - if (str) res += (12 + 4 + strlen(str)); - } - - if (data->top_left) res += wdata_compute_size(data->top_left); - if (data->top_right) res += wdata_compute_size(data->top_right); - if (data->buttom_left) res += wdata_compute_size(data->buttom_left); - if (data->buttom_right) res += wdata_compute_size(data->buttom_right); - - data->sz = res; - - return res + 12; /* + 12 = caller needs info about tag header size */ + if (str) { + res += (12 + 4 + strlen(str)); + } + } + + if (data->top_left) { + res += wdata_compute_size(data->top_left); + } + if (data->top_right) { + res += wdata_compute_size(data->top_right); + } + if (data->buttom_left) { + res += wdata_compute_size(data->buttom_left); + } + if (data->buttom_right) { + res += wdata_compute_size(data->buttom_right); + } + + data->sz = res; + + return res + 12; /* + 12 = caller needs info about tag header size */ } static void -wdata_write(const writer_data_t *data) +wdata_write(const writer_data_t* data) { - queue *elem, *tmp; - - gbfputint32(0x80008, fout); - gbfputint32(data->sz, fout); - gbfputint32(23, fout); /* bounds + three bytes */ - - gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lat), fout); - gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lon), fout); - gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lat), fout); - gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lon), fout); - - gbfputint32(0, fout); - gbfputint16(1, fout); - gbfputc(data->alert, fout); - - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - char *str; - int s0, s1; - waypoint *wpt = (waypoint *)elem; - gpi_waypt_t *dt = wpt->extra_data; - - str = wpt->description; - if (! str) str = wpt->notes; + queue* elem, *tmp; + + gbfputint32(0x80008, fout); + gbfputint32(data->sz, fout); + gbfputint32(23, fout); /* bounds + three bytes */ + + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lat), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lon), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lat), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lon), fout); + + gbfputint32(0, fout); + gbfputint16(1, fout); + gbfputc(data->alert, fout); + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + char* str; + int s0, s1; + waypoint* wpt = (waypoint*)elem; + gpi_waypt_t* dt = (gpi_waypt_t*) wpt->extra_data; + + str = wpt->description; + if (! str) { + str = wpt->notes; + } // if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; - gbfputint32(0x80002, fout); - - s0 = s1 = 19 + strlen(wpt->shortname); - if (! opt_hide_bitmap) s0 += 10; /* tag(4) */ - if (str) s0 += (12 + 4 + strlen(str)); /* descr */ - if (dt->sz) s0 += (12 + dt->sz); /* address part */ - if (dt->phone_nr) s0 += (12 + 4 + strlen(dt->phone_nr)); - if (dt->alerts) s0 += 20; /* tag(3) */ - - gbfputint32(s0, fout); /* size of following data (tag) */ - gbfputint32(s1, fout); /* basic size (without options) */ - - gbfputint32(GPS_Math_Deg_To_Semi(wpt->latitude), fout); - gbfputint32(GPS_Math_Deg_To_Semi(wpt->longitude), fout); - - gbfputint16(1, fout); /* ? always 1 ? */ - gbfputc(alerts, fout); /* seems to be 1 when extra options present */ - - write_string(wpt->shortname, 1); - - if (dt->alerts) { - char flag = 0; - - gbfputint32(3, fout); /* tag(3) */ - gbfputint32(12, fout); /* always 12 */ - - if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) { - gbfputint16((int) wpt->proximity, fout); - flag = 4; - } - else - gbfputint16(0, fout); - if (WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) { - gbfputint16((int) (wpt->speed * 100), fout); - flag = 5; - } - else - gbfputint16(0, fout); - - gbfputint32(0x100100, fout); /* ??? */ - gbfputc(1, fout); /* ??? */ - gbfputc(1, fout); /* ??? */ - gbfputc(flag, fout); - gbfputc(0x10, fout); /* ??? */ - } - - if (! opt_hide_bitmap) { - gbfputint32(4, fout); /* tag(4) */ - gbfputint32(2, fout); /* ? always 2 == version ??? */ - gbfputint16(0, fout); - } - - if (str) { - gbfputint32(0xa, fout); - gbfputint32(strlen(str) + 8, fout); /* string + string header */ - write_string(str, 1); - } - - if (dt->sz) { /* gpi address */ - gbfputint32(0x8000b, fout); - gbfputint32(dt->sz, fout); - gbfputint32(0x2, fout); /* ? always 2 ? */ - gbfputint16(dt->mask, fout); - if (dt->mask & GPI_ADDR_CITY) write_string(dt->city, 1); - if (dt->mask & GPI_ADDR_COUNTRY) write_string(dt->country, 1); - if (dt->mask & GPI_ADDR_STATE) write_string(dt->state, 1); - if (dt->mask & GPI_ADDR_POSTAL_CODE) write_string(dt->postal_code, 0); - if (dt->mask & GPI_ADDR_ADDR) write_string(dt->addr, 1); - } - - if (dt->phone_nr) { - gbfputint32(0x8000c, fout); - gbfputint32(strlen(dt->phone_nr) + 2 + 2, fout); - gbfputint32(0x2, fout); /* ? always 2 ? */ - gbfputint16(1, fout); /* mask */ - write_string(dt->phone_nr, 0); - } - } - - if (data->top_left) wdata_write(data->top_left); - if (data->top_right) wdata_write(data->top_right); - if (data->buttom_left) wdata_write(data->buttom_left); - if (data->buttom_right) wdata_write(data->buttom_right); + gbfputint32(0x80002, fout); + + s0 = s1 = 19 + strlen(wpt->shortname); + if (! opt_hide_bitmap) { + s0 += 10; /* tag(4) */ + } + if (str) { + s0 += (12 + 4 + strlen(str)); /* descr */ + } + if (dt->sz) { + s0 += (12 + dt->sz); /* address part */ + } + if (dt->phone_nr) { + s0 += (12 + 4 + strlen(dt->phone_nr)); + } + if (dt->alerts) { + s0 += 20; /* tag(3) */ + } + + gbfputint32(s0, fout); /* size of following data (tag) */ + gbfputint32(s1, fout); /* basic size (without options) */ + + gbfputint32(GPS_Math_Deg_To_Semi(wpt->latitude), fout); + gbfputint32(GPS_Math_Deg_To_Semi(wpt->longitude), fout); + + gbfputint16(1, fout); /* ? always 1 ? */ + gbfputc(alerts, fout); /* seems to be 1 when extra options present */ + + write_string(wpt->shortname, 1); + + if (dt->alerts) { + char flag = 0; + + gbfputint32(3, fout); /* tag(3) */ + gbfputint32(12, fout); /* always 12 */ + + if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) { + gbfputint16((int) wpt->proximity, fout); + flag = 4; + } else { + gbfputint16(0, fout); + } + if (WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) { + gbfputint16((int)(wpt->speed * 100), fout); + flag = 5; + } else { + gbfputint16(0, fout); + } + + gbfputint32(0x100100, fout); /* ??? */ + gbfputc(1, fout); /* ??? */ + gbfputc(1, fout); /* ??? */ + gbfputc(flag, fout); + gbfputc(0x10, fout); /* ??? */ + } + + if (! opt_hide_bitmap) { + gbfputint32(4, fout); /* tag(4) */ + gbfputint32(2, fout); /* ? always 2 == version ??? */ + gbfputint16(0, fout); + } + + if (str) { + gbfputint32(0xa, fout); + gbfputint32(strlen(str) + 8, fout); /* string + string header */ + write_string(str, 1); + } + + if (dt->sz) { /* gpi address */ + gbfputint32(0x8000b, fout); + gbfputint32(dt->sz, fout); + gbfputint32(0x2, fout); /* ? always 2 ? */ + gbfputint16(dt->mask, fout); + if (dt->mask & GPI_ADDR_CITY) { + write_string(dt->city, 1); + } + if (dt->mask & GPI_ADDR_COUNTRY) { + write_string(dt->country, 1); + } + if (dt->mask & GPI_ADDR_STATE) { + write_string(dt->state, 1); + } + if (dt->mask & GPI_ADDR_POSTAL_CODE) { + write_string(dt->postal_code, 0); + } + if (dt->mask & GPI_ADDR_ADDR) { + write_string(dt->addr, 1); + } + } + + if (dt->phone_nr) { + gbfputint32(0x8000c, fout); + gbfputint32(strlen(dt->phone_nr) + 2 + 2, fout); + gbfputint32(0x2, fout); /* ? always 2 ? */ + gbfputint16(1, fout); /* mask */ + write_string(dt->phone_nr, 0); + } + } + + if (data->top_left) { + wdata_write(data->top_left); + } + if (data->top_right) { + wdata_write(data->top_right); + } + if (data->buttom_left) { + wdata_write(data->buttom_left); + } + if (data->buttom_right) { + wdata_write(data->buttom_right); + } } static void -write_category(const char *category, const char *image, const int image_sz) +write_category(const char* category, const char* image, const int image_sz) { - int sz; - - sz = wdata_compute_size(wdata); - sz += 8; /* string header */ - sz += strlen(opt_cat); - - gbfputint32(0x80009, fout); - if ((! opt_hide_bitmap) && image_sz) - gbfputint32(sz + image_sz + 8, fout); - else - gbfputint32(sz, fout); - gbfputint32(sz, fout); - write_string(opt_cat, 1); - - wdata_write(wdata); - - if ((! opt_hide_bitmap) && image_sz) { - gbfputint32(5, fout); - gbfputint32(image_sz, fout); - gbfwrite(image, 1, image_sz, fout); - } + int sz; + + sz = wdata_compute_size(wdata); + sz += 8; /* string header */ + sz += strlen(opt_cat); + + gbfputint32(0x80009, fout); + if ((! opt_hide_bitmap) && image_sz) { + gbfputint32(sz + image_sz + 8, fout); + } else { + gbfputint32(sz, fout); + } + gbfputint32(sz, fout); + write_string(opt_cat, 1); + + wdata_write(wdata); + + if ((! opt_hide_bitmap) && image_sz) { + gbfputint32(5, fout); + gbfputint32(image_sz, fout); + gbfwrite(image, 1, image_sz, fout); + } } static void write_header(void) { - time_t time = gpi_timestamp; - - if (time != 0) { - struct tm tm; - tm = *gmtime(&time); - tm.tm_year -= 20; - time = mkgmtime(&tm); - time += SECONDS_PER_DAY; - } - - gbfputint32(0, fout); - gbfputint32(0x16, fout); - gbfwrite("GRMREC00", 1, 8, fout); - gbfputint32(time, fout); - gbfputint16(0, fout); - gbfputint16(6, fout); - gbfwrite("my.gpi", 1, 6, fout); - gbfputint32(1, fout); - gbfputint32(0xc, fout); - gbfwrite("POI", 1, 3, fout); - gbfputc(0, fout); - gbfputc(0, fout); - gbfputc(0, fout); - gbfwrite("00", 1, 2, fout); - gbfputint16(codepage, fout); - gbfputint16(0, fout); + time_t time = gpi_timestamp; + + if (time != 0) { + struct tm tm; + tm = *gmtime(&time); + tm.tm_year -= 20; + time = mkgmtime(&tm); + time += SECONDS_PER_DAY; + } + + gbfputint32(0, fout); + gbfputint32(0x16, fout); + gbfwrite("GRMREC00", 1, 8, fout); + gbfputint32(time, fout); + gbfputint16(0, fout); + gbfputint16(6, fout); + gbfwrite("my.gpi", 1, 6, fout); + gbfputint32(1, fout); + gbfputint32(0xc, fout); + gbfwrite("POI", 1, 3, fout); + gbfputc(0, fout); + gbfputc(0, fout); + gbfputc(0, fout); + gbfwrite("00", 1, 2, fout); + gbfputint16(codepage, fout); + gbfputint16(0, fout); } static void -enum_waypt_cb(const waypoint *ref) +enum_waypt_cb(const waypoint* ref) { - waypoint *wpt; - char *str; - queue *elem, *tmp; - - QUEUE_FOR_EACH(&wdata->Q, elem, tmp) { - waypoint *cmp = (waypoint *) elem; - - /* sort out nearly equal waypoints */ - if ((compare_strings(cmp->shortname, ref->shortname) == 0) && - (cmp->latitude == ref->latitude) && - (cmp->longitude == ref->longitude) && - (compare_strings(cmp->description, ref->description) == 0) && - (compare_strings(cmp->notes, ref->notes) == 0)) return; - } - - wpt = waypt_dupe(ref); - - if (*opt_unique == '1') { - str = mkshort(short_h, wpt->shortname); - xfree(wpt->shortname); - wpt->shortname = str; - } - - wdata_add_wpt(wdata, wpt); + waypoint* wpt; + char* str; + queue* elem, *tmp; + + QUEUE_FOR_EACH(&wdata->Q, elem, tmp) { + waypoint* cmp = (waypoint*) elem; + + /* sort out nearly equal waypoints */ + if ((compare_strings(cmp->shortname, ref->shortname) == 0) && + (cmp->latitude == ref->latitude) && + (cmp->longitude == ref->longitude) && + (compare_strings(cmp->description, ref->description) == 0) && + (compare_strings(cmp->notes, ref->notes) == 0)) { + return; + } + } + + wpt = waypt_dupe(ref); + + if (*opt_unique == '1') { + str = mkshort(short_h, wpt->shortname); + xfree(wpt->shortname); + wpt->shortname = str; + } + + wdata_add_wpt(wdata, wpt); } static void -load_bitmap_from_file(const char *fname, char **data, int *data_sz) +load_bitmap_from_file(const char* fname, char** data, int* data_sz) { - gbfile *f; - int i, sz; - int dest_bpp; - int src_line_sz, dest_line_sz; - bmp_header_t src_h; - int *color_table = NULL; - gpi_bitmap_header_t *dest_h; - char *ptr; - - f = gbfopen_le(fname, "rb", MYNAME); - is_fatal(gbfgetint16(f) != 0x4d42, MYNAME ": No BMP image."); - - /* read a standard bmp file header */ - src_h.size = gbfgetint32(f); - src_h.res1 = gbfgetint16(f); - src_h.res2 = gbfgetint16(f); - src_h.image_offset = gbfgetint32(f); - src_h.header_size = gbfgetint32(f); - src_h.width = gbfgetint32(f); - src_h.height = gbfgetint32(f); - src_h.planes = gbfgetint16(f); - src_h.bpp = gbfgetint16(f); - src_h.compression_type = gbfgetint32(f); - src_h.image_data_size = gbfgetint32(f); - src_h.resolution_h = gbfgetint32(f); - src_h.resolution_v = gbfgetint32(f); - src_h.used_colors = gbfgetint32(f); - src_h.important_colors = gbfgetint32(f); - - /* Workaround for indexed BMP's with used_colors = 0 */ - if ((src_h.bpp == 8) && (src_h.used_colors == 0)) - src_h.used_colors = (src_h.image_offset - gbftell(f)) / 4; + gbfile* f; + int i, sz; + int dest_bpp; + int src_line_sz, dest_line_sz; + bmp_header_t src_h; + int* color_table = NULL; + gpi_bitmap_header_t* dest_h; + char* ptr; + + f = gbfopen_le(fname, "rb", MYNAME); + is_fatal(gbfgetint16(f) != 0x4d42, MYNAME ": No BMP image."); + + /* read a standard bmp file header */ + src_h.size = gbfgetint32(f); + src_h.res1 = gbfgetint16(f); + src_h.res2 = gbfgetint16(f); + src_h.image_offset = gbfgetint32(f); + src_h.header_size = gbfgetint32(f); + src_h.width = gbfgetint32(f); + src_h.height = gbfgetint32(f); + src_h.planes = gbfgetint16(f); + src_h.bpp = gbfgetint16(f); + src_h.compression_type = gbfgetint32(f); + src_h.image_data_size = gbfgetint32(f); + src_h.resolution_h = gbfgetint32(f); + src_h.resolution_v = gbfgetint32(f); + src_h.used_colors = gbfgetint32(f); + src_h.important_colors = gbfgetint32(f); + + /* Workaround for indexed BMP's with used_colors = 0 */ + if ((src_h.bpp == 8) && (src_h.used_colors == 0)) { + src_h.used_colors = (src_h.image_offset - gbftell(f)) / 4; + } #ifdef GPI_DBG - printf("data size: 0x%1$x (%1$d)\n", src_h.size); - printf("image data offset: 0x%1$x (%1$d)\n", src_h.image_offset); - printf("header size: 0x%1$x (%1$d)\n", src_h.header_size); - printf("image width: 0x%1$x (%1$d)\n", src_h.width); - printf("image height: 0x%1$x (%1$d)\n", src_h.height); - printf("number of planes: 0x%1$x (%1$d)\n", src_h.planes); - printf("bits per pixel: 0x%1$x (%1$d)\n", src_h.bpp); - printf("compression type: 0x%1$x (%1$d)\n", src_h.compression_type); - printf("image size: 0x%1$x (%1$d)\n", src_h.image_data_size); - printf("horizontal resolution: 0x%1$x (%1$d)\n", src_h.resolution_h); - printf("vertical resolution: 0x%1$x (%1$d)\n", src_h.resolution_v); - printf("number of colors: 0x%1$x (%1$d)\n", src_h.used_colors); - printf("important colors: 0x%1$x (%1$d)\n", src_h.important_colors); + printf("data size: 0x%1$x (%1$d)\n", src_h.size); + printf("image data offset: 0x%1$x (%1$d)\n", src_h.image_offset); + printf("header size: 0x%1$x (%1$d)\n", src_h.header_size); + printf("image width: 0x%1$x (%1$d)\n", src_h.width); + printf("image height: 0x%1$x (%1$d)\n", src_h.height); + printf("number of planes: 0x%1$x (%1$d)\n", src_h.planes); + printf("bits per pixel: 0x%1$x (%1$d)\n", src_h.bpp); + printf("compression type: 0x%1$x (%1$d)\n", src_h.compression_type); + printf("image size: 0x%1$x (%1$d)\n", src_h.image_data_size); + printf("horizontal resolution: 0x%1$x (%1$d)\n", src_h.resolution_h); + printf("vertical resolution: 0x%1$x (%1$d)\n", src_h.resolution_v); + printf("number of colors: 0x%1$x (%1$d)\n", src_h.used_colors); + printf("important colors: 0x%1$x (%1$d)\n", src_h.important_colors); #endif - - /* sort out unsupported files */ - if (! ((src_h.width <= 24) && (src_h.height <= 24) && - (src_h.width > 0) && (src_h.height > 0))) - fatal(MYNAME ": Unsupported format (%dx%d)!\n", src_h.width, src_h.height); - if (! ((src_h.bpp == 8) || (src_h.bpp == 24) || (src_h.bpp == 32))) - fatal(MYNAME ": Unsupported color depth (%d)!\n", src_h.bpp); - if (! (src_h.compression_type == 0)) - fatal(MYNAME ": Sorry, we don't support compressed bitmaps.\n"); - - if (src_h.used_colors > 0) { - color_table = xmalloc(4 * src_h.used_colors); - gbfread(color_table, 1, 4 * src_h.used_colors, f); - for (i = 0; i < src_h.used_colors; i++) { - int color = color_table[i]; - /* swap blue and red value */ - color = (color >> 16) | (color << 16) | (color & 0x00ff00); - color_table[i] = color & 0xffffff; - } - } - - /* calculate line-size for source and destination */ - src_line_sz = (src_h.width * src_h.bpp) / 8; - src_line_sz = ((int)((src_line_sz + 3) / 4)) * 4; - - if (src_h.bpp == 24) dest_bpp = 32; - else dest_bpp = src_h.bpp; - - dest_line_sz = (src_h.width * dest_bpp) / 8; - dest_line_sz = ((int)((dest_line_sz + 3) / 4)) * 4; - - sz = sizeof(*dest_h) + (src_h.height * dest_line_sz); - if (src_h.used_colors) sz += (src_h.used_colors * 4); - - ptr = xmalloc(sz); - dest_h = (void *)ptr; - *data = ptr; - *data_sz = sz; - - le_write16(&dest_h->index, 0); - le_write16(&dest_h->height, src_h.height); - le_write16(&dest_h->width, src_h.width); - le_write16(&dest_h->line_sz, dest_line_sz); - le_write16(&dest_h->bpp, dest_bpp); - le_write16(&dest_h->fixed_0, 0); /* seems to be fixed */ - le_write32(&dest_h->image_size, dest_line_sz * src_h.height); - le_write32(&dest_h->fixed_2c, 0x2c); /* seems to be fixed */ - le_write32(&dest_h->flag1, (dest_bpp == 8) ? 0x100 : 0); - le_write32(&dest_h->tr_color, 0xff00ff); /* magenta = transparent color */ - le_write32(&dest_h->flag2, 0x1); /* ? enable transparent mode ? */ - le_write32(&dest_h->size_2c, (dest_line_sz * src_h.height) + 0x2c); - - /* copy and revert order of BMP lines */ - ptr = (void *)dest_h; - ptr += (sizeof(*dest_h) + (dest_line_sz * (src_h.height - 1))); - - if (src_h.bpp == 24) { - /* 24 bpp seems to be not supported, convert to 32 bpp */ - for (i = 0; i < src_h.height; i++) { - int j; - char *p = ptr; - - for (j = 0; j < src_h.width; j++) { - int color; - color = (gbint32)gbfgetint16(f) | (gbfgetc(f) << 16); - le_write32(p, color); - p += 4; - } - for (j = (src_h.width * src_h.bpp) / 8; j < src_line_sz; j++) { - gbfgetc(f); /* drop fill-in bytes */ - } - ptr -= dest_line_sz; - } - } - else for (i = 0; i < src_h.height; i++) { - gbfread(ptr, 1, src_line_sz, f); - ptr -= dest_line_sz; - } - - if (src_h.used_colors > 0) { - ptr = (void *)dest_h; - ptr += (sizeof(*dest_h) + (src_h.height * src_line_sz)); - - for (i = 0; i < src_h.used_colors; i++) { - le_write32(ptr, color_table[i]); - ptr += 4; - } - } - - if (color_table) xfree(color_table); - gbfclose(f); + + /* sort out unsupported files */ + if (!((src_h.width <= 24) && (src_h.height <= 24) && + (src_h.width > 0) && (src_h.height > 0))) { + fatal(MYNAME ": Unsupported format (%dx%d)!\n", src_h.width, src_h.height); + } + if (!((src_h.bpp == 8) || (src_h.bpp == 24) || (src_h.bpp == 32))) { + fatal(MYNAME ": Unsupported color depth (%d)!\n", src_h.bpp); + } + if (!(src_h.compression_type == 0)) { + fatal(MYNAME ": Sorry, we don't support compressed bitmaps.\n"); + } + + if (src_h.used_colors > 0) { + color_table = (int*) xmalloc(4 * src_h.used_colors); + gbfread(color_table, 1, 4 * src_h.used_colors, f); + for (i = 0; i < src_h.used_colors; i++) { + int color = color_table[i]; + /* swap blue and red value */ + color = (color >> 16) | (color << 16) | (color & 0x00ff00); + color_table[i] = color & 0xffffff; + } + } + + /* calculate line-size for source and destination */ + src_line_sz = (src_h.width * src_h.bpp) / 8; + src_line_sz = ((int)((src_line_sz + 3) / 4)) * 4; + + if (src_h.bpp == 24) { + dest_bpp = 32; + } else { + dest_bpp = src_h.bpp; + } + + dest_line_sz = (src_h.width * dest_bpp) / 8; + dest_line_sz = ((int)((dest_line_sz + 3) / 4)) * 4; + + sz = sizeof(*dest_h) + (src_h.height * dest_line_sz); + if (src_h.used_colors) { + sz += (src_h.used_colors * 4); + } + + ptr = (char*) xmalloc(sz); + dest_h = (gpi_bitmap_header_t*)ptr; + *data = ptr; + *data_sz = sz; + + le_write16(&dest_h->index, 0); + le_write16(&dest_h->height, src_h.height); + le_write16(&dest_h->width, src_h.width); + le_write16(&dest_h->line_sz, dest_line_sz); + le_write16(&dest_h->bpp, dest_bpp); + le_write16(&dest_h->fixed_0, 0); /* seems to be fixed */ + le_write32(&dest_h->image_size, dest_line_sz * src_h.height); + le_write32(&dest_h->fixed_2c, 0x2c); /* seems to be fixed */ + le_write32(&dest_h->flag1, (dest_bpp == 8) ? 0x100 : 0); + le_write32(&dest_h->tr_color, 0xff00ff); /* magenta = transparent color */ + le_write32(&dest_h->flag2, 0x1); /* ? enable transparent mode ? */ + le_write32(&dest_h->size_2c, (dest_line_sz * src_h.height) + 0x2c); + + /* copy and revert order of BMP lines */ + ptr = (char*)dest_h; + ptr += (sizeof(*dest_h) + (dest_line_sz * (src_h.height - 1))); + + if (src_h.bpp == 24) { + /* 24 bpp seems to be not supported, convert to 32 bpp */ + for (i = 0; i < src_h.height; i++) { + int j; + char* p = ptr; + + for (j = 0; j < src_h.width; j++) { + int color; + color = (gbint32)gbfgetint16(f) | (gbfgetc(f) << 16); + le_write32(p, color); + p += 4; + } + for (j = (src_h.width * src_h.bpp) / 8; j < src_line_sz; j++) { + gbfgetc(f); /* drop fill-in bytes */ + } + ptr -= dest_line_sz; + } + } else for (i = 0; i < src_h.height; i++) { + gbfread(ptr, 1, src_line_sz, f); + ptr -= dest_line_sz; + } + + if (src_h.used_colors > 0) { + ptr = (char*)dest_h; + ptr += (sizeof(*dest_h) + (src_h.height * src_line_sz)); + + for (i = 0; i < src_h.used_colors; i++) { + le_write32(ptr, color_table[i]); + ptr += 4; + } + } + + if (color_table) { + xfree(color_table); + } + gbfclose(f); } /******************************************************************************* @@ -1244,184 +1406,207 @@ load_bitmap_from_file(const char *fname, char **data, int *data_sz) *******************************************************************************/ static void -garmin_gpi_rd_init(const char *fname) +garmin_gpi_rd_init(const char* fname) { - char cp[8]; - - fin = gbfopen_le(fname, "rb", MYNAME); - rdata = xcalloc(1, sizeof(*rdata)); - - read_header(); - - if ((codepage >= 1250) && (codepage <= 1257)) { - snprintf(cp, sizeof(cp), "CP%d", codepage); - cet_convert_init(cp, 1); - } - else warning(MYNAME ": Unsupported code page (%d).\n", codepage); - - units = tolower(opt_units[0]); - if ((units != 'm') && (units != 's')) - fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); + char cp[8]; + + fin = gbfopen_le(fname, "rb", MYNAME); + rdata = (reader_data_t*) xcalloc(1, sizeof(*rdata)); + + read_header(); + + if ((codepage >= 1250) && (codepage <= 1257)) { + snprintf(cp, sizeof(cp), "CP%d", codepage); + cet_convert_init(cp, 1); + } else { + warning(MYNAME ": Unsupported code page (%d).\n", codepage); + } + + units = tolower(opt_units[0]); + if ((units != 'm') && (units != 's')) { + fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); + } } static void -garmin_gpi_wr_init(const char *fname) +garmin_gpi_wr_init(const char* fname) { - char cp[8]; - cet_cs_vec_t *vec; - int i; - - if (gpi_timestamp != 0) { /* not the first gpi output session */ - time_t t = time(NULL); - if (t <= gpi_timestamp) - gpi_timestamp++; /* don't create files with same timestamp */ - else - gpi_timestamp = t; - } - else - gpi_timestamp = gpsbabel_time; /* always ZERO during 'testo' */ - - fout = gbfopen_le(fname, "wb", MYNAME); - - short_h = mkshort_new_handle(); - - setshort_length(short_h, 1024); - setshort_badchars(short_h, "\r\n"); - setshort_mustupper(short_h, 0); - setshort_mustuniq(short_h, 1); - setshort_whitespace_ok(short_h, 1); - setshort_repeating_whitespace_ok(short_h, 0); - setshort_defname(short_h, "POI"); - - codepage = 0; - - for (i = 1250; i <= 1257; i++) { - snprintf(cp, sizeof(cp), "CP%d", i); - vec = cet_find_cs_by_name(cp); - if (vec == global_opts.charset) { - codepage = i; - break; - } - } - - if (! codepage) { - warning(MYNAME ": Unsupported character set (%s)!\n", global_opts.charset_name); - fatal(MYNAME ": Valid values are CP1250 to CP1257.\n"); - } - - units = tolower(opt_units[0]); - if ((units != 'm') && (units != 's')) - fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); - - alerts = (opt_alerts) ? 1 : 0; - - if (opt_speed) { - double scale; - alerts = 1; /* Force alerts to be enabled */ - if (units == 's') scale = MPH_TO_MPS(1); /* We need speed in meters per second */ - else scale = KPH_TO_MPS(1); - parse_speed(opt_speed, &defspeed, scale, MYNAME); - } - - if (opt_proximity) { - double scale; - alerts = 1; /* Force alerts to be enabled */ - if (units == 's') scale = MILES_TO_METERS(1); /* We need proximity in meters */ - else scale = 1000.0; /* one kilometer in meters */ - parse_distance(opt_proximity, &defproximity, scale, MYNAME); - } - wdata = wdata_alloc(); + char cp[8]; + cet_cs_vec_t* vec; + int i; + + if (gpi_timestamp != 0) { /* not the first gpi output session */ + time_t t = time(NULL); + if (t <= gpi_timestamp) { + gpi_timestamp++; /* don't create files with same timestamp */ + } else { + gpi_timestamp = t; + } + } else { + gpi_timestamp = gpsbabel_time; /* always ZERO during 'testo' */ + } + + fout = gbfopen_le(fname, "wb", MYNAME); + + short_h = mkshort_new_handle(); + + setshort_length(short_h, 1024); + setshort_badchars(short_h, "\r\n"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 0); + setshort_defname(short_h, "POI"); + + codepage = 0; + + for (i = 1250; i <= 1257; i++) { + snprintf(cp, sizeof(cp), "CP%d", i); + vec = cet_find_cs_by_name(cp); + if (vec == global_opts.charset) { + codepage = i; + break; + } + } + + if (! codepage) { + warning(MYNAME ": Unsupported character set (%s)!\n", global_opts.charset_name); + fatal(MYNAME ": Valid values are CP1250 to CP1257.\n"); + } + + units = tolower(opt_units[0]); + if ((units != 'm') && (units != 's')) { + fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); + } + + alerts = (opt_alerts) ? 1 : 0; + + if (opt_speed) { + double scale; + alerts = 1; /* Force alerts to be enabled */ + if (units == 's') { + scale = MPH_TO_MPS(1); /* We need speed in meters per second */ + } else { + scale = KPH_TO_MPS(1); + } + parse_speed(opt_speed, &defspeed, scale, MYNAME); + } + + if (opt_proximity) { + double scale; + alerts = 1; /* Force alerts to be enabled */ + if (units == 's') { + scale = MILES_TO_METERS(1); /* We need proximity in meters */ + } else { + scale = 1000.0; /* one kilometer in meters */ + } + parse_distance(opt_proximity, &defproximity, scale, MYNAME); + } + wdata = wdata_alloc(); } -static void +static void garmin_gpi_rd_deinit(void) { - if (rdata->category) xfree(rdata->category); - if (rdata->group) xfree(rdata->group); - xfree(rdata); - gbfclose(fin); + if (rdata->category) { + xfree(rdata->category); + } + if (rdata->group) { + xfree(rdata->group); + } + xfree(rdata); + gbfclose(fin); } -static void +static void garmin_gpi_wr_deinit(void) { - wdata_free(wdata); - mkshort_del_handle(&short_h); - gbfclose(fout); - - if ((opt_sleep) && (gpi_timestamp != 0)) { /* don't sleep during 'testo' */ - int sleep = atoi(opt_sleep); - if (sleep < 1) sleep = 1; - gpi_timestamp += sleep; - while (gpi_timestamp > time(NULL)) { - gb_sleep(100); - } - } + wdata_free(wdata); + mkshort_del_handle(&short_h); + gbfclose(fout); + + if ((opt_sleep) && (gpi_timestamp != 0)) { /* don't sleep during 'testo' */ + int sleep = atoi(opt_sleep); + if (sleep < 1) { + sleep = 1; + } + gpi_timestamp += sleep; + while (gpi_timestamp > time(NULL)) { + gb_sleep(100); + } + } } static void garmin_gpi_read(void) { - while (1) { - int tag = gbfgetint32(fin); - if (tag == 0xffff) return; - if (! read_tag("garmin_gpi_read", tag, NULL)) return; - }; + while (1) { + int tag = gbfgetint32(fin); + if (tag == 0xffff) { + return; + } + if (! read_tag("garmin_gpi_read", tag, NULL)) { + return; + } + }; } static void garmin_gpi_write(void) { - char *image; - int image_sz; - - if (strlen(opt_cat) == 0) fatal(MYNAME ": Can't write empty category!\n"); - - if (opt_hide_bitmap) { - image = NULL; - image_sz = 0; - } - else if (opt_bitmap && *opt_bitmap) - load_bitmap_from_file(opt_bitmap, &image, &image_sz); - else { - image = gpi_bitmap; /* embedded GPSBabel icon in gpi format */ - image_sz = GPI_BITMAP_SIZE; - } - waypt_disp_all(enum_waypt_cb); - - wdata_check(wdata); - write_header(); - write_category(opt_cat, image, image_sz); - - gbfputint32(0xffff, fout); /* final tag */ - gbfputint32(0, fout); /* ? dummy size ? */ - - if (image != gpi_bitmap) xfree(image); + char* image; + int image_sz; + + if (strlen(opt_cat) == 0) { + fatal(MYNAME ": Can't write empty category!\n"); + } + + if (opt_hide_bitmap) { + image = NULL; + image_sz = 0; + } else if (opt_bitmap && *opt_bitmap) { + load_bitmap_from_file(opt_bitmap, &image, &image_sz); + } else { + image = gpi_bitmap; /* embedded GPSBabel icon in gpi format */ + image_sz = GPI_BITMAP_SIZE; + } + waypt_disp_all(enum_waypt_cb); + + wdata_check(wdata); + write_header(); + write_category(opt_cat, image, image_sz); + + gbfputint32(0xffff, fout); /* final tag */ + gbfputint32(0, fout); /* ? dummy size ? */ + + if (image != gpi_bitmap) { + xfree(image); + } } /**************************************************************************/ ff_vecs_t garmin_gpi_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - garmin_gpi_rd_init, - garmin_gpi_wr_init, - garmin_gpi_rd_deinit, - garmin_gpi_wr_deinit, - garmin_gpi_read, - garmin_gpi_write, - NULL, - garmin_gpi_args, - CET_CHARSET_MS_ANSI, 0 /* WIN-CP1252 */ + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + garmin_gpi_rd_init, + garmin_gpi_wr_init, + garmin_gpi_rd_deinit, + garmin_gpi_wr_deinit, + garmin_gpi_read, + garmin_gpi_write, + NULL, + garmin_gpi_args, + CET_CHARSET_MS_ANSI, 0 /* WIN-CP1252 */ }; /**************************************************************************/ diff --git a/gpsbabel/garmin_gpi.h b/gpsbabel/garmin_gpi.h index 8c2bab369..9e816ba11 100644 --- a/gpsbabel/garmin_gpi.h +++ b/gpsbabel/garmin_gpi.h @@ -2,109 +2,109 @@ #define GARMIN_GPI_H static char gpi_bitmap[] = { - 0x00,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x08,0x00,0x00,0x00,0x40,0x02,0x00,0x00, - 0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x00,0xff,0x00,0x01,0x00,0x00,0x00, - 0x6c,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7e,0x7e,0x7e, - 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, - 0x7e,0x7e,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, - 0x7f,0x7f,0x59,0x67,0x65,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, - 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x74,0x3d,0x42,0x56,0x7e,0x7e,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, - 0x7f,0x72,0x38,0x49,0x47,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, - 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, - 0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, - 0x7f,0x7f,0x7f,0x7f,0x7f,0x7c,0x6c,0x50,0x44,0x5e,0x4f,0x76,0x7e,0x7f,0x7f,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x77,0x7e,0x7f,0x7f,0x7e,0x62,0x0d,0x00,0x05, - 0x10,0x08,0x09,0x59,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x29,0x1c, - 0x4c,0x7f,0x7f,0x60,0x02,0x0c,0x2a,0x37,0x51,0x63,0x57,0x15,0x58,0x7e,0x7e,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x68,0x5a,0x41,0x5f,0x5f,0x07,0x0e,0x3d,0x41,0x41, - 0x4d,0x55,0x6b,0x61,0x26,0x57,0x57,0x2b,0x2f,0x30,0x00,0x7e,0x00,0x7e,0x77,0x7d, - 0x4e,0x3d,0x3d,0x16,0x35,0x41,0x7d,0x49,0x18,0x48,0x52,0x54,0x5b,0x31,0x31,0x63, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x40,0x7d,0x75,0x47,0x47,0x41,0x35,0x40,0x72,0x1e, - 0x7c,0x5d,0x1d,0x20,0x49,0x3d,0x3d,0x5b,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x60,0x5c, - 0x7a,0x1a,0x1a,0x3b,0x38,0x5d,0x0e,0x59,0x7d,0x3c,0x72,0x37,0x78,0x60,0x60,0x28, - 0x4f,0x71,0x00,0x7e,0x00,0x7e,0x7e,0x43,0x33,0x69,0x69,0x17,0x22,0x7d,0x2c,0x27, - 0x2a,0x2b,0x7d,0x32,0x61,0x4f,0x4f,0x36,0x3f,0x4c,0x00,0x7e,0x00,0x7e,0x7f,0x7e, - 0x3a,0x2b,0x2b,0x45,0x1a,0x40,0x47,0x7d,0x37,0x41,0x12,0x25,0x5e,0x46,0x46,0x4d, - 0x62,0x53,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x73,0x71,0x71,0x6a,0x13,0x39,0x1b,0x45, - 0x62,0x50,0x3a,0x7e,0x7e,0x7b,0x7b,0x5c,0x5b,0x49,0x00,0x7e,0x00,0x7e,0x7f,0x7e, - 0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e,0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e, - 0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e, - 0x7c,0x0a,0x0a,0x0f,0x65,0x7d,0x74,0x71,0x7c,0x7e,0x7e,0x7e,0x58,0x03,0x03,0x2b, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x6d,0x6d,0x6f,0x2d,0x1d,0x63,0x7a, - 0x7e,0x75,0x5d,0x19,0x32,0x70,0x70,0x6f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, - 0x7f,0x7f,0x7f,0x7e,0x7d,0x53,0x35,0x0b,0x1f,0x0e,0x34,0x5a,0x7f,0x7f,0x7f,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x7f,0x7e,0x7e,0x7e, - 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, - 0x7e,0x7e,0x7e,0x7e,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x16,0x16,0x16,0x00, - 0x1f,0x1f,0x1f,0x00,0x28,0x28,0x28,0x00,0x2d,0x2d,0x2d,0x00,0x35,0x35,0x35,0x00, - 0x3d,0x3d,0x3d,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00, - 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x4b,0x4b,0x4b,0x00,0x4e,0x4e,0x4e,0x00, - 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x59,0x59,0x59,0x00, - 0x5a,0x5a,0x5a,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x62,0x62,0x62,0x00, - 0x63,0x63,0x63,0x00,0x6a,0x6a,0x6a,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, - 0x76,0x76,0x76,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, - 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x80,0x00, - 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00, - 0x85,0x85,0x85,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, - 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x90,0x00, - 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, - 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9b,0x9b,0x9b,0x00, - 0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, - 0xa2,0xa2,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, - 0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, - 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00, - 0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, - 0xb7,0xb7,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00, - 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, - 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00, - 0xc9,0xc9,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xce,0xce,0x00, - 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00, - 0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd9,0xd9,0xd9,0x00, - 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, - 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00, - 0xe4,0xe4,0xe4,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, - 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00, - 0xee,0xee,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00, - 0xf5,0xf5,0xf5,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00, - 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xff,0xff,0xff,0x00, - 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00 + 0x00,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x08,0x00,0x00,0x00,0x40,0x02,0x00,0x00, + 0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x00,0xff,0x00,0x01,0x00,0x00,0x00, + 0x6c,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x59,0x67,0x65,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x74,0x3d,0x42,0x56,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x72,0x38,0x49,0x47,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7c,0x6c,0x50,0x44,0x5e,0x4f,0x76,0x7e,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x77,0x7e,0x7f,0x7f,0x7e,0x62,0x0d,0x00,0x05, + 0x10,0x08,0x09,0x59,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x29,0x1c, + 0x4c,0x7f,0x7f,0x60,0x02,0x0c,0x2a,0x37,0x51,0x63,0x57,0x15,0x58,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x68,0x5a,0x41,0x5f,0x5f,0x07,0x0e,0x3d,0x41,0x41, + 0x4d,0x55,0x6b,0x61,0x26,0x57,0x57,0x2b,0x2f,0x30,0x00,0x7e,0x00,0x7e,0x77,0x7d, + 0x4e,0x3d,0x3d,0x16,0x35,0x41,0x7d,0x49,0x18,0x48,0x52,0x54,0x5b,0x31,0x31,0x63, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x40,0x7d,0x75,0x47,0x47,0x41,0x35,0x40,0x72,0x1e, + 0x7c,0x5d,0x1d,0x20,0x49,0x3d,0x3d,0x5b,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x60,0x5c, + 0x7a,0x1a,0x1a,0x3b,0x38,0x5d,0x0e,0x59,0x7d,0x3c,0x72,0x37,0x78,0x60,0x60,0x28, + 0x4f,0x71,0x00,0x7e,0x00,0x7e,0x7e,0x43,0x33,0x69,0x69,0x17,0x22,0x7d,0x2c,0x27, + 0x2a,0x2b,0x7d,0x32,0x61,0x4f,0x4f,0x36,0x3f,0x4c,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x3a,0x2b,0x2b,0x45,0x1a,0x40,0x47,0x7d,0x37,0x41,0x12,0x25,0x5e,0x46,0x46,0x4d, + 0x62,0x53,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x73,0x71,0x71,0x6a,0x13,0x39,0x1b,0x45, + 0x62,0x50,0x3a,0x7e,0x7e,0x7b,0x7b,0x5c,0x5b,0x49,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e,0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e, + 0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x7c,0x0a,0x0a,0x0f,0x65,0x7d,0x74,0x71,0x7c,0x7e,0x7e,0x7e,0x58,0x03,0x03,0x2b, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x6d,0x6d,0x6f,0x2d,0x1d,0x63,0x7a, + 0x7e,0x75,0x5d,0x19,0x32,0x70,0x70,0x6f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7e,0x7d,0x53,0x35,0x0b,0x1f,0x0e,0x34,0x5a,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x7f,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x16,0x16,0x16,0x00, + 0x1f,0x1f,0x1f,0x00,0x28,0x28,0x28,0x00,0x2d,0x2d,0x2d,0x00,0x35,0x35,0x35,0x00, + 0x3d,0x3d,0x3d,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x4b,0x4b,0x4b,0x00,0x4e,0x4e,0x4e,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x59,0x59,0x59,0x00, + 0x5a,0x5a,0x5a,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x62,0x62,0x62,0x00, + 0x63,0x63,0x63,0x00,0x6a,0x6a,0x6a,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00, + 0x85,0x85,0x85,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9b,0x9b,0x9b,0x00, + 0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, + 0xa2,0xa2,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00, + 0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00, + 0xc9,0xc9,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00, + 0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd9,0xd9,0xd9,0x00, + 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00, + 0xe4,0xe4,0xe4,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00, + 0xee,0xee,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00, + 0xf5,0xf5,0xf5,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xff,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00 }; #define GPI_BITMAP_SIZE sizeof(gpi_bitmap) diff --git a/gpsbabel/garmin_tables.c b/gpsbabel/garmin_tables.c index ed4a38b1b..161f15c56 100644 --- a/gpsbabel/garmin_tables.c +++ b/gpsbabel/garmin_tables.c @@ -30,648 +30,644 @@ /* MapSource 4.13 */ icon_mapping_t garmin_icon_table[] = { -/* mps pcx desc */ - { 107, 16384, "Airport" }, - { 73, 8204, "Amusement Park" }, - { 55, 169, "Ball Park" }, - { 6, 6, "Bank" }, - { 13, 13, "Bar" }, - { 104, 8244, "Beach" }, - { 1, 1, "Bell" }, - { 37, 150, "Boat Ramp" }, - { 74, 8205, "Bowling" }, - { 93, 8233, "Bridge" }, - { 94, 8234, "Building" }, - { 38, 151, "Campground" }, - { 56, 170, "Car" }, - { 75, 8206, "Car Rental" }, - { 76, 8207, "Car Repair" }, - { 95, 8235, "Cemetery" }, - { 96, 8236, "Church" }, - { 65, 179, "Circle with X" }, - { 72, 8203, "City (Capitol)" }, - { 71, 8200, "City (Large)" }, - { 70, 8199, "City (Medium)" }, - { 69, 8198, "City (Small)" }, - { 69, 8198, "Small City" }, - { 97, 8237, "Civil" }, - { 119, 8262, "Contact, Afro" }, - { 120, 8272, "Contact, Alien" }, - { 121, 8258, "Contact, Ball Cap" }, - { 122, 8259, "Contact, Big Ears" }, - { 123, 8271, "Contact, Biker" }, - { 124, 8273, "Contact, Bug" }, - { 125, 8274, "Contact, Cat" }, - { 126, 8275, "Contact, Dog" }, - { 127, 8263, "Contact, Dreadlocks" }, - { 128, 8264, "Contact, Female1" }, - { 129, 8265, "Contact, Female2" }, - { 130, 8266, "Contact, Female3" }, - { 131, 8261, "Contact, Goatee" }, - { 132, 8268, "Contact, Kung-Fu" }, - { 133, 8276, "Contact, Pig" }, - { 134, 8270, "Contact, Pirate" }, - { 135, 8267, "Contact, Ranger" }, - { 136, 8257, "Contact, Smiley" }, - { 137, 8260, "Contact, Spike" }, - { 138, 8269, "Contact, Sumo" }, - { 52, 165, "Controlled Area" }, - { 89, 8220, "Convenience Store" }, - { 98, 8238, "Crossing" }, - { 51, 164, "Dam" }, - { 53, 166, "Danger Area" }, - { 87, 8218, "Department Store" }, - { 4, 4, "Diver Down Flag 1" }, - { 5, 5, "Diver Down Flag 2" }, - { 41, 154, "Drinking Water" }, - { 63, 177, "Exit" }, - { 77, 8208, "Fast Food" }, - { 7, 7, "Fishing Area" }, - { 78, 8209, "Fitness Center" }, - { 64, 178, "Flag" }, - { 105, 8245, "Forest" }, - { 8, 8, "Gas Station" }, - { 117, 8255, "Geocache" }, - { 118, 8256, "Geocache Found" }, - { 99, 8239, "Ghost Town" }, - { 113, 16393, "Glider Area" }, - { 68, 8197, "Golf Course" }, - { 2, 2, "Diamond, Green" }, - { 15, 15, "Square, Green" }, - { 108, 16388, "Heliport" }, - { 9, 9, "Horn" }, - { 57, 171, "Hunting Area" }, - { 44, 157, "Information" }, - { 100, 8240, "Levee" }, - { 12, 12, "Light" }, - { 90, 8221, "Live Theater" }, - { 59, 173, "Lodging" }, - { 59, 173, "Hotel" }, - { 20, 21, "Man Overboard" }, - { 0, 0, "Anchor" }, - { 43, 156, "Medical Facility" }, - { 66, 8195, "Mile Marker" }, - { 101, 8241, "Military" }, - { 60, 174, "Mine" }, - { 79, 8210, "Movie Theater" }, - { 80, 8211, "Museum" }, - { 21, 22, "Navaid, Amber" }, - { 22, 23, "Navaid, Black" }, - { 23, 24, "Navaid, Blue" }, - { 24, 25, "Navaid, Green" }, - { 25, 26, "Navaid, Green/Red" }, - { 26, 27, "Navaid, Green/White" }, - { 27, 28, "Navaid, Orange" }, - { 28, 29, "Navaid, Red" }, - { 29, 30, "Navaid, Red/Green" }, - { 30, 31, "Navaid, Red/White" }, - { 31, 32, "Navaid, Violet" }, - { 32, 33, "Navaid, White" }, - { 33, 34, "Navaid, White/Green" }, - { 34, 35, "Navaid, White/Red" }, - { 102, 8242, "Oil Field" }, - { 115, 16395, "Parachute Area" }, - { 46, 159, "Park" }, - { 45, 158, "Parking Area" }, - { 81, 8212, "Pharmacy" }, - { 47, 160, "Picnic Area" }, - { 82, 8213, "Pizza" }, - { 83, 8214, "Post Office" }, - { 109, 16389, "Private Field" }, - { 36, 37, "Radio Beacon" }, - { 3, 3, "Diamond, Red" }, - { 16, 16, "Square, Red" }, - { 10, 10, "Residence" }, - { 10, 10, "House" }, - { 11, 11, "Restaurant" }, - { 54, 167, "Restricted Area" }, - { 39, 152, "Restroom" }, - { 84, 8215, "RV Park" }, - { 91, 8226, "Scales" }, - { 48, 161, "Scenic Area" }, - { 85, 8216, "School" }, - { 116, 16402, "Seaplane Base" }, - { 19, 19, "Shipwreck" }, - { 58, 172, "Shopping Center" }, - { 112, 16392, "Short Tower" }, - { 40, 153, "Shower" }, - { 49, 162, "Skiing Area" }, - { 14, 14, "Skull and Crossbones" }, - { 110, 16390, "Soft Field" }, - { 86, 8217, "Stadium" }, - { 106, 8246, "Summit" }, - { 50, 163, "Swimming Area" }, - { 111, 16391, "Tall Tower" }, - { 42, 155, "Telephone" }, - { 92, 8227, "Toll Booth" }, - { 67, 8196, "TracBack Point" }, - { 61, 175, "Trail Head" }, - { 62, 176, "Truck Stop" }, - { 103, 8243, "Tunnel" }, - { 114, 16394, "Ultralight Area" }, - { 139, 8282, "Water Hydrant" }, /* new in MapSource V5 */ - { 18, 18, "Waypoint" }, - { 17, 17, "Buoy, White" }, - { 35, 36, "Dot, White" }, - { 88, 8219, "Zoo" }, - - /* Custom icons. The spec reserves 7680-8191 for the custom - * icons on the C units, Quest, 27xx, 276, 296, and other units. - * Note that firmware problems on the earlier unit result in these - * being mangled, so be sure you're on a version from at least - * late 2005. - * { -2, 7680, "Custom 0" }, - * .... - * { -2, 8192, "Custom 511" }, - */ - /* MapSource V6.x */ - - { 140, 8286, "Flag, Red" }, - { 141, 8284, "Flag, Blue" }, - { 142, 8285, "Flag, Green" }, - { 143, 8289, "Pin, Red" }, - { 144, 8287, "Pin, Blue" }, - { 145, 8288, "Pin, Green" }, - { 146, 8292, "Block, Red" }, - { 147, 8290, "Block, Blue" }, - { 148, 8291, "Block, Green" }, - { 149, 8293, "Bike Trail" }, - { 150, 181, "Fishing Hot Spot Facility" }, - { 151, 8249, "Police Station"}, - { 152, 8251, "Ski Resort" }, - { 153, 8252, "Ice Skating" }, - { 154, 8253, "Wrecker" }, - { 155, 184, "Anchor Prohibited" }, - { 156, 185, "Beacon" }, - { 157, 186, "Coast Guard" }, - { 158, 187, "Reef" }, - { 159, 188, "Weed Bed" }, - { 160, 189, "Dropoff" }, - { 161, 190, "Dock" }, - { 162, 191, "Marina" }, - { 163, 192, "Bait and Tackle" }, - { 164, 193, "Stump" }, - - /* New in Garmin protocol spec from June 2006. Extracted from - * spec and fed through some horrible awk to add ones we didn't - * have before but normalized for consistency. */ - { -1, 8359, "Asian Food" }, - { 167, 8296, "Circle, Blue" }, - { 168, 8299, "Diamond, Blue" }, - { 178, 8317, "Letter A, Blue" }, - { 181, 8318, "Letter B, Blue" }, - { 184, 8319, "Letter C, Blue" }, - { 187, 8320, "Letter D, Blue" }, - { 190, 8341, "Number 0, Blue" }, - { 193, 8342, "Number 1, Blue" }, - { 196, 8343, "Number 2, Blue" }, - { 199, 8344, "Number 3, Blue" }, - { 202, 8345, "Number 4, Blue" }, - { 205, 8346, "Number 5, Blue" }, - { 208, 8347, "Number 6, Blue" }, - { 211, 8348, "Number 7, Blue" }, - { 214, 8349, "Number 8, Blue" }, - { 217, 8350, "Number 9, Blue" }, - { 171, 8302, "Oval, Blue" }, - { 174, 8305, "Rectangle, Blue" }, - { 175, 8308, "Square, Blue" }, - { 218, 8351, "Triangle, Blue" }, - { -1, 8254, "Border Crossing (Port Of Entry)" }, - { -1, 182, "Bottom Conditions" }, - { -1, 8360, "Deli" }, - { -1, 8228, "Elevation point" }, - { -1, 8229, "Exit without services" }, - { -1, 16398, "First approach fix" }, - { -1, 8250, "Gambling/casino" }, - { -1, 8232, "Geographic place name, land" }, - { -1, 8230, "Geographic place name, Man-made" }, - { -1, 8231, "Geographic place name, water" }, - { 166, 8295, "Circle, Green" }, - { 177, 8313, "Letter A, Green" }, - { 180, 8315, "Letter B, Green" }, - { 183, 8314, "Letter C, Green" }, - { 186, 8316, "Letter D, Green" }, - { 189, 8331, "Number 0, Green" }, - { 192, 8332, "Number 1, Green" }, - { 195, 8333, "Number 2, Green" }, - { 198, 8334, "Number 3, Green" }, - { 201, 8335, "Number 4, Green" }, - { 204, 8336, "Number 5, Green" }, - { 207, 8337, "Number 6, Green" }, - { 210, 8338, "Number 7, Green" }, - { 213, 8339, "Number 8, Green" }, - { 216, 8340, "Number 9, Green" }, - { 170, 8301, "Oval, Green" }, - { 173, 8304, "Rectangle, Green" }, - { 219, 8352, "Triangle, Green" }, - { -1, 16385, "Intersection" }, - { -1, 8201, "Intl freeway hwy" }, - { -1, 8202, "Intl national hwy" }, - { -1, 8361, "Italian food" }, - { -1, 8248, "Large exit without services" }, - { -1, 8247, "Large Ramp intersection" }, - { -1, 16399, "Localizer Outer Marker" }, - { -1, 16400, "Missed approach point" }, - { -1, 16386, "Non-directional beacon" }, - { -1, 168, "Null" }, - { -1, 180, "Open 24 Hours" }, - { -1, 8222, "Ramp intersection" }, - { 165, 8294, "Circle, Red" }, - { 176, 8309, "Letter A, Red" }, - { 179, 8310, "Letter B, Red" }, - { 182, 8311, "Letter C, Red" }, - { 185, 8312, "Letter D, Red" }, - { 188, 8321, "Number 0, Red" }, - { 191, 8322, "Number 1, Red" }, - { 194, 8323, "Number 2, Red" }, - { 197, 8324, "Number 3, Red" }, - { 200, 8325, "Number 4, Red" }, - { 203, 8326, "Number 5, Red" }, - { 206, 8327, "Number 6, Red" }, - { 209, 8328, "Number 7, Red" }, - { 212, 8329, "Number 8, Red" }, - { 215, 8330, "Number 9, Red" }, - { 169, 8300, "Oval, Red" }, - { 172, 8303, "Rectangle, Red" }, - { 220, 8353, "Triangle, Red" }, - { -1, 8362, "Seafood" }, - { -1, 8194, "State Hwy" }, - { -1, 8363, "Steak" }, - { -1, 8223, "Street Intersection" }, - { -1, 16401, "TACAN" }, - { -1, 183, "Tide/Current PRediction Station" }, - { -1, 191, "U Marina" }, - { -1, 8193, "US hwy" }, - { -1, 193, "U stump" }, - { -1, 16387, "VHF Omni-range" }, - { -1, 16397, "VOR-DME" }, - { -1, 16396, "VOR/TACAN" }, - - /* This block new on 1/15 from the Mapsource 6.12 beta */ - { 221, -1, "Contact, Blonde" }, - { 222, -1, "Contact, Clown" }, - { 223, -1, "Contact, Glasses" }, - { 224, -1, "Contact, Panda" }, - { 225, -1, "Multi-Cache" }, - { 226, -1, "Letterbox Cache" }, - { 227, -1, "Puzzle Cache" }, - { 228, -1, "Library" }, - { 229, -1, "Ground Transportation" }, - { 230, -1, "City Hall" }, - { 231, -1, "Winery" }, - { 232, -1, "ATV" }, - { 233, -1, "Big Game" }, - { 234, -1, "Blind" }, - { 235, -1, "Blood Trail" }, - { 236, -1, "Cover" }, - { 237, -1, "Covey" }, - { 238, -1, "Food Source" }, - { 239, -1, "Furbearer" }, - { 240, -1, "Lodge" }, - { 241, -1, "Small Game" }, - { 242, -1, "Animal Tracks" }, - { 243, -1, "Treed Quarry" }, - { 244, -1, "Tree Stand" }, - { 245, -1, "Truck" }, - { 246, -1, "Upland Game" }, - { 247, -1, "Waterfowl" }, - { 248, -1, "Water Source" }, - - - { -1, -1, NULL }, + /* mps pcx desc */ + { 107, 16384, "Airport" }, + { 73, 8204, "Amusement Park" }, + { 55, 169, "Ball Park" }, + { 6, 6, "Bank" }, + { 13, 13, "Bar" }, + { 104, 8244, "Beach" }, + { 1, 1, "Bell" }, + { 37, 150, "Boat Ramp" }, + { 74, 8205, "Bowling" }, + { 93, 8233, "Bridge" }, + { 94, 8234, "Building" }, + { 38, 151, "Campground" }, + { 56, 170, "Car" }, + { 75, 8206, "Car Rental" }, + { 76, 8207, "Car Repair" }, + { 95, 8235, "Cemetery" }, + { 96, 8236, "Church" }, + { 65, 179, "Circle with X" }, + { 72, 8203, "City (Capitol)" }, + { 71, 8200, "City (Large)" }, + { 70, 8199, "City (Medium)" }, + { 69, 8198, "City (Small)" }, + { 69, 8198, "Small City" }, + { 97, 8237, "Civil" }, + { 119, 8262, "Contact, Afro" }, + { 120, 8272, "Contact, Alien" }, + { 121, 8258, "Contact, Ball Cap" }, + { 122, 8259, "Contact, Big Ears" }, + { 123, 8271, "Contact, Biker" }, + { 124, 8273, "Contact, Bug" }, + { 125, 8274, "Contact, Cat" }, + { 126, 8275, "Contact, Dog" }, + { 127, 8263, "Contact, Dreadlocks" }, + { 128, 8264, "Contact, Female1" }, + { 129, 8265, "Contact, Female2" }, + { 130, 8266, "Contact, Female3" }, + { 131, 8261, "Contact, Goatee" }, + { 132, 8268, "Contact, Kung-Fu" }, + { 133, 8276, "Contact, Pig" }, + { 134, 8270, "Contact, Pirate" }, + { 135, 8267, "Contact, Ranger" }, + { 136, 8257, "Contact, Smiley" }, + { 137, 8260, "Contact, Spike" }, + { 138, 8269, "Contact, Sumo" }, + { 52, 165, "Controlled Area" }, + { 89, 8220, "Convenience Store" }, + { 98, 8238, "Crossing" }, + { 51, 164, "Dam" }, + { 53, 166, "Danger Area" }, + { 87, 8218, "Department Store" }, + { 4, 4, "Diver Down Flag 1" }, + { 5, 5, "Diver Down Flag 2" }, + { 41, 154, "Drinking Water" }, + { 63, 177, "Exit" }, + { 77, 8208, "Fast Food" }, + { 7, 7, "Fishing Area" }, + { 78, 8209, "Fitness Center" }, + { 64, 178, "Flag" }, + { 105, 8245, "Forest" }, + { 8, 8, "Gas Station" }, + { 117, 8255, "Geocache" }, + { 118, 8256, "Geocache Found" }, + { 99, 8239, "Ghost Town" }, + { 113, 16393, "Glider Area" }, + { 68, 8197, "Golf Course" }, + { 2, 2, "Diamond, Green" }, + { 15, 15, "Square, Green" }, + { 108, 16388, "Heliport" }, + { 9, 9, "Horn" }, + { 57, 171, "Hunting Area" }, + { 44, 157, "Information" }, + { 100, 8240, "Levee" }, + { 12, 12, "Light" }, + { 90, 8221, "Live Theater" }, + { 59, 173, "Lodging" }, + { 59, 173, "Hotel" }, + { 20, 21, "Man Overboard" }, + { 0, 0, "Anchor" }, + { 43, 156, "Medical Facility" }, + { 66, 8195, "Mile Marker" }, + { 101, 8241, "Military" }, + { 60, 174, "Mine" }, + { 79, 8210, "Movie Theater" }, + { 80, 8211, "Museum" }, + { 21, 22, "Navaid, Amber" }, + { 22, 23, "Navaid, Black" }, + { 23, 24, "Navaid, Blue" }, + { 24, 25, "Navaid, Green" }, + { 25, 26, "Navaid, Green/Red" }, + { 26, 27, "Navaid, Green/White" }, + { 27, 28, "Navaid, Orange" }, + { 28, 29, "Navaid, Red" }, + { 29, 30, "Navaid, Red/Green" }, + { 30, 31, "Navaid, Red/White" }, + { 31, 32, "Navaid, Violet" }, + { 32, 33, "Navaid, White" }, + { 33, 34, "Navaid, White/Green" }, + { 34, 35, "Navaid, White/Red" }, + { 102, 8242, "Oil Field" }, + { 115, 16395, "Parachute Area" }, + { 46, 159, "Park" }, + { 45, 158, "Parking Area" }, + { 81, 8212, "Pharmacy" }, + { 47, 160, "Picnic Area" }, + { 82, 8213, "Pizza" }, + { 83, 8214, "Post Office" }, + { 109, 16389, "Private Field" }, + { 36, 37, "Radio Beacon" }, + { 3, 3, "Diamond, Red" }, + { 16, 16, "Square, Red" }, + { 10, 10, "Residence" }, + { 10, 10, "House" }, + { 11, 11, "Restaurant" }, + { 54, 167, "Restricted Area" }, + { 39, 152, "Restroom" }, + { 84, 8215, "RV Park" }, + { 91, 8226, "Scales" }, + { 48, 161, "Scenic Area" }, + { 85, 8216, "School" }, + { 116, 16402, "Seaplane Base" }, + { 19, 19, "Shipwreck" }, + { 58, 172, "Shopping Center" }, + { 112, 16392, "Short Tower" }, + { 40, 153, "Shower" }, + { 49, 162, "Skiing Area" }, + { 14, 14, "Skull and Crossbones" }, + { 110, 16390, "Soft Field" }, + { 86, 8217, "Stadium" }, + { 106, 8246, "Summit" }, + { 50, 163, "Swimming Area" }, + { 111, 16391, "Tall Tower" }, + { 42, 155, "Telephone" }, + { 92, 8227, "Toll Booth" }, + { 67, 8196, "TracBack Point" }, + { 61, 175, "Trail Head" }, + { 62, 176, "Truck Stop" }, + { 103, 8243, "Tunnel" }, + { 114, 16394, "Ultralight Area" }, + { 139, 8282, "Water Hydrant" }, /* new in MapSource V5 */ + { 18, 18, "Waypoint" }, + { 17, 17, "Buoy, White" }, + { 35, 36, "Dot, White" }, + { 88, 8219, "Zoo" }, + + /* Custom icons. The spec reserves 7680-8191 for the custom + * icons on the C units, Quest, 27xx, 276, 296, and other units. + * Note that firmware problems on the earlier unit result in these + * being mangled, so be sure you're on a version from at least + * late 2005. + * { -2, 7680, "Custom 0" }, + * .... + * { -2, 8192, "Custom 511" }, + */ + /* MapSource V6.x */ + + { 140, 8286, "Flag, Red" }, + { 141, 8284, "Flag, Blue" }, + { 142, 8285, "Flag, Green" }, + { 143, 8289, "Pin, Red" }, + { 144, 8287, "Pin, Blue" }, + { 145, 8288, "Pin, Green" }, + { 146, 8292, "Block, Red" }, + { 147, 8290, "Block, Blue" }, + { 148, 8291, "Block, Green" }, + { 149, 8293, "Bike Trail" }, + { 150, 181, "Fishing Hot Spot Facility" }, + { 151, 8249, "Police Station"}, + { 152, 8251, "Ski Resort" }, + { 153, 8252, "Ice Skating" }, + { 154, 8253, "Wrecker" }, + { 155, 184, "Anchor Prohibited" }, + { 156, 185, "Beacon" }, + { 157, 186, "Coast Guard" }, + { 158, 187, "Reef" }, + { 159, 188, "Weed Bed" }, + { 160, 189, "Dropoff" }, + { 161, 190, "Dock" }, + { 162, 191, "Marina" }, + { 163, 192, "Bait and Tackle" }, + { 164, 193, "Stump" }, + + /* New in Garmin protocol spec from June 2006. Extracted from + * spec and fed through some horrible awk to add ones we didn't + * have before but normalized for consistency. */ + { -1, 8359, "Asian Food" }, + { 167, 8296, "Circle, Blue" }, + { 168, 8299, "Diamond, Blue" }, + { 178, 8317, "Letter A, Blue" }, + { 181, 8318, "Letter B, Blue" }, + { 184, 8319, "Letter C, Blue" }, + { 187, 8320, "Letter D, Blue" }, + { 190, 8341, "Number 0, Blue" }, + { 193, 8342, "Number 1, Blue" }, + { 196, 8343, "Number 2, Blue" }, + { 199, 8344, "Number 3, Blue" }, + { 202, 8345, "Number 4, Blue" }, + { 205, 8346, "Number 5, Blue" }, + { 208, 8347, "Number 6, Blue" }, + { 211, 8348, "Number 7, Blue" }, + { 214, 8349, "Number 8, Blue" }, + { 217, 8350, "Number 9, Blue" }, + { 171, 8302, "Oval, Blue" }, + { 174, 8305, "Rectangle, Blue" }, + { 175, 8308, "Square, Blue" }, + { 218, 8351, "Triangle, Blue" }, + { -1, 8254, "Border Crossing (Port Of Entry)" }, + { -1, 182, "Bottom Conditions" }, + { -1, 8360, "Deli" }, + { -1, 8228, "Elevation point" }, + { -1, 8229, "Exit without services" }, + { -1, 16398, "First approach fix" }, + { -1, 8250, "Gambling/casino" }, + { -1, 8232, "Geographic place name, land" }, + { -1, 8230, "Geographic place name, Man-made" }, + { -1, 8231, "Geographic place name, water" }, + { 166, 8295, "Circle, Green" }, + { 177, 8313, "Letter A, Green" }, + { 180, 8315, "Letter B, Green" }, + { 183, 8314, "Letter C, Green" }, + { 186, 8316, "Letter D, Green" }, + { 189, 8331, "Number 0, Green" }, + { 192, 8332, "Number 1, Green" }, + { 195, 8333, "Number 2, Green" }, + { 198, 8334, "Number 3, Green" }, + { 201, 8335, "Number 4, Green" }, + { 204, 8336, "Number 5, Green" }, + { 207, 8337, "Number 6, Green" }, + { 210, 8338, "Number 7, Green" }, + { 213, 8339, "Number 8, Green" }, + { 216, 8340, "Number 9, Green" }, + { 170, 8301, "Oval, Green" }, + { 173, 8304, "Rectangle, Green" }, + { 219, 8352, "Triangle, Green" }, + { -1, 16385, "Intersection" }, + { -1, 8201, "Intl freeway hwy" }, + { -1, 8202, "Intl national hwy" }, + { -1, 8361, "Italian food" }, + { -1, 8248, "Large exit without services" }, + { -1, 8247, "Large Ramp intersection" }, + { -1, 16399, "Localizer Outer Marker" }, + { -1, 16400, "Missed approach point" }, + { -1, 16386, "Non-directional beacon" }, + { -1, 168, "Null" }, + { -1, 180, "Open 24 Hours" }, + { -1, 8222, "Ramp intersection" }, + { 165, 8294, "Circle, Red" }, + { 176, 8309, "Letter A, Red" }, + { 179, 8310, "Letter B, Red" }, + { 182, 8311, "Letter C, Red" }, + { 185, 8312, "Letter D, Red" }, + { 188, 8321, "Number 0, Red" }, + { 191, 8322, "Number 1, Red" }, + { 194, 8323, "Number 2, Red" }, + { 197, 8324, "Number 3, Red" }, + { 200, 8325, "Number 4, Red" }, + { 203, 8326, "Number 5, Red" }, + { 206, 8327, "Number 6, Red" }, + { 209, 8328, "Number 7, Red" }, + { 212, 8329, "Number 8, Red" }, + { 215, 8330, "Number 9, Red" }, + { 169, 8300, "Oval, Red" }, + { 172, 8303, "Rectangle, Red" }, + { 220, 8353, "Triangle, Red" }, + { -1, 8362, "Seafood" }, + { -1, 8194, "State Hwy" }, + { -1, 8363, "Steak" }, + { -1, 8223, "Street Intersection" }, + { -1, 16401, "TACAN" }, + { -1, 183, "Tide/Current PRediction Station" }, + { -1, 191, "U Marina" }, + { -1, 8193, "US hwy" }, + { -1, 193, "U stump" }, + { -1, 16387, "VHF Omni-range" }, + { -1, 16397, "VOR-DME" }, + { -1, 16396, "VOR/TACAN" }, + + /* This block new on 1/15 from the Mapsource 6.12 beta */ + { 221, -1, "Contact, Blonde" }, + { 222, -1, "Contact, Clown" }, + { 223, -1, "Contact, Glasses" }, + { 224, -1, "Contact, Panda" }, + { 225, -1, "Multi-Cache" }, + { 226, -1, "Letterbox Cache" }, + { 227, -1, "Puzzle Cache" }, + { 228, -1, "Library" }, + { 229, -1, "Ground Transportation" }, + { 230, -1, "City Hall" }, + { 231, -1, "Winery" }, + { 232, -1, "ATV" }, + { 233, -1, "Big Game" }, + { 234, -1, "Blind" }, + { 235, -1, "Blood Trail" }, + { 236, -1, "Cover" }, + { 237, -1, "Covey" }, + { 238, -1, "Food Source" }, + { 239, -1, "Furbearer" }, + { 240, -1, "Lodge" }, + { 241, -1, "Small Game" }, + { 242, -1, "Animal Tracks" }, + { 243, -1, "Treed Quarry" }, + { 244, -1, "Tree Stand" }, + { 245, -1, "Truck" }, + { 246, -1, "Upland Game" }, + { 247, -1, "Waterfowl" }, + { 248, -1, "Water Source" }, + + + { -1, -1, NULL }, }; icon_mapping_t garmin_smart_icon_table[] = { - /* Additional (optional, activated with -Si) icons */ - { 92, 8227, "Micro-Cache" }, /* icon for "Toll Booth" */ - { 48, 161, "Virtual cache" }, /* icon for "Scenic Area" */ - { 86, 8217, "Multi-Cache" }, /* icon for "Stadium" */ - { 44, 157, "Unknown Cache" }, /* icon for "Information" */ - { 64, 178, "Locationless (Reverse) Cache" }, /* Icon for "Flag" */ - { 83, 8214, "Post Office" }, /* Icon for "Post Office" */ - { 47, 160, "Event Cache" }, /* Icon for "Event" */ - { 90, 8221, "Webcam Cache" }, /* Icon for "Live Theatre" */ - { -1, -1, NULL } + /* Additional (optional, activated with -Si) icons */ + { 92, 8227, "Micro-Cache" }, /* icon for "Toll Booth" */ + { 48, 161, "Virtual cache" }, /* icon for "Scenic Area" */ + { 86, 8217, "Multi-Cache" }, /* icon for "Stadium" */ + { 44, 157, "Unknown Cache" }, /* icon for "Information" */ + { 64, 178, "Locationless (Reverse) Cache" }, /* Icon for "Flag" */ + { 83, 8214, "Post Office" }, /* Icon for "Post Office" */ + { 47, 160, "Event Cache" }, /* Icon for "Event" */ + { 90, 8221, "Webcam Cache" }, /* Icon for "Live Theatre" */ + { -1, -1, NULL } }; /* ICAO coutry code table */ /* source: http://en.wikipedia.org/wiki/ICAO_airport_code */ -gt_country_code_t gt_country_codes[] = -{ - { "ZM,", "Mongolia" }, - { "ZK,", "North Korea" }, - { "Z*,", "China" }, - { "Y*,", "Australia" }, - { "WS,", "Singapore" }, - { "WM,", "Brunei/Malaysia" }, - { "WB,", "Malaysia" }, - { "WA,WI,WQ,WR,", "Indonesia" }, - { "VV,", "Vietnam" }, - { "VT,", "Thailand" }, - { "VR,", "Maldives" }, - { "VQ,", "Bhutan" }, - { "VN,", "Nepal" }, - { "VM,", "Macau" }, - { "VL,", "Laos" }, - { "VH,", "Hong Kong" }, - { "VG,", "Bangladesh" }, - { "VD,", "Kampuchea" }, - { "VC,", "Sri Lanka" }, - { "VB,VY,", "Myanmar/Burma" }, - { "VA,VE,VI,VO,", "India" }, - { "UR,", "Kazakhstan/Russia" }, - { "UT,", "Kazakhstan/Tadzhikistan/Turkmenistan/Uzbekistan" }, - { "UM,", "Belorussia/Russia" }, - { "UK,", "Ukraine" }, - { "UB,", "Azerbaijan" }, - { "UA,", "Kazakhstan/Kirgizia" }, - { "U*,", "Russia" }, - { "TX,", "Bermuda" }, - { "TV,", "St Vincent and the Grenadines" }, - { "TU,", "British Virgin Islands" }, - { "TT,", "Trinidad and Tobago" }, - { "TR,", "Montserrat Island" }, - { "TQ,", "Anguilla" }, - { "TN,", "Aruba/Neth Antilles" }, - { "TL,", "St Lucia" }, - { "TK,", "St Kitts/Nevis Islands" }, - { "TJ,", "Puerto Rico" }, - { "TG,", "Grenada" }, - { "TF,", "Guadeloupe/Martinique" }, - { "TD,", "Dominica" }, - { "TB,", "Barbados" }, - { "TA,", "Antigua" }, - { "SY,", "Guyana" }, - { "SV,", "Venezuela" }, - { "SU,", "Uruguay" }, - { "SP,", "Peru" }, - { "SO,", "French Guiana" }, - { "SM,", "Suriname" }, - { "SL,", "Bolivia" }, - { "SK,", "Colombia/San Andres" }, - { "SG,", "Paraguay" }, - { "SF,", "Falkland Islands" }, - { "SE,", "Ecuador" }, - { "SC,", "Chile/Easter Island" }, - { "SB,SD,SN,SS,SW,", "Brazil" }, - { "SA,", "Argentina" }, - { "S1,", "Antarctica (Argentina/Chile)" }, - { "RP,", "Philippines" }, - { "RK,", "South Korea" }, - { "RJ,", "Japan" }, - { "RC,", "Taiwan" }, - { "PW,", "Wake Island" }, - { "PT,", "Caroline Islands/Micronesia/Palau" }, - { "PM,", "Midway Islands" }, - { "PK,", "Marshall Islands" }, - { "PJ,", "Johnston Atoll" }, - { "PG,", "Guam/Mariana Islands/Northern Mariana Islands" }, - { "PC,", "Kiribati" }, - { "P", "Oakland Octa" }, - { "OY,", "Yemen Arab Rep" }, - { "OT,", "Qatar" }, - { "OS,", "Syria" }, - { "OR,", "Iraq" }, - { "OP,", "Pakistan" }, - { "OO,", "Oman" }, - { "OM,", "United Arab Emirates" }, - { "OL,", "Lebanon" }, - { "OK,", "Kuwait" }, - { "OJ,", "Jordan" }, - { "OI,", "Iran" }, - { "OE,", "Saudi Arabia" }, - { "OB,", "Bahrain" }, - { "OA,", "Afghanistan" }, - { "NZ,PL,", "New Zealand" }, - { "NW,", "New Caledonia" }, - { "NV,", "Vanuatu" }, - { "NT,", "French Polynesia/Society Islands/Tuamotu Islands" }, - { "NS,", "American Samoa/Western Samoa" }, - { "NL,", "Futuna Island/Wallis Island" }, - { "NI,", "Niue" }, - { "NG,", "Kiribati/Tuvalu" }, - { "NF,", "Fiji Island/Tonga" }, - { "NC,", "Cook Islands" }, - { "MZ,", "Belize" }, - { "MY,", "Bahamas" }, - { "MW,", "Cayman Islands" }, - { "MU,", "Cuba" }, - { "MT,", "Haiti" }, - { "MS,", "El Salvador" }, - { "MR,", "Costa rica" }, - { "MP,", "Panama" }, - { "MN,", "Nicaragua" }, - { "MM,", "Mexico" }, - { "MK,", "Jamaica" }, - { "MI,TI,", "Virgin Islands (U.S.)" }, - { "MH,", "Honduras" }, - { "MG,", "Guatemala" }, - { "MD,", "Dominican Republic" }, - { "MB,", "Turks Island/Caicos Island" }, - { "LZ,", "Slovakia" }, - { "LY,", "Yugoslavia" }, - { "LX,", "Gibraltar" }, - { "LW,", "Macedonia" }, - { "LV,", "Gaza" }, - { "LU,", "Moldova" }, - { "LT,", "Turkey" }, - { "LS,", "Switzerland" }, - { "LR,", "Romania" }, - { "LQ,", "Bosnia-Herzegovina" }, - { "LP,", "Portugal/Azores/Madeira Islands" }, - { "LO,", "Austria" }, - { "LN,", "Monaco" }, - { "LM,", "Malta" }, - { "LL,", "Israel/Jerusalem" }, - { "LK,", "Czech" }, - { "LI,", "Italy" }, - { "LH,", "Hungary" }, - { "LG,", "Slovenia" }, - { "LG,", "Greece" }, - { "LF,", "France" }, - { "LF,", "Miquelon Island/St Pierre Island" }, - { "LE,", "Spain" }, - { "LD,", "Croatia" }, - { "LC,", "Cyprus/Turkey (Northern Cyprus)" }, - { "LB,", "Bulgaria" }, - { "LA,", "Albania" }, - { "K*,X*,PA,PB,PF,PJ,PL,PM,PO,PP,PH,PW,", "United States of America" }, - { "HU,", "Uganda" }, - { "HT,", "Tanzania" }, - { "HS,", "Sudan" }, - { "HR,", "Rwanda" }, - { "HL,", "Libya, Spa Jamahiriya" }, - { "HK,", "Kenya" }, - { "HH,", "Eritrea" }, - { "HE,", "Egypt" }, - { "HD,HF,", "Djibouti" }, - { "HC,", "Somalia" }, - { "HB,", "Burundi" }, - { "HA,", "Ethiopia" }, - { "GV,", "Cape Verde" }, - { "GU,", "Guinea Tepublic" }, - { "GQ,", "Mauritania" }, - { "GO,", "Senegal" }, - { "GM,", "Morocco/Ad Dakhla/La'Youn" }, - { "GL,", "Liberia" }, - { "GG,", "Guinea-Bissau" }, - { "GF,", "Sierra Leone" }, - { "GE,", "Melilla" }, - { "GC,", "Canary Island" }, - { "GB,", "Gambia" }, - { "GA,", "Mali" }, - { "FZ,", "Democratic Republic of Congo" }, - { "FY,", "Namibia" }, - { "FX,", "Lesotho" }, - { "FW,", "Malawi" }, - { "FV,", "Zimbabwe" }, - { "FT,", "Chad" }, - { "FS,", "Seychelles" }, - { "FQ,", "Mozambique" }, - { "FP,", "Sao Tome & Principe" }, - { "FO,", "Gabon" }, - { "FN,", "Angola" }, - { "FM,", "Madagascar/Comoros/Reunion/Mayotte Islands" }, - { "FL,", "Zambia" }, - { "FK,", "Cameroon" }, - { "FJ,", "Chagos Archipelago/British Indian Ocean Territory" }, - { "FI,", "Mauritius" }, - { "FH,", "Ascension Island/St Helena Island" }, - { "FG,", "Equitorial Guinea" }, - { "FE,", "Central African Republic" }, - { "FD,", "Swaziland" }, - { "FC,", "Congo" }, - { "FB,", "Botswana" }, - { "FA,", "South African Republic" }, - { "EY,", "Lithuania" }, - { "EV,", "Latvia" }, - { "ES,", "Sweden" }, - { "EP,", "Poland" }, - { "EN,", "Norway" }, - { "EL,", "Luxembourg" }, - { "EK,", "Denmark/Faroe Island" }, - { "EI,", "Ireland" }, - { "EH,", "Netherlands" }, - { "EG,LX,", "United Kingdom" }, - { "EF,", "Finland" }, - { "EE,", "Estonia" }, - { "ED,ET,", "Germany" }, - { "EB,", "Belgium" }, - { "DX,", "Togo" }, - { "DT,", "Tunisia" }, - { "DR,", "Niger" }, - { "DN,", "Nigeria" }, - { "DI,", "Ivory Coast" }, - { "DG,", "Ghana" }, - { "DF,", "Burkina Faso" }, - { "DB,", "Benin" }, - { "DA,", "Algeria" }, - { "C*,", "Canada" }, - { "BI,", "Iceland" }, - { "BG,", "Greenland" }, - { "AY,", "Papua New Guinea" }, - { "AN,", "Nauru" }, - { "AG,", "Solomon Island" }, - { NULL, NULL } +gt_country_code_t gt_country_codes[] = { + { "ZM,", "Mongolia" }, + { "ZK,", "North Korea" }, + { "Z*,", "China" }, + { "Y*,", "Australia" }, + { "WS,", "Singapore" }, + { "WM,", "Brunei/Malaysia" }, + { "WB,", "Malaysia" }, + { "WA,WI,WQ,WR,", "Indonesia" }, + { "VV,", "Vietnam" }, + { "VT,", "Thailand" }, + { "VR,", "Maldives" }, + { "VQ,", "Bhutan" }, + { "VN,", "Nepal" }, + { "VM,", "Macau" }, + { "VL,", "Laos" }, + { "VH,", "Hong Kong" }, + { "VG,", "Bangladesh" }, + { "VD,", "Kampuchea" }, + { "VC,", "Sri Lanka" }, + { "VB,VY,", "Myanmar/Burma" }, + { "VA,VE,VI,VO,", "India" }, + { "UR,", "Kazakhstan/Russia" }, + { "UT,", "Kazakhstan/Tadzhikistan/Turkmenistan/Uzbekistan" }, + { "UM,", "Belorussia/Russia" }, + { "UK,", "Ukraine" }, + { "UB,", "Azerbaijan" }, + { "UA,", "Kazakhstan/Kirgizia" }, + { "U*,", "Russia" }, + { "TX,", "Bermuda" }, + { "TV,", "St Vincent and the Grenadines" }, + { "TU,", "British Virgin Islands" }, + { "TT,", "Trinidad and Tobago" }, + { "TR,", "Montserrat Island" }, + { "TQ,", "Anguilla" }, + { "TN,", "Aruba/Neth Antilles" }, + { "TL,", "St Lucia" }, + { "TK,", "St Kitts/Nevis Islands" }, + { "TJ,", "Puerto Rico" }, + { "TG,", "Grenada" }, + { "TF,", "Guadeloupe/Martinique" }, + { "TD,", "Dominica" }, + { "TB,", "Barbados" }, + { "TA,", "Antigua" }, + { "SY,", "Guyana" }, + { "SV,", "Venezuela" }, + { "SU,", "Uruguay" }, + { "SP,", "Peru" }, + { "SO,", "French Guiana" }, + { "SM,", "Suriname" }, + { "SL,", "Bolivia" }, + { "SK,", "Colombia/San Andres" }, + { "SG,", "Paraguay" }, + { "SF,", "Falkland Islands" }, + { "SE,", "Ecuador" }, + { "SC,", "Chile/Easter Island" }, + { "SB,SD,SN,SS,SW,", "Brazil" }, + { "SA,", "Argentina" }, + { "S1,", "Antarctica (Argentina/Chile)" }, + { "RP,", "Philippines" }, + { "RK,", "South Korea" }, + { "RJ,", "Japan" }, + { "RC,", "Taiwan" }, + { "PW,", "Wake Island" }, + { "PT,", "Caroline Islands/Micronesia/Palau" }, + { "PM,", "Midway Islands" }, + { "PK,", "Marshall Islands" }, + { "PJ,", "Johnston Atoll" }, + { "PG,", "Guam/Mariana Islands/Northern Mariana Islands" }, + { "PC,", "Kiribati" }, + { "P", "Oakland Octa" }, + { "OY,", "Yemen Arab Rep" }, + { "OT,", "Qatar" }, + { "OS,", "Syria" }, + { "OR,", "Iraq" }, + { "OP,", "Pakistan" }, + { "OO,", "Oman" }, + { "OM,", "United Arab Emirates" }, + { "OL,", "Lebanon" }, + { "OK,", "Kuwait" }, + { "OJ,", "Jordan" }, + { "OI,", "Iran" }, + { "OE,", "Saudi Arabia" }, + { "OB,", "Bahrain" }, + { "OA,", "Afghanistan" }, + { "NZ,PL,", "New Zealand" }, + { "NW,", "New Caledonia" }, + { "NV,", "Vanuatu" }, + { "NT,", "French Polynesia/Society Islands/Tuamotu Islands" }, + { "NS,", "American Samoa/Western Samoa" }, + { "NL,", "Futuna Island/Wallis Island" }, + { "NI,", "Niue" }, + { "NG,", "Kiribati/Tuvalu" }, + { "NF,", "Fiji Island/Tonga" }, + { "NC,", "Cook Islands" }, + { "MZ,", "Belize" }, + { "MY,", "Bahamas" }, + { "MW,", "Cayman Islands" }, + { "MU,", "Cuba" }, + { "MT,", "Haiti" }, + { "MS,", "El Salvador" }, + { "MR,", "Costa rica" }, + { "MP,", "Panama" }, + { "MN,", "Nicaragua" }, + { "MM,", "Mexico" }, + { "MK,", "Jamaica" }, + { "MI,TI,", "Virgin Islands (U.S.)" }, + { "MH,", "Honduras" }, + { "MG,", "Guatemala" }, + { "MD,", "Dominican Republic" }, + { "MB,", "Turks Island/Caicos Island" }, + { "LZ,", "Slovakia" }, + { "LY,", "Yugoslavia" }, + { "LX,", "Gibraltar" }, + { "LW,", "Macedonia" }, + { "LV,", "Gaza" }, + { "LU,", "Moldova" }, + { "LT,", "Turkey" }, + { "LS,", "Switzerland" }, + { "LR,", "Romania" }, + { "LQ,", "Bosnia-Herzegovina" }, + { "LP,", "Portugal/Azores/Madeira Islands" }, + { "LO,", "Austria" }, + { "LN,", "Monaco" }, + { "LM,", "Malta" }, + { "LL,", "Israel/Jerusalem" }, + { "LK,", "Czech" }, + { "LI,", "Italy" }, + { "LH,", "Hungary" }, + { "LG,", "Slovenia" }, + { "LG,", "Greece" }, + { "LF,", "France" }, + { "LF,", "Miquelon Island/St Pierre Island" }, + { "LE,", "Spain" }, + { "LD,", "Croatia" }, + { "LC,", "Cyprus/Turkey (Northern Cyprus)" }, + { "LB,", "Bulgaria" }, + { "LA,", "Albania" }, + { "K*,X*,PA,PB,PF,PJ,PL,PM,PO,PP,PH,PW,", "United States of America" }, + { "HU,", "Uganda" }, + { "HT,", "Tanzania" }, + { "HS,", "Sudan" }, + { "HR,", "Rwanda" }, + { "HL,", "Libya, Spa Jamahiriya" }, + { "HK,", "Kenya" }, + { "HH,", "Eritrea" }, + { "HE,", "Egypt" }, + { "HD,HF,", "Djibouti" }, + { "HC,", "Somalia" }, + { "HB,", "Burundi" }, + { "HA,", "Ethiopia" }, + { "GV,", "Cape Verde" }, + { "GU,", "Guinea Tepublic" }, + { "GQ,", "Mauritania" }, + { "GO,", "Senegal" }, + { "GM,", "Morocco/Ad Dakhla/La'Youn" }, + { "GL,", "Liberia" }, + { "GG,", "Guinea-Bissau" }, + { "GF,", "Sierra Leone" }, + { "GE,", "Melilla" }, + { "GC,", "Canary Island" }, + { "GB,", "Gambia" }, + { "GA,", "Mali" }, + { "FZ,", "Democratic Republic of Congo" }, + { "FY,", "Namibia" }, + { "FX,", "Lesotho" }, + { "FW,", "Malawi" }, + { "FV,", "Zimbabwe" }, + { "FT,", "Chad" }, + { "FS,", "Seychelles" }, + { "FQ,", "Mozambique" }, + { "FP,", "Sao Tome & Principe" }, + { "FO,", "Gabon" }, + { "FN,", "Angola" }, + { "FM,", "Madagascar/Comoros/Reunion/Mayotte Islands" }, + { "FL,", "Zambia" }, + { "FK,", "Cameroon" }, + { "FJ,", "Chagos Archipelago/British Indian Ocean Territory" }, + { "FI,", "Mauritius" }, + { "FH,", "Ascension Island/St Helena Island" }, + { "FG,", "Equitorial Guinea" }, + { "FE,", "Central African Republic" }, + { "FD,", "Swaziland" }, + { "FC,", "Congo" }, + { "FB,", "Botswana" }, + { "FA,", "South African Republic" }, + { "EY,", "Lithuania" }, + { "EV,", "Latvia" }, + { "ES,", "Sweden" }, + { "EP,", "Poland" }, + { "EN,", "Norway" }, + { "EL,", "Luxembourg" }, + { "EK,", "Denmark/Faroe Island" }, + { "EI,", "Ireland" }, + { "EH,", "Netherlands" }, + { "EG,LX,", "United Kingdom" }, + { "EF,", "Finland" }, + { "EE,", "Estonia" }, + { "ED,ET,", "Germany" }, + { "EB,", "Belgium" }, + { "DX,", "Togo" }, + { "DT,", "Tunisia" }, + { "DR,", "Niger" }, + { "DN,", "Nigeria" }, + { "DI,", "Ivory Coast" }, + { "DG,", "Ghana" }, + { "DF,", "Burkina Faso" }, + { "DB,", "Benin" }, + { "DA,", "Algeria" }, + { "C*,", "Canada" }, + { "BI,", "Iceland" }, + { "BG,", "Greenland" }, + { "AY,", "Papua New Guinea" }, + { "AN,", "Nauru" }, + { "AG,", "Solomon Island" }, + { NULL, NULL } }; /* gt_waypt_classes: gdb internal order */ -char *gt_waypt_class_names[] = { - "User Waypoint", - "Airport", - "Intersection", - "NDB", - "VOR", - "Runway Threshold", - "Airport Intersection", - "Airport NDB", - "Map Point", - "Map Area", - "Map Intersection", - "Map Address", - "Map Line", - NULL +char* gt_waypt_class_names[] = { + "User Waypoint", + "Airport", + "Intersection", + "NDB", + "VOR", + "Runway Threshold", + "Airport Intersection", + "Airport NDB", + "Map Point", + "Map Area", + "Map Intersection", + "Map Address", + "Map Line", + NULL }; /* gt_display_mode_names: this order is used by most devices */ -char *gt_display_mode_names[] = { - "Symbol & Name", - "Symbol", - "Symbol & Description" +char* gt_display_mode_names[] = { + "Symbol & Name", + "Symbol", + "Symbol & Description" }; typedef struct { - const char *shortname; - const char *longname; - grid_type grid; + const char* shortname; + const char* longname; + grid_type grid; } grid_mapping_t; /* gt_mps_grid_names: !!! degree sign substituted with '*' !!! */ -grid_mapping_t gt_mps_grid_names[] = -{ - { "ddd", "Lat/Lon hddd.ddddd*", grid_lat_lon_ddd }, - { "dmm", "Lat/Lon hddd*mm.mmm'", grid_lat_lon_dmm }, - { "dms", "Lat/Lon hddd*mm'ss.s\"", grid_lat_lon_dms }, - { "bng", "British National Grid", grid_bng }, - { "utm", "UTM", grid_utm }, - { "swiss", "Swiss grid", grid_swiss }, - { NULL, NULL, 0 } +grid_mapping_t gt_mps_grid_names[] = { + { "ddd", "Lat/Lon hddd.ddddd*", grid_lat_lon_ddd }, + { "dmm", "Lat/Lon hddd*mm.mmm'", grid_lat_lon_dmm }, + { "dms", "Lat/Lon hddd*mm'ss.s\"", grid_lat_lon_dms }, + { "bng", "British National Grid", grid_bng }, + { "utm", "UTM", grid_utm }, + { "swiss", "Swiss grid", grid_swiss }, + { NULL, NULL, (grid_type) 0 } }; /* gt_mps_datum_names: */ typedef struct { - const char *jeeps_name; - const char *mps_name; + const char* jeeps_name; + const char* mps_name; } datum_mapping_t; -/* will be continued (when requested) */ -static datum_mapping_t gt_mps_datum_names[] = -{ - { "Alaska-NAD27", "NAD27 Alaska" }, - { "Bahamas NAD27", "NAD27 Bahamas" }, - { "Canada_Mean(NAD27)", "NAD27 Canada" }, - { "Canal_Zone_(NAD27)", "NAD27 Canal Zone" }, - { "Carribean NAD27", "NAD27 Caribbean" }, - { "Cent America NAD27", "NAD27 Central" }, - { "Cuba NAD27", "NAD27 Cuba" }, - { "Geodetic Datum 49", "Geodetic Datum '49" }, - { "Greenland NAD27", "NAD27 Greenland" }, - { "Mexico NAD27", "NAD27 Mexico" }, - { "North America 83", "NAD83" }, - { "OSGB36", "Ord Srvy Grt Britn" }, - { NULL, NULL } +/* will be continued (when requested) */ +static datum_mapping_t gt_mps_datum_names[] = { + { "Alaska-NAD27", "NAD27 Alaska" }, + { "Bahamas NAD27", "NAD27 Bahamas" }, + { "Canada_Mean(NAD27)", "NAD27 Canada" }, + { "Canal_Zone_(NAD27)", "NAD27 Canal Zone" }, + { "Carribean NAD27", "NAD27 Caribbean" }, + { "Cent America NAD27", "NAD27 Central" }, + { "Cuba NAD27", "NAD27 Cuba" }, + { "Geodetic Datum 49", "Geodetic Datum '49" }, + { "Greenland NAD27", "NAD27 Greenland" }, + { "Mexico NAD27", "NAD27 Mexico" }, + { "North America 83", "NAD83" }, + { "OSGB36", "Ord Srvy Grt Britn" }, + { NULL, NULL } }; typedef struct garmin_color_s { - const char *name; - gbint32 rgb; + const char* name; + gbint32 rgb; } garmin_color_t; -static garmin_color_t gt_colors[] = -{ - { "Unknown", unknown_color }, - { "Black", 0x000000 }, - { "DarkRed", 0x00008B }, - { "DarkGreen", 0x006400 }, - { "DarkYellow", 0x008B8B }, - { "DarkBlue", 0x8B0000 }, - { "DarkMagenta", 0x8B008B }, - { "DarkCyan", 0x8B8B00 }, - { "LightGray", 0xD3D3D3 }, - { "DarkGray", 0xA9A9A9 }, - { "Red", 0x0000FF }, - { "Green", 0x008000 }, - { "Yellow", 0x00FFFF }, - { "Blue", 0xFF0000 }, - { "Magenta", 0xFF00FF }, - { "Cyan", 0xFFFF00 }, - { "White", 0xFFFFFF }, - { "Transparent", unknown_color }, /* Currently not handled */ - { NULL } +static garmin_color_t gt_colors[] = { + { "Unknown", unknown_color }, + { "Black", 0x000000 }, + { "DarkRed", 0x00008B }, + { "DarkGreen", 0x006400 }, + { "DarkYellow", 0x008B8B }, + { "DarkBlue", 0x8B0000 }, + { "DarkMagenta", 0x8B008B }, + { "DarkCyan", 0x8B8B00 }, + { "LightGray", 0xD3D3D3 }, + { "DarkGray", 0xA9A9A9 }, + { "Red", 0x0000FF }, + { "Green", 0x008000 }, + { "Yellow", 0x00FFFF }, + { "Blue", 0xFF0000 }, + { "Magenta", 0xFF00FF }, + { "Cyan", 0xFFFF00 }, + { "White", 0xFFFFFF }, + { "Transparent", unknown_color }, /* Currently not handled */ + { NULL } }; #define GT_COLORS_CT ((sizeof(gt_colors) / sizeof(gt_colors[0])) - 1) @@ -679,408 +675,457 @@ static garmin_color_t gt_colors[] = unsigned char gt_switch_display_mode_value(const unsigned char display_mode, const int protoid, const char device) { - if (device) { - switch(protoid) { - - case 103: - case 107: - case 108: - case 109: - case 110: return display_mode & 3; - case 104: - switch(display_mode) { - case 0: - case 1: return gt_display_mode_symbol; - case 3: return gt_display_mode_symbol_and_name; - case 5: return gt_display_mode_symbol_and_comment; - } - case 155: - switch(display_mode) { - case 1: return gt_display_mode_symbol; - case 3: return gt_display_mode_symbol_and_name; - case 5: return gt_display_mode_symbol_and_comment; - } - } - return gt_display_mode_symbol_and_name; - } else { - switch(protoid) { - - case 103: - case 107: - case 108: - case 109: - case 110: return display_mode & 3; - case 104: - case 155: - switch(display_mode) { - case gt_display_mode_symbol: return 1; - case gt_display_mode_symbol_and_name: return 3; - case gt_display_mode_symbol_and_comment: return 5; - } - } - return 0; - } + if (device) { + switch (protoid) { + + case 103: + case 107: + case 108: + case 109: + case 110: + return display_mode & 3; + case 104: + switch (display_mode) { + case 0: + case 1: + return gt_display_mode_symbol; + case 3: + return gt_display_mode_symbol_and_name; + case 5: + return gt_display_mode_symbol_and_comment; + } + case 155: + switch (display_mode) { + case 1: + return gt_display_mode_symbol; + case 3: + return gt_display_mode_symbol_and_name; + case 5: + return gt_display_mode_symbol_and_comment; + } + } + return gt_display_mode_symbol_and_name; + } else { + switch (protoid) { + + case 103: + case 107: + case 108: + case 109: + case 110: + return display_mode & 3; + case 104: + case 155: + switch (display_mode) { + case gt_display_mode_symbol: + return 1; + case gt_display_mode_symbol_and_name: + return 3; + case gt_display_mode_symbol_and_comment: + return 5; + } + } + return 0; + } } -char * -gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int *dynamic) +char* +gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int* dynamic) { - icon_mapping_t *i; - char custom[] = "Custom 63 "; - - if ((garmin_format == GDB) && (icon >= 500) && (icon <= 563)) - { - snprintf(custom, sizeof(custom), "Custom %d", icon - 500); - *dynamic = 1; - return xstrdup(custom); - } - - if ((garmin_format == PCX) && (icon >= 7680) && (icon <= 8191)) { - snprintf(custom, sizeof(custom), "Custom %d", icon - 7680); - *dynamic = 1; - return xstrdup(custom); - } - - if (dynamic) *dynamic = 0; - - for (i = garmin_icon_table; i->icon; i++) { - switch (garmin_format) { - case MAPSOURCE: - case GDB: - if (icon == i->mpssymnum) - return (char *)i->icon; - break; - case PCX: - case GARMIN_SERIAL: - if (icon == i->pcxsymnum) - return (char *)i->icon; - break; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - return DEFAULT_ICON_DESCR; + icon_mapping_t* i; + char custom[] = "Custom 63 "; + + if ((garmin_format == GDB) && (icon >= 500) && (icon <= 563)) { + snprintf(custom, sizeof(custom), "Custom %d", icon - 500); + *dynamic = 1; + return xstrdup(custom); + } + + if ((garmin_format == PCX) && (icon >= 7680) && (icon <= 8191)) { + snprintf(custom, sizeof(custom), "Custom %d", icon - 7680); + *dynamic = 1; + return xstrdup(custom); + } + + if (dynamic) { + *dynamic = 0; + } + + for (i = garmin_icon_table; i->icon; i++) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + if (icon == i->mpssymnum) { + return (char*)i->icon; + } + break; + case PCX: + case GARMIN_SERIAL: + if (icon == i->pcxsymnum) { + return (char*)i->icon; + } + break; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + return DEFAULT_ICON_DESCR; } -int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format) +int gt_find_icon_number_from_desc(const char* desc, garmin_formats_e garmin_format) { - static int find_flag = 0; - icon_mapping_t *i; - int def_icon = DEFAULT_ICON_VALUE; - int n; - - if (!desc) - return def_icon; - - /* - * If we were given a numeric icon number as a description - * (i.e. 8255), just return that. - */ - n = atoi(desc); - if (n) { - return n; - } - - if (0 == case_ignore_strncmp(desc, "Custom ", 7)) { - int base = 0; - if (garmin_format == GDB) base = 500; - if (garmin_format == PCX) base = 7680; - if (base) { - n = atoi(&desc[7]); - return n + base; - } - } - - for (i = garmin_smart_icon_table; global_opts.smart_icons && i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - switch (garmin_format) { - case MAPSOURCE: - case GDB: - return i->mpssymnum; - case PCX: - case GARMIN_SERIAL: - return i->pcxsymnum; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - } - for (i = garmin_icon_table; i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - switch (garmin_format) { - case MAPSOURCE: - case GDB: - return i->mpssymnum; - case PCX: - case GARMIN_SERIAL: - return i->pcxsymnum; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - } - - /* - * try to handle some complex icon names: i.e. "Blue Diamond" and "Diamond, Blue" - * "find_flag" prevents us from a possible endless loop - */ - - if (find_flag == 0) - { - char **prefix; - char *prefixes[] = {"White ", "Red ", "Green ", "Blue ", "Black ", NULL}; - - for (prefix = prefixes; *prefix != NULL; prefix++) - { - int len = strlen(*prefix); - - if (case_ignore_strncmp(desc, *prefix, len) == 0) - { - char buff[64]; - int result; - - snprintf(buff, sizeof(buff), "%s, %s", &desc[len], *prefix); - rtrim(buff); - - find_flag = 1; - result = gt_find_icon_number_from_desc(buff, garmin_format); - find_flag = 0; - - return result; - } - } - } - return def_icon; + static int find_flag = 0; + icon_mapping_t* i; + int def_icon = DEFAULT_ICON_VALUE; + int n; + + if (!desc) { + return def_icon; + } + + /* + * If we were given a numeric icon number as a description + * (i.e. 8255), just return that. + */ + n = atoi(desc); + if (n) { + return n; + } + + if (0 == case_ignore_strncmp(desc, "Custom ", 7)) { + int base = 0; + if (garmin_format == GDB) { + base = 500; + } + if (garmin_format == PCX) { + base = 7680; + } + if (base) { + n = atoi(&desc[7]); + return n + base; + } + } + + for (i = garmin_smart_icon_table; global_opts.smart_icons && i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + return i->mpssymnum; + case PCX: + case GARMIN_SERIAL: + return i->pcxsymnum; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + } + for (i = garmin_icon_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + return i->mpssymnum; + case PCX: + case GARMIN_SERIAL: + return i->pcxsymnum; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + } + + /* + * try to handle some complex icon names: i.e. "Blue Diamond" and "Diamond, Blue" + * "find_flag" prevents us from a possible endless loop + */ + + if (find_flag == 0) { + char** prefix; + char* prefixes[] = {"White ", "Red ", "Green ", "Blue ", "Black ", NULL}; + + for (prefix = prefixes; *prefix != NULL; prefix++) { + int len = strlen(*prefix); + + if (case_ignore_strncmp(desc, *prefix, len) == 0) { + char buff[64]; + int result; + + snprintf(buff, sizeof(buff), "%s, %s", &desc[len], *prefix); + rtrim(buff); + + find_flag = 1; + result = gt_find_icon_number_from_desc(buff, garmin_format); + find_flag = 0; + + return result; + } + } + } + return def_icon; } -const char * -gt_get_icao_country(const char *cc) +const char* +gt_get_icao_country(const char* cc) { - gt_country_code_t *x = >_country_codes[0]; - - if ((cc == NULL) || (*cc == '\0')) return NULL; - - do { - const char *ccx = x->cc; - while (ccx != NULL) { - if (strncmp(ccx, cc, 2) == 0) return x->country; - if ((ccx[0] == cc[0]) && (ccx[1] == '*')) return x->country; - ccx = strchr(ccx, ','); - if (ccx == NULL) break; - ccx++; - } - x++; - } while (x->cc != NULL); - return NULL; + gt_country_code_t* x = >_country_codes[0]; + + if ((cc == NULL) || (*cc == '\0')) { + return NULL; + } + + do { + const char* ccx = x->cc; + while (ccx != NULL) { + if (strncmp(ccx, cc, 2) == 0) { + return x->country; + } + if ((ccx[0] == cc[0]) && (ccx[1] == '*')) { + return x->country; + } + ccx = strchr(ccx, ','); + if (ccx == NULL) { + break; + } + ccx++; + } + x++; + } while (x->cc != NULL); + return NULL; } -const char * -gt_get_icao_cc(const char *country, const char *shortname) +const char* +gt_get_icao_cc(const char* country, const char* shortname) { - static char res[3]; - gt_country_code_t *x = >_country_codes[0]; - - if ((country == NULL) || (*country == '\0')) { - const char *test; - if (shortname == NULL) return NULL; - switch(strlen(shortname)) { - case 3: strncpy(res, shortname, 1); break; - case 4: strncpy(res, shortname, 2); break; - default: return NULL; - } - test = gt_get_icao_country(res); - if (test != NULL) - return res; - else - return NULL; - } - - do { - if (case_ignore_strcmp(country, x->country) != 0) { - x++; - continue; - } - - if (strlen(x->cc) <= 3) { - strncpy(res, x->cc, 3); - if (res[1] == '*') - res[1] = '\0'; - else - res[2] = '\0'; - return res; - } - if (shortname && (strlen(shortname) == 4)) { - const char *ccx = x->cc; - - strncpy(res, shortname, 2); - res[2] = '\0'; - while (ccx != NULL) { - if (strncmp(ccx, res, 2) == 0) return res; - if ((ccx[0] == res[0]) && (ccx[1] == '*')) return res; - ccx = strchr(ccx, ','); - if (ccx == NULL) break; - ccx++; - } - } - return NULL; - } while (x->country != NULL); - return NULL; + static char res[3]; + gt_country_code_t* x = >_country_codes[0]; + + if ((country == NULL) || (*country == '\0')) { + const char* test; + if (shortname == NULL) { + return NULL; + } + switch (strlen(shortname)) { + case 3: + strncpy(res, shortname, 1); + break; + case 4: + strncpy(res, shortname, 2); + break; + default: + return NULL; + } + test = gt_get_icao_country(res); + if (test != NULL) { + return res; + } else { + return NULL; + } + } + + do { + if (case_ignore_strcmp(country, x->country) != 0) { + x++; + continue; + } + + if (strlen(x->cc) <= 3) { + strncpy(res, x->cc, 3); + if (res[1] == '*') { + res[1] = '\0'; + } else { + res[2] = '\0'; + } + return res; + } + if (shortname && (strlen(shortname) == 4)) { + const char* ccx = x->cc; + + strncpy(res, shortname, 2); + res[2] = '\0'; + while (ccx != NULL) { + if (strncmp(ccx, res, 2) == 0) { + return res; + } + if ((ccx[0] == res[0]) && (ccx[1] == '*')) { + return res; + } + ccx = strchr(ccx, ','); + if (ccx == NULL) { + break; + } + ccx++; + } + } + return NULL; + } while (x->country != NULL); + return NULL; } grid_type -gt_lookup_grid_type(const char *grid_name, const char *module) +gt_lookup_grid_type(const char* grid_name, const char* module) { - grid_mapping_t *g; - - for (g = gt_mps_grid_names; (g->shortname); g++) { - if ((case_ignore_strcmp(grid_name, g->shortname) == 0) || - (case_ignore_strcmp(grid_name, g->longname) == 0)) - return g->grid; - } - - fatal("%s: Unsupported grid (%s)! See GPSBabel help for supported grids.\n", - module, grid_name); - - return grid_unknown; /* (warnings) */ + grid_mapping_t* g; + + for (g = gt_mps_grid_names; (g->shortname); g++) { + if ((case_ignore_strcmp(grid_name, g->shortname) == 0) || + (case_ignore_strcmp(grid_name, g->longname) == 0)) { + return g->grid; + } + } + + fatal("%s: Unsupported grid (%s)! See GPSBabel help for supported grids.\n", + module, grid_name); + + return grid_unknown; /* (warnings) */ } -const char * -gt_get_mps_grid_longname(const grid_type grid, const char *module) +const char* +gt_get_mps_grid_longname(const grid_type grid, const char* module) { - if ((grid < GRID_INDEX_MIN) || (grid > GRID_INDEX_MAX)) - fatal("%s: Grid index out of range %d (%d..%d)!", - module, (int) grid, - (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); - return gt_mps_grid_names[grid].longname; + if ((grid < GRID_INDEX_MIN) || (grid > GRID_INDEX_MAX)) + fatal("%s: Grid index out of range %d (%d..%d)!", + module, (int) grid, + (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); + return gt_mps_grid_names[grid].longname; } -const char * +const char* gt_get_mps_datum_name(const int datum_index) { - char *result; - datum_mapping_t *d; - - result = GPS_Math_Get_Datum_Name(datum_index); + char* result; + datum_mapping_t* d; + + result = GPS_Math_Get_Datum_Name(datum_index); - for (d = gt_mps_datum_names; (d->jeeps_name); d++) - if (case_ignore_strcmp(result, d->jeeps_name) == 0) return d->mps_name; + for (d = gt_mps_datum_names; (d->jeeps_name); d++) + if (case_ignore_strcmp(result, d->jeeps_name) == 0) { + return d->mps_name; + } - return result; + return result; } int -gt_lookup_datum_index(const char *datum_str, const char *module) +gt_lookup_datum_index(const char* datum_str, const char* module) { - datum_mapping_t *d; - int result; - const char *name = datum_str; - - for (d = gt_mps_datum_names; (d->jeeps_name); d++) { - if (case_ignore_strcmp(name, d->mps_name) == 0) { - name = d->jeeps_name; - break; - } - } - - result = GPS_Lookup_Datum_Index(name); - - if (result < 0) { - char *tmp; - xasprintf(&tmp, "%s mean", datum_str); - result = GPS_Lookup_Datum_Index(tmp); - xfree(tmp); - } - - is_fatal(result < 0, - "%s: Unsupported datum (%s)! See GPSBabel help for supported datums.", - module, datum_str); - - return result; + datum_mapping_t* d; + int result; + const char* name = datum_str; + + for (d = gt_mps_datum_names; (d->jeeps_name); d++) { + if (case_ignore_strcmp(name, d->mps_name) == 0) { + name = d->jeeps_name; + break; + } + } + + result = GPS_Lookup_Datum_Index(name); + + if (result < 0) { + char* tmp; + xasprintf(&tmp, "%s mean", datum_str); + result = GPS_Lookup_Datum_Index(tmp); + xfree(tmp); + } + + is_fatal(result < 0, + "%s: Unsupported datum (%s)! See GPSBabel help for supported datums.", + module, datum_str); + + return result; } gbuint32 gt_color_value(const int garmin_index) { - if ((garmin_index >= 0) && (garmin_index < GT_COLORS_CT)) - return gt_colors[garmin_index].rgb; - else - return unknown_color; /* -1 */ + if ((garmin_index >= 0) && (garmin_index < GT_COLORS_CT)) { + return gt_colors[garmin_index].rgb; + } else { + return unknown_color; /* -1 */ + } } gbuint32 -gt_color_value_by_name(const char *name) +gt_color_value_by_name(const char* name) { - int i; + int i; - for (i = 0; i < GT_COLORS_CT; i++) - if (case_ignore_strcmp(gt_colors[i].name, name) == 0) - return gt_colors[i].rgb; + for (i = 0; i < GT_COLORS_CT; i++) + if (case_ignore_strcmp(gt_colors[i].name, name) == 0) { + return gt_colors[i].rgb; + } - return gt_colors[0].rgb; + return gt_colors[0].rgb; } int -gt_color_index_by_name(const char *name) +gt_color_index_by_name(const char* name) { - int i; + int i; - for (i = 0; i < GT_COLORS_CT; i++) - if (case_ignore_strcmp(name, gt_colors[i].name) == 0) return i; + for (i = 0; i < GT_COLORS_CT; i++) + if (case_ignore_strcmp(name, gt_colors[i].name) == 0) { + return i; + } - return 0; /* unknown */ + return 0; /* unknown */ } int gt_color_index_by_rgb(const int rgb) { - int i; + int i; - for (i = 0; i < GT_COLORS_CT; i++) - if (rgb == gt_colors[i].rgb) return i; + for (i = 0; i < GT_COLORS_CT; i++) + if (rgb == gt_colors[i].rgb) { + return i; + } - return 0; /* unknown */ + return 0; /* unknown */ } -const char * +const char* gt_color_name(const int garmin_index) { - if ((garmin_index >= 0) && (garmin_index < GT_COLORS_CT)) - return gt_colors[garmin_index].name; - else - return gt_colors[0].name; + if ((garmin_index >= 0) && (garmin_index < GT_COLORS_CT)) { + return gt_colors[garmin_index].name; + } else { + return gt_colors[0].name; + } } #if MAKE_TABLE /* - * Used to generate icon tables in appendix. + * Used to generate icon tables in appendix. * cc -DMAKE_TABLE garmin_tables.c fatal.o util.o globals.o -lm */ -int cet_utf8_to_ucs4(const char *str, int *bytes, int *value) +int cet_utf8_to_ucs4(const char* str, int* bytes, int* value) { - fatal("Should not be here."); + fatal("Should not be here."); } int -sortem(const void *a, const void *b) +sortem(const void* a, const void* b) { - const icon_mapping_t *aa = a; - const icon_mapping_t *bb = b; + const icon_mapping_t* aa = a; + const icon_mapping_t* bb = b; // return aa->mpssymnum - bb->mpssymnum; - return strcmp(aa->icon, bb->icon); + return strcmp(aa->icon, bb->icon); } main() { - icon_mapping_t *i; - qsort(garmin_icon_table, sizeof(garmin_icon_table) / sizeof(garmin_icon_table[0]) - 1, sizeof(garmin_icon_table[0]), sortem); - for (i = garmin_icon_table; i->icon; i++) { + icon_mapping_t* i; + qsort(garmin_icon_table, sizeof(garmin_icon_table) / sizeof(garmin_icon_table[0]) - 1, sizeof(garmin_icon_table[0]), sortem); + for (i = garmin_icon_table; i->icon; i++) { // printf("%03d\t%s\n", i->mpssymnum, i->icon); - printf("%s\n", i->icon); - } + printf("%s\n", i->icon); + } } #endif diff --git a/gpsbabel/garmin_tables.h b/gpsbabel/garmin_tables.h index 0d2de7734..8a010904e 100644 --- a/gpsbabel/garmin_tables.h +++ b/gpsbabel/garmin_tables.h @@ -29,77 +29,76 @@ #define DEFAULT_ICON_VALUE 18 typedef struct icon_mapping { - const int mpssymnum; - const int pcxsymnum; - const char *icon; + const int mpssymnum; + const int pcxsymnum; + const char* icon; } icon_mapping_t; typedef enum {MAPSOURCE, PCX, GARMIN_SERIAL, GDB} garmin_formats_e; -char *gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int *dynamic); -int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format); +char* gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int* dynamic); +int gt_find_icon_number_from_desc(const char* desc, garmin_formats_e garmin_format); extern icon_mapping_t garmin_icon_table[]; typedef enum { - gt_waypt_class_user_waypoint = 0, - gt_waypt_class_airport, - gt_waypt_class_intersection, - gt_waypt_class_ndb, - gt_waypt_class_vor, - gt_waypt_class_runway_threshold, - gt_waypt_class_airport_intersection, - gt_waypt_class_airport_ndb, - gt_waypt_class_map_point, - gt_waypt_class_map_area, - gt_waypt_class_map_intersection, - gt_waypt_class_map_address, - gt_waypt_class_map_line + gt_waypt_class_user_waypoint = 0, + gt_waypt_class_airport, + gt_waypt_class_intersection, + gt_waypt_class_ndb, + gt_waypt_class_vor, + gt_waypt_class_runway_threshold, + gt_waypt_class_airport_intersection, + gt_waypt_class_airport_ndb, + gt_waypt_class_map_point, + gt_waypt_class_map_area, + gt_waypt_class_map_intersection, + gt_waypt_class_map_address, + gt_waypt_class_map_line } gt_waypt_classes_e; -extern char *gt_waypt_class_names[]; +extern char* gt_waypt_class_names[]; -typedef struct gt_country_code_s -{ - const char *cc; - const char *country; +typedef struct gt_country_code_s { + const char* cc; + const char* country; } gt_country_code_t; extern gt_country_code_t gt_country_codes[]; -const char *gt_get_icao_country(const char *cc); -const char *gt_get_icao_cc(const char *country, const char *shortname); +const char* gt_get_icao_country(const char* cc); +const char* gt_get_icao_cc(const char* country, const char* shortname); /* this order is used by most devices */ typedef enum { - gt_display_mode_symbol_and_name = 0, - gt_display_mode_symbol, - gt_display_mode_symbol_and_comment + gt_display_mode_symbol_and_name = 0, + gt_display_mode_symbol, + gt_display_mode_symbol_and_comment } gt_display_modes_e; - -extern char *gt_display_mode_names[]; + +extern char* gt_display_mode_names[]; #define GT_DISPLAY_MODE_MIN gt_display_mode_symbol_and_name #define GT_DISPLAY_MODE_MAX gt_display_mode_symbol_and_comment typedef enum { - gt_gdb_display_mode_symbol = 0, - gt_gdb_display_mode_symbol_and_name, - gt_gdb_display_mode_symbol_and_comment + gt_gdb_display_mode_symbol = 0, + gt_gdb_display_mode_symbol_and_name, + gt_gdb_display_mode_symbol_and_comment } gt_gdb_display_modes_e; -unsigned char gt_convert_category(const char *name, int *category); +unsigned char gt_convert_category(const char* name, int* category); unsigned char gt_switch_display_mode_value(const unsigned char display_mode, const int protoid, const char device); -grid_type gt_lookup_grid_type(const char *grid_name, const char *module); -const char *gt_get_mps_grid_longname(const grid_type grid, const char *module); -int gt_lookup_datum_index(const char *datum_str, const char *module); -const char *gt_get_mps_datum_name(const int datum_index); +grid_type gt_lookup_grid_type(const char* grid_name, const char* module); +const char* gt_get_mps_grid_longname(const grid_type grid, const char* module); +int gt_lookup_datum_index(const char* datum_str, const char* module); +const char* gt_get_mps_datum_name(const int datum_index); gbuint32 gt_color_value(const int garmin_index); -gbuint32 gt_color_value_by_name(const char *name); -int gt_color_index_by_name(const char *name); +gbuint32 gt_color_value_by_name(const char* name); +int gt_color_index_by_name(const char* name); int gt_color_index_by_rgb(const int rgb); -const char *gt_color_name(const int garmin_index); +const char* gt_color_name(const int garmin_index); #endif diff --git a/gpsbabel/garmin_txt.c b/gpsbabel/garmin_txt.c index 99748e96c..a6e288f9b 100644 --- a/gpsbabel/garmin_txt.c +++ b/gpsbabel/garmin_txt.c @@ -1,7 +1,7 @@ /* Support for MapSource Text Export (Tab delimited) files. - + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #if CSVFMTS_ENABLED @@ -40,42 +40,54 @@ #define MYNAME "garmin_txt" typedef struct gtxt_flags_s { - unsigned int metric:1; - unsigned int celsius:1; - unsigned int utc:1; - unsigned int enum_waypoints:1; - unsigned int route_header_written:1; - unsigned int track_header_written:1; + unsigned int metric:1; + unsigned int celsius:1; + unsigned int utc:1; + unsigned int enum_waypoints:1; + unsigned int route_header_written:1; + unsigned int track_header_written:1; } gtxt_flags_t; -static gbfile *fin, *fout; -static route_head *current_trk, *current_rte; +static gbfile* fin, *fout; +static route_head* current_trk, *current_rte; static int waypoints; static int routepoints; -static waypoint **wpt_a; +static waypoint** wpt_a; static int wpt_a_ct; static grid_type grid_index; static int datum_index; -static char *datum_str; +static char* datum_str; static int current_line; -static char *date_time_format = NULL; +static char* date_time_format = NULL; static int precision = 3; static time_t utc_offs = 0; static gtxt_flags_t gtxt_flags; typedef enum { - waypt_header = 0, - rtept_header, - trkpt_header, - route_header, - track_header, - unknown_header + waypt_header = 0, + rtept_header, + trkpt_header, + route_header, + track_header, + unknown_header } header_type; +#if __cplusplus +inline header_type operator++(header_type& rs, int) +{ + return rs = (header_type)((int)rs + 1); +} + +inline gt_display_modes_e operator++(gt_display_modes_e& rs, int) +{ + return rs = (gt_display_modes_e)((int)rs + 1); +} +#endif + #define MAX_HEADER_FIELDS 36 -static char *header_lines[unknown_header + 1][MAX_HEADER_FIELDS]; +static char* header_lines[unknown_header + 1][MAX_HEADER_FIELDS]; static int header_fields[unknown_header + 1][MAX_HEADER_FIELDS]; static int header_ct[unknown_header + 1]; @@ -89,92 +101,90 @@ static int header_ct[unknown_header + 1]; #define IS_VALID_ALT(a) (((a) != unknown_alt) && ((a) < GARMIN_UNKNOWN_ALT)) #define DUPSTR(a) (((a) != NULL) && ((a)[0] != 0)) ? xstrdup((a)) : NULL -static char *opt_datum = NULL; -static char *opt_dist = NULL; -static char *opt_temp = NULL; -static char *opt_date_format = NULL; -static char *opt_time_format = NULL; -static char *opt_precision = NULL; -static char *opt_utc = NULL; -static char *opt_grid = NULL; +static char* opt_datum = NULL; +static char* opt_dist = NULL; +static char* opt_temp = NULL; +static char* opt_date_format = NULL; +static char* opt_time_format = NULL; +static char* opt_precision = NULL; +static char* opt_utc = NULL; +static char* opt_grid = NULL; static arglist_t garmin_txt_args[] = { - {"date", &opt_date_format, "Read/Write date format (i.e. yyyy/mm/dd)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"datum", &opt_datum, "GPS datum (def. WGS 84)", "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, - {"dist", &opt_dist, "Distance unit [m=metric, s=statute]", "m", ARGTYPE_STRING, ARG_NOMINMAX}, - {"grid", &opt_grid, "Write position using this grid.", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"prec", &opt_precision, "Precision of coordinates", "3", ARGTYPE_INT, ARG_NOMINMAX}, - {"temp", &opt_temp, "Temperature unit [c=Celsius, f=Fahrenheit]", "c", ARGTYPE_STRING, ARG_NOMINMAX}, - {"time", &opt_time_format, "Read/Write time format (i.e. HH:mm:ss xx)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"utc", &opt_utc, "Write timestamps with offset x to UTC time", NULL, ARGTYPE_INT, "-23", "+23"}, - ARG_TERMINATOR + {"date", &opt_date_format, "Read/Write date format (i.e. yyyy/mm/dd)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"datum", &opt_datum, "GPS datum (def. WGS 84)", "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, + {"dist", &opt_dist, "Distance unit [m=metric, s=statute]", "m", ARGTYPE_STRING, ARG_NOMINMAX}, + {"grid", &opt_grid, "Write position using this grid.", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"prec", &opt_precision, "Precision of coordinates", "3", ARGTYPE_INT, ARG_NOMINMAX}, + {"temp", &opt_temp, "Temperature unit [c=Celsius, f=Fahrenheit]", "c", ARGTYPE_STRING, ARG_NOMINMAX}, + {"time", &opt_time_format, "Read/Write time format (i.e. HH:mm:ss xx)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"utc", &opt_utc, "Write timestamps with offset x to UTC time", NULL, ARGTYPE_INT, "-23", "+23"}, + ARG_TERMINATOR }; -typedef struct info_s -{ - double length; - time_t start; - time_t time; - double speed; - double total; - int count; - waypoint *prev_wpt; - waypoint *first_wpt; - waypoint *last_wpt; +typedef struct info_s { + double length; + time_t start; + time_t time; + double speed; + double total; + int count; + waypoint* prev_wpt; + waypoint* first_wpt; + waypoint* last_wpt; } info_t; -static info_t *route_info; +static info_t* route_info; static int route_idx; -static info_t *cur_info; - -static char *headers[] = { - "Name\tDescription\tType\tPosition\tAltitude\tDepth\tProximity\tTemperature\t" - "Display Mode\tColor\tSymbol\tFacility\tCity\tState\tCountry\t" - "Date Modified\tLink\tCategories", - "Waypoint Name\tDistance\tLeg Length\tCourse", - "Position\tTime\tAltitude\tDepth\tTemperature\tLeg Length\tLeg Time\tLeg Speed\tLeg Course", - "Name\tLength\tCourse\tWaypoints\tLink", - "Name\tStart Time\tElapsed Time\tLength\tAverage Speed\tLink", - NULL +static info_t* cur_info; + +static char* headers[] = { + "Name\tDescription\tType\tPosition\tAltitude\tDepth\tProximity\tTemperature\t" + "Display Mode\tColor\tSymbol\tFacility\tCity\tState\tCountry\t" + "Date Modified\tLink\tCategories", + "Waypoint Name\tDistance\tLeg Length\tCourse", + "Position\tTime\tAltitude\tDepth\tTemperature\tLeg Length\tLeg Time\tLeg Speed\tLeg Course", + "Name\tLength\tCourse\tWaypoints\tLink", + "Name\tStart Time\tElapsed Time\tLength\tAverage Speed\tLink", + NULL }; /* helpers */ -static char * -get_option_val(char *option, char *def) +static char* +get_option_val(char* option, char* def) { - char *c = (option != NULL) ? option : def; - return c; + char* c = (option != NULL) ? option : def; + return c; } static void init_date_and_time_format(void) { - char *f, *c; - - f = get_option_val(opt_date_format, DEFAULT_DATE_FORMAT); - date_time_format = convert_human_date_format(f); - - date_time_format = xstrappend(date_time_format, " "); - - f = get_option_val(opt_time_format, DEFAULT_TIME_FORMAT); - c = convert_human_time_format(f); - date_time_format = xstrappend(date_time_format, c); - xfree(c); + char* f, *c; + + f = get_option_val(opt_date_format, DEFAULT_DATE_FORMAT); + date_time_format = convert_human_date_format(f); + + date_time_format = xstrappend(date_time_format, " "); + + f = get_option_val(opt_time_format, DEFAULT_TIME_FORMAT); + c = convert_human_time_format(f); + date_time_format = xstrappend(date_time_format, c); + xfree(c); } static void -convert_datum(const waypoint *wpt, double *dest_lat, double *dest_lon) +convert_datum(const waypoint* wpt, double* dest_lat, double* dest_lon) { - double alt; - - if (datum_index == DATUM_WGS84 ) { - *dest_lat = wpt->latitude; - *dest_lon = wpt->longitude; - } - else GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, - dest_lat, dest_lon, &alt, datum_index); + double alt; + + if (datum_index == DATUM_WGS84) { + *dest_lat = wpt->latitude; + *dest_lon = wpt->longitude; + } else GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + dest_lat, dest_lon, &alt, datum_index); } /* WRITER *****************************************************************/ @@ -182,527 +192,554 @@ convert_datum(const waypoint *wpt, double *dest_lat, double *dest_lon) /* Waypoint preparation */ static void -enum_waypt_cb(const waypoint *wpt) +enum_waypt_cb(const waypoint* wpt) { - garmin_fs_p gmsd; - int wpt_class; - - gmsd = GMSD_FIND(wpt); - wpt_class = GMSD_GET(wpt_class, 0); - if (wpt_class < 0x80) - { - int i; - - if (gtxt_flags.enum_waypoints) /* enumerate only */ - { - waypoints++; - return; - } - for (i = 0; i < wpt_a_ct; i++) { /* check for duplicates */ - waypoint *tmp = wpt_a[i]; - if (case_ignore_strcmp(tmp->shortname, wpt->shortname) == 0) - { - wpt_a[i] = (waypoint *)wpt; - waypoints--; - return; - - } - } - wpt_a[wpt_a_ct++] = (waypoint *)wpt; - } + garmin_fs_p gmsd; + int wpt_class; + + gmsd = GMSD_FIND(wpt); + wpt_class = GMSD_GET(wpt_class, 0); + if (wpt_class < 0x80) { + int i; + + if (gtxt_flags.enum_waypoints) { /* enumerate only */ + waypoints++; + return; + } + for (i = 0; i < wpt_a_ct; i++) { /* check for duplicates */ + waypoint* tmp = wpt_a[i]; + if (case_ignore_strcmp(tmp->shortname, wpt->shortname) == 0) { + wpt_a[i] = (waypoint*)wpt; + waypoints--; + return; + + } + } + wpt_a[wpt_a_ct++] = (waypoint*)wpt; + } } static int -sort_waypt_cb(const void *a, const void *b) +sort_waypt_cb(const void* a, const void* b) { - const waypoint *wa = *(waypoint **)a; - const waypoint *wb = *(waypoint **)b; + const waypoint* wa = *(waypoint**)a; + const waypoint* wb = *(waypoint**)b; - return case_ignore_strcmp(wa->shortname, wb->shortname); + return case_ignore_strcmp(wa->shortname, wb->shortname); } /* common route and track pre-work */ static void -prework_hdr_cb(const route_head *rte) +prework_hdr_cb(const route_head* rte) { - cur_info = &route_info[route_idx]; - cur_info->prev_wpt = NULL; - cur_info->length = 0; - cur_info->time = 0; + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->length = 0; + cur_info->time = 0; } static void -prework_tlr_cb(const route_head *rte) +prework_tlr_cb(const route_head* rte) { - cur_info->last_wpt = cur_info->prev_wpt; - route_idx++; + cur_info->last_wpt = cur_info->prev_wpt; + route_idx++; } static void -prework_wpt_cb(const waypoint *wpt) +prework_wpt_cb(const waypoint* wpt) { - waypoint *prev = cur_info->prev_wpt; - - if (prev != NULL) { - cur_info->time += (wpt->creation_time - prev->creation_time); - cur_info->length += waypt_distance_ex(prev, wpt); - } - else { - cur_info->first_wpt = (waypoint *)wpt; - cur_info->start = wpt->creation_time; - } - cur_info->prev_wpt = (waypoint *)wpt; - cur_info->count++; - routepoints++; + waypoint* prev = cur_info->prev_wpt; + + if (prev != NULL) { + cur_info->time += (wpt->creation_time - prev->creation_time); + cur_info->length += waypt_distance_ex(prev, wpt); + } else { + cur_info->first_wpt = (waypoint*)wpt; + cur_info->start = wpt->creation_time; + } + cur_info->prev_wpt = (waypoint*)wpt; + cur_info->count++; + routepoints++; } /* output helpers */ static void -print_position(const waypoint *wpt) +print_position(const waypoint* wpt) { - int valid = 1; - double lat, lon, north, east; - char latsig, lonsig; - double latmin, lonmin, latsec, lonsec; - int latint, lonint, zone; - char map[3], zonec; - - convert_datum(wpt, &lat, &lon); - - /* ----------------------------------------------------------------------------*/ - /* the following code is from pretty_deg_format (util.c) */ - /* ----------------------------------------------------------------------------*/ - /* !ToDo! generate common code for calculating of degrees, minutes and seconds */ - /* ----------------------------------------------------------------------------*/ - - latsig = lat < 0 ? 'S':'N'; - lonsig = lon < 0 ? 'W':'E'; - latint = abs((int) lat); - lonint = abs((int) lon); - latmin = 60.0 * (fabs(lat) - latint); - lonmin = 60.0 * (fabs(lon) - lonint); - latsec = 60.0 * (latmin - floor(latmin)); - lonsec = 60.0 * (lonmin - floor(lonmin)); - - switch(grid_index) { - - case grid_lat_lon_ddd: - - gbfprintf(fout, "%c%0.*f %c%0.*f\t", - latsig, precision, fabs(lat), - lonsig, precision, fabs(lon)); - break; - - case grid_lat_lon_dmm: - - gbfprintf(fout, "%c%d %0*.*f %c%d %0*.*f\t", - latsig, latint, precision + 3, precision, latmin, - lonsig, lonint, precision + 3, precision, lonmin); - break; - - case grid_lat_lon_dms: - - gbfprintf(fout, "%c%d %d %.*f %c%d %d %.*f\t", - latsig, latint, (int)latmin, precision, latsec, - lonsig, lonint, (int)lonmin, precision, lonsec); - break; - - case grid_bng: - - valid = GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map); - if (valid) gbfprintf(fout, "%s %5.0f %5.0f\t", map, east, north); - break; - - case grid_utm: - - valid = GPS_Math_Known_Datum_To_UTM_EN(lat, lon, - &east, &north, &zone, &zonec, datum_index); - if (valid) gbfprintf(fout, "%02d %c %.0f %.0f\t", zone, zonec, east, north); - break; - - case grid_swiss: - - valid = GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &east, &north); - if (valid) gbfprintf(fout, "%.f %.f\t", east, north); - break; - - default: - fatal("ToDo\n"); - } - - if (! valid) { - gbfprintf(fout, "#####\n"); - fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", - wpt->shortname ? wpt->shortname : "Waypoint", - pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), - gt_get_mps_grid_longname(grid_index, MYNAME)); - } + int valid = 1; + double lat, lon, north, east; + char latsig, lonsig; + double latmin, lonmin, latsec, lonsec; + int latint, lonint, zone; + char map[3], zonec; + + convert_datum(wpt, &lat, &lon); + + /* ----------------------------------------------------------------------------*/ + /* the following code is from pretty_deg_format (util.c) */ + /* ----------------------------------------------------------------------------*/ + /* !ToDo! generate common code for calculating of degrees, minutes and seconds */ + /* ----------------------------------------------------------------------------*/ + + latsig = lat < 0 ? 'S':'N'; + lonsig = lon < 0 ? 'W':'E'; + latint = abs((int) lat); + lonint = abs((int) lon); + latmin = 60.0 * (fabs(lat) - latint); + lonmin = 60.0 * (fabs(lon) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + + switch (grid_index) { + + case grid_lat_lon_ddd: + + gbfprintf(fout, "%c%0.*f %c%0.*f\t", + latsig, precision, fabs(lat), + lonsig, precision, fabs(lon)); + break; + + case grid_lat_lon_dmm: + + gbfprintf(fout, "%c%d %0*.*f %c%d %0*.*f\t", + latsig, latint, precision + 3, precision, latmin, + lonsig, lonint, precision + 3, precision, lonmin); + break; + + case grid_lat_lon_dms: + + gbfprintf(fout, "%c%d %d %.*f %c%d %d %.*f\t", + latsig, latint, (int)latmin, precision, latsec, + lonsig, lonint, (int)lonmin, precision, lonsec); + break; + + case grid_bng: + + valid = GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map); + if (valid) { + gbfprintf(fout, "%s %5.0f %5.0f\t", map, east, north); + } + break; + + case grid_utm: + + valid = GPS_Math_Known_Datum_To_UTM_EN(lat, lon, + &east, &north, &zone, &zonec, datum_index); + if (valid) { + gbfprintf(fout, "%02d %c %.0f %.0f\t", zone, zonec, east, north); + } + break; + + case grid_swiss: + + valid = GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &east, &north); + if (valid) { + gbfprintf(fout, "%.f %.f\t", east, north); + } + break; + + default: + fatal("ToDo\n"); + } + + if (! valid) { + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", + wpt->shortname ? wpt->shortname : "Waypoint", + pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), + gt_get_mps_grid_longname(grid_index, MYNAME)); + } } static void print_date_and_time(const time_t time, const int time_only) { - struct tm tm; - char tbuf[32]; - - if (time < 0) { - gbfprintf(fout, "\t"); - return; - } - if (time_only) { - tm = *gmtime(&time); - snprintf(tbuf, sizeof(tbuf), "%d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); - gbfprintf(fout, "%s", tbuf); - } - else if (time != 0) { - if (gtxt_flags.utc) { - time_t t = time + utc_offs; - tm = *gmtime(&t); - } - else - tm = *localtime(&time); - strftime(tbuf, sizeof(tbuf), date_time_format, &tm); - gbfprintf(fout, "%s ", tbuf); - } - gbfprintf(fout, "\t"); + struct tm tm; + char tbuf[32]; + + if (time < 0) { + gbfprintf(fout, "\t"); + return; + } + if (time_only) { + tm = *gmtime(&time); + snprintf(tbuf, sizeof(tbuf), "%d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + gbfprintf(fout, "%s", tbuf); + } else if (time != 0) { + if (gtxt_flags.utc) { + time_t t = time + utc_offs; + tm = *gmtime(&t); + } else { + tm = *localtime(&time); + } + strftime(tbuf, sizeof(tbuf), date_time_format, &tm); + gbfprintf(fout, "%s ", tbuf); + } + gbfprintf(fout, "\t"); } static void print_categories(gbuint16 categories) { - int i, count; - char *c; - - if (categories == 0) return; - - count = 0; - for (i = 0; i < 16; i++) { - if ((categories & 1) != 0) { - if (global_opts.inifile != NULL) { - char key[3]; - snprintf(key, sizeof(key), "%d", i + 1); - c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); - } - else c = NULL; - - gbfprintf(fout, "%s", (count++ > 0) ? "," : ""); - if (c == NULL) - gbfprintf(fout, "Category %d", i+1); + int i, count; + char* c; + + if (categories == 0) { + return; + } + + count = 0; + for (i = 0; i < 16; i++) { + if ((categories & 1) != 0) { + if (global_opts.inifile != NULL) { + char key[3]; + snprintf(key, sizeof(key), "%d", i + 1); + c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); + } else { + c = NULL; + } + + gbfprintf(fout, "%s", (count++ > 0) ? "," : ""); + if (c == NULL) { + gbfprintf(fout, "Category %d", i+1); + } // gbfprintf(fout, "%s", gps_categories[i]); - else - gbfprintf(fout, "%s", c); - - } - categories = categories >> 1; - } + else { + gbfprintf(fout, "%s", c); + } + + } + categories = categories >> 1; + } } static void -print_course(const waypoint *A, const waypoint *B) /* seems to be okay */ +print_course(const waypoint* A, const waypoint* B) /* seems to be okay */ { - if ((A != NULL) && (B != NULL) && (A != B)) { - int course; - course = si_round(waypt_course(A, B)); - cet_gbfprintf(fout, &cet_cs_vec_cp1252, "%d%c true", course, 0xB0); - } + if ((A != NULL) && (B != NULL) && (A != B)) { + int course; + course = si_round(waypt_course(A, B)); + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "%d%c true", course, 0xB0); + } } static void print_distance(const double distance, const int no_scale, const int with_tab, const int decis) { - double dist = distance; - - if (gtxt_flags.metric == 0) { - dist = METERS_TO_FEET(dist); - - if ((dist < 5280) || no_scale) - gbfprintf(fout, "%.*f ft", decis, dist); - else { - dist = METERS_TO_MILES(distance); - if (dist < (double)100) - gbfprintf(fout, "%.1f mi", dist); - else - gbfprintf(fout, "%d mi", si_round(dist)); - } - } - else - { - if ((dist < 1000) || no_scale) - gbfprintf(fout, "%.*f m", decis, dist); - else { - dist = dist / (double)1000.0; - if (dist < (double)100) - gbfprintf(fout, "%.1f km", dist); - else - gbfprintf(fout, "%d km", si_round(dist)); - } - } - if (with_tab) gbfprintf(fout, "\t"); + double dist = distance; + + if (gtxt_flags.metric == 0) { + dist = METERS_TO_FEET(dist); + + if ((dist < 5280) || no_scale) { + gbfprintf(fout, "%.*f ft", decis, dist); + } else { + dist = METERS_TO_MILES(distance); + if (dist < (double)100) { + gbfprintf(fout, "%.1f mi", dist); + } else { + gbfprintf(fout, "%d mi", si_round(dist)); + } + } + } else { + if ((dist < 1000) || no_scale) { + gbfprintf(fout, "%.*f m", decis, dist); + } else { + dist = dist / (double)1000.0; + if (dist < (double)100) { + gbfprintf(fout, "%.1f km", dist); + } else { + gbfprintf(fout, "%d km", si_round(dist)); + } + } + } + if (with_tab) { + gbfprintf(fout, "\t"); + } } static void -print_speed(double *distance, time_t *time) +print_speed(double* distance, time_t* time) { - int idist; - double dist = *distance; - char *unit; - - if (!gtxt_flags.metric) { - dist = METERS_TO_MILES(dist) * 1000.0; - unit = "mph"; - } - else unit = "kph"; - idist = si_round(dist); - - if ((*time != 0) && (idist > 0)) { - double speed = MPS_TO_KPH(dist / (double)*time); - int ispeed = si_round(speed); - - if (speed < (double)0.01) - gbfprintf(fout, "0 %s", unit); - else if (ispeed < 2) - gbfprintf(fout, "%.1f %s", speed, unit); - else - gbfprintf(fout, "%d %s", ispeed, unit); - } - else - gbfprintf(fout, "0 %s", unit); - gbfprintf(fout, "\t"); + int idist; + double dist = *distance; + char* unit; + + if (!gtxt_flags.metric) { + dist = METERS_TO_MILES(dist) * 1000.0; + unit = "mph"; + } else { + unit = "kph"; + } + idist = si_round(dist); + + if ((*time != 0) && (idist > 0)) { + double speed = MPS_TO_KPH(dist / (double)*time); + int ispeed = si_round(speed); + + if (speed < (double)0.01) { + gbfprintf(fout, "0 %s", unit); + } else if (ispeed < 2) { + gbfprintf(fout, "%.1f %s", speed, unit); + } else { + gbfprintf(fout, "%d %s", ispeed, unit); + } + } else { + gbfprintf(fout, "0 %s", unit); + } + gbfprintf(fout, "\t"); } static void print_temperature(const float temperature) { - if (gtxt_flags.celsius) - gbfprintf(fout, "%.f C", temperature); - else - gbfprintf(fout, "%.f F", (temperature * 1.8) + 32); + if (gtxt_flags.celsius) { + gbfprintf(fout, "%.f C", temperature); + } else { + gbfprintf(fout, "%.f F", (temperature * 1.8) + 32); + } } static void -print_string(const char *fmt, const char *string) +print_string(const char* fmt, const char* string) { - char *c; - char *buff; - - buff = xstrdup(string); - /* remove unwanted characters from source string */ - for (c = buff; *c; c++) { - if (iscntrl(*c)) { - *c = ' '; - } - } - gbfprintf(fout, fmt, buff); - xfree(buff); + char* c; + char* buff; + + buff = xstrdup(string); + /* remove unwanted characters from source string */ + for (c = buff; *c; c++) { + if (iscntrl(*c)) { + *c = ' '; + } + } + gbfprintf(fout, fmt, buff); + xfree(buff); } /* main cb's */ static void -write_waypt(const waypoint *wpt) +write_waypt(const waypoint* wpt) { - unsigned char wpt_class; - garmin_fs_p gmsd; - char *wpt_type; - char *dspl_mode; - const char *country; - double x; - int i, icon, dynamic; - char *icon_descr; - - gmsd = GMSD_FIND(wpt); - - i = GMSD_GET(display, 0); - if (i > GT_DISPLAY_MODE_MAX) i = 0; - dspl_mode = gt_display_mode_names[i]; - - wpt_class = GMSD_GET(wpt_class, 0); - if (wpt_class <= gt_waypt_class_map_line) - wpt_type = gt_waypt_class_names[wpt_class]; - else - wpt_type = gt_waypt_class_names[0]; - - gbfprintf(fout, "Waypoint\t%s\t", (wpt->shortname) ? wpt->shortname : ""); - if (wpt_class <= gt_waypt_class_airport_ndb) { - char *temp = wpt->notes; - if (temp == NULL) { - if (wpt->description && (strcmp(wpt->description, wpt->shortname) != 0)) - temp = wpt->description; - else - temp = ""; - } - print_string("%s\t", temp); - } - else - gbfprintf(fout, "\t"); - gbfprintf(fout, "%s\t", wpt_type); - - print_position(wpt); - - if IS_VALID_ALT(wpt->altitude) - print_distance(wpt->altitude, 1, 0, 0); - gbfprintf(fout, "\t"); - - x = WAYPT_GET(wpt, depth, unknown_alt); - if (x != unknown_alt) - print_distance(x, 1, 0, 1); - gbfprintf(fout, "\t"); - - x = WAYPT_GET(wpt, proximity, unknown_alt); - if (x != unknown_alt) - print_distance(x, 0, 0, 0); - gbfprintf(fout, "\t"); - - x = WAYPT_GET(wpt, temperature, -999); - if (x != -999) - print_temperature(x); - gbfprintf(fout, "\t%s\t", dspl_mode); - - gbfprintf(fout, "Unknown\t"); /* Color is fixed: Unknown */ - - icon = GMSD_GET(icon, -1); - if (icon == -1) { - icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); - } - icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); - print_string("%s\t", icon_descr); - if (dynamic) xfree(icon_descr); - - print_string("%s\t", GMSD_GET(facility, "")); - print_string("%s\t", GMSD_GET(city, "")); - print_string("%s\t", GMSD_GET(state, "")); - country = gt_get_icao_country(GMSD_GET(cc, "")); - print_string("%s\t", (country != NULL) ? country : ""); - print_date_and_time(wpt->creation_time, 0); - print_string("%s\t", wpt->url ? wpt->url : ""); - print_categories(GMSD_GET(category, 0)); - - gbfprintf(fout, "\r\n"); + unsigned char wpt_class; + garmin_fs_p gmsd; + char* wpt_type; + char* dspl_mode; + const char* country; + double x; + int i, icon, dynamic; + char* icon_descr; + + gmsd = GMSD_FIND(wpt); + + i = GMSD_GET(display, 0); + if (i > GT_DISPLAY_MODE_MAX) { + i = 0; + } + dspl_mode = gt_display_mode_names[i]; + + wpt_class = GMSD_GET(wpt_class, 0); + if (wpt_class <= gt_waypt_class_map_line) { + wpt_type = gt_waypt_class_names[wpt_class]; + } else { + wpt_type = gt_waypt_class_names[0]; + } + + gbfprintf(fout, "Waypoint\t%s\t", (wpt->shortname) ? wpt->shortname : ""); + if (wpt_class <= gt_waypt_class_airport_ndb) { + char* temp = wpt->notes; + if (temp == NULL) { + if (wpt->description && (strcmp(wpt->description, wpt->shortname) != 0)) { + temp = wpt->description; + } else { + temp = ""; + } + } + print_string("%s\t", temp); + } else { + gbfprintf(fout, "\t"); + } + gbfprintf(fout, "%s\t", wpt_type); + + print_position(wpt); + + if IS_VALID_ALT(wpt->altitude) { + print_distance(wpt->altitude, 1, 0, 0); + } + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, depth, unknown_alt); + if (x != unknown_alt) { + print_distance(x, 1, 0, 1); + } + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, proximity, unknown_alt); + if (x != unknown_alt) { + print_distance(x, 0, 0, 0); + } + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, temperature, -999); + if (x != -999) { + print_temperature(x); + } + gbfprintf(fout, "\t%s\t", dspl_mode); + + gbfprintf(fout, "Unknown\t"); /* Color is fixed: Unknown */ + + icon = GMSD_GET(icon, -1); + if (icon == -1) { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); + } + icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); + print_string("%s\t", icon_descr); + if (dynamic) { + xfree(icon_descr); + } + + print_string("%s\t", GMSD_GET(facility, "")); + print_string("%s\t", GMSD_GET(city, "")); + print_string("%s\t", GMSD_GET(state, "")); + country = gt_get_icao_country(GMSD_GET(cc, "")); + print_string("%s\t", (country != NULL) ? country : ""); + print_date_and_time(wpt->creation_time, 0); + print_string("%s\t", wpt->url ? wpt->url : ""); + print_categories(GMSD_GET(category, 0)); + + gbfprintf(fout, "\r\n"); } static void -route_disp_hdr_cb(const route_head *rte) +route_disp_hdr_cb(const route_head* rte) { - current_trk = (route_head *)rte; - cur_info = &route_info[route_idx]; - cur_info->prev_wpt = NULL; - cur_info->total = 0; - if (rte->rte_waypt_ct <= 0) return; - - if (!gtxt_flags.route_header_written) { - gtxt_flags.route_header_written = 1; - gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[route_header]); - } - - print_string("\r\nRoute\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); - print_distance(cur_info->length, 0, 1, 0); - print_course(cur_info->first_wpt, cur_info->last_wpt); - gbfprintf(fout, "\t%d waypoints\t", cur_info->count); - print_string("%s\r\n", rte->rte_url ? rte->rte_url : ""); - gbfprintf(fout, "\r\nHeader\t%s\r\n\r\n", headers[rtept_header]); + current_trk = (route_head*)rte; + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->total = 0; + if (rte->rte_waypt_ct <= 0) { + return; + } + + if (!gtxt_flags.route_header_written) { + gtxt_flags.route_header_written = 1; + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[route_header]); + } + + print_string("\r\nRoute\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); + print_distance(cur_info->length, 0, 1, 0); + print_course(cur_info->first_wpt, cur_info->last_wpt); + gbfprintf(fout, "\t%d waypoints\t", cur_info->count); + print_string("%s\r\n", rte->rte_url ? rte->rte_url : ""); + gbfprintf(fout, "\r\nHeader\t%s\r\n\r\n", headers[rtept_header]); } static void -route_disp_tlr_cb(const route_head *rte) +route_disp_tlr_cb(const route_head* rte) { - route_idx++; + route_idx++; } static void -route_disp_wpt_cb(const waypoint *wpt) +route_disp_wpt_cb(const waypoint* wpt) { - waypoint *prev = cur_info->prev_wpt; - - gbfprintf(fout, "Route Waypoint\t"); - gbfprintf(fout, "%s\t", wpt->shortname); - - if (prev != NULL) - { - double dist = waypt_distance_ex(prev, wpt); - cur_info->total += dist; - print_distance(cur_info->total, 0, 1, 0); - print_distance(dist, 0, 1, 0); - print_course(prev, wpt); - } - else - print_distance(0, 1, 0, 0); - - gbfprintf(fout, "\r\n"); - - cur_info->prev_wpt = (waypoint *)wpt; + waypoint* prev = cur_info->prev_wpt; + + gbfprintf(fout, "Route Waypoint\t"); + gbfprintf(fout, "%s\t", wpt->shortname); + + if (prev != NULL) { + double dist = waypt_distance_ex(prev, wpt); + cur_info->total += dist; + print_distance(cur_info->total, 0, 1, 0); + print_distance(dist, 0, 1, 0); + print_course(prev, wpt); + } else { + print_distance(0, 1, 0, 0); + } + + gbfprintf(fout, "\r\n"); + + cur_info->prev_wpt = (waypoint*)wpt; } static void -track_disp_hdr_cb(const route_head *track) +track_disp_hdr_cb(const route_head* track) { - cur_info = &route_info[route_idx]; - cur_info->prev_wpt = NULL; - cur_info->total = 0; - current_trk = (route_head *)track; - if (track->rte_waypt_ct <= 0) return; - - if (!gtxt_flags.track_header_written) { - gtxt_flags.track_header_written = 1; - gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[track_header]); - } - - print_string("\r\nTrack\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); - print_date_and_time(cur_info->start, 0); - print_date_and_time(cur_info->time, 1); - print_distance(cur_info->length, 0, 1, 0); - print_speed(&cur_info->length, &cur_info->time); - print_string("%s", (track->rte_url != NULL) ? track->rte_url : ""); - gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n\r\n", headers[trkpt_header]); + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->total = 0; + current_trk = (route_head*)track; + if (track->rte_waypt_ct <= 0) { + return; + } + + if (!gtxt_flags.track_header_written) { + gtxt_flags.track_header_written = 1; + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[track_header]); + } + + print_string("\r\nTrack\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); + print_date_and_time(cur_info->start, 0); + print_date_and_time(cur_info->time, 1); + print_distance(cur_info->length, 0, 1, 0); + print_speed(&cur_info->length, &cur_info->time); + print_string("%s", (track->rte_url != NULL) ? track->rte_url : ""); + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n\r\n", headers[trkpt_header]); } static void -track_disp_tlr_cb(const route_head *track) +track_disp_tlr_cb(const route_head* track) { - route_idx++; + route_idx++; } static void -track_disp_wpt_cb(const waypoint *wpt) +track_disp_wpt_cb(const waypoint* wpt) { - waypoint *prev = cur_info->prev_wpt; - time_t delta; - double dist, depth; - - gbfprintf(fout, "Trackpoint\t"); - - print_position(wpt); - print_date_and_time(wpt->creation_time, 0); - if IS_VALID_ALT(wpt->altitude) - print_distance(wpt->altitude, 1, 0, 0); - - gbfprintf(fout, "\t"); - depth = WAYPT_GET(wpt, depth, unknown_alt); - if (depth != unknown_alt) - print_distance(depth, 1, 0, 1); - - if (prev != NULL) { - float temp; - gbfprintf(fout, "\t"); - delta = wpt->creation_time - prev->creation_time; - temp = WAYPT_GET(wpt, temperature, -999); - if (temp != -999) - print_temperature(temp); - gbfprintf(fout, "\t"); - dist = waypt_distance_ex(prev, wpt); - print_distance(dist, 0, 1, 0); - print_date_and_time(delta, 1); - print_speed(&dist, &delta); - print_course(prev, wpt); - } - gbfprintf(fout, "\r\n"); - - cur_info->prev_wpt = (waypoint *)wpt; + waypoint* prev = cur_info->prev_wpt; + time_t delta; + double dist, depth; + + gbfprintf(fout, "Trackpoint\t"); + + print_position(wpt); + print_date_and_time(wpt->creation_time, 0); + if IS_VALID_ALT(wpt->altitude) { + print_distance(wpt->altitude, 1, 0, 0); + } + + gbfprintf(fout, "\t"); + depth = WAYPT_GET(wpt, depth, unknown_alt); + if (depth != unknown_alt) { + print_distance(depth, 1, 0, 1); + } + + if (prev != NULL) { + float temp; + gbfprintf(fout, "\t"); + delta = wpt->creation_time - prev->creation_time; + temp = WAYPT_GET(wpt, temperature, -999); + if (temp != -999) { + print_temperature(temp); + } + gbfprintf(fout, "\t"); + dist = waypt_distance_ex(prev, wpt); + print_distance(dist, 0, 1, 0); + print_date_and_time(delta, 1); + print_speed(&dist, &delta); + print_course(prev, wpt); + } + gbfprintf(fout, "\r\n"); + + cur_info->prev_wpt = (waypoint*)wpt; } /******************************************************************************* @@ -710,125 +747,127 @@ track_disp_wpt_cb(const waypoint *wpt) *******************************************************************************/ static void -garmin_txt_wr_init(const char *fname) +garmin_txt_wr_init(const char* fname) { - char *grid_str; - - memset(>xt_flags, 0, sizeof(gtxt_flags)); - - fout = gbfopen(fname, "wb", MYNAME); - - gtxt_flags.metric = (toupper(*get_option_val(opt_dist, "m")) == 'M'); - gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C'); - init_date_and_time_format(); - if (opt_precision) { - precision = atoi(opt_precision); - is_fatal(precision < 0, MYNAME ": Invalid precision (%s)!", opt_precision); - } - - datum_str = get_option_val(opt_datum, NULL); - grid_str = get_option_val(opt_grid, NULL); - - grid_index = grid_lat_lon_dmm; - if (grid_str != NULL) { - int i; - - if (sscanf(grid_str, "%d", &i)) { - grid_index = (grid_type) i; - if ((grid_index < GRID_INDEX_MIN) || (grid_index > GRID_INDEX_MAX)) - fatal(MYNAME ": Grid index out of range (%d..%d)!", - (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); - } - else grid_index = gt_lookup_grid_type(grid_str, MYNAME); - } - - switch(grid_index) { - case grid_bng: /* force datum to "Ord Srvy Grt Britn" */ - datum_index = DATUM_OSGB36; - break; - case grid_swiss: /* force datum to "Ord Srvy Grt Britn" */ - datum_index = DATUM_WGS84; - break; - default: - datum_index = gt_lookup_datum_index(datum_str, MYNAME); - } - - if (opt_utc != NULL) { - if (case_ignore_strcmp(opt_utc, "utc") == 0) - utc_offs = 0; - else - utc_offs = atoi(opt_utc); - utc_offs *= (60 * 60); - gtxt_flags.utc = 1; - } + char* grid_str; + + memset(>xt_flags, 0, sizeof(gtxt_flags)); + + fout = gbfopen(fname, "wb", MYNAME); + + gtxt_flags.metric = (toupper(*get_option_val(opt_dist, "m")) == 'M'); + gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C'); + init_date_and_time_format(); + if (opt_precision) { + precision = atoi(opt_precision); + is_fatal(precision < 0, MYNAME ": Invalid precision (%s)!", opt_precision); + } + + datum_str = get_option_val(opt_datum, NULL); + grid_str = get_option_val(opt_grid, NULL); + + grid_index = grid_lat_lon_dmm; + if (grid_str != NULL) { + int i; + + if (sscanf(grid_str, "%d", &i)) { + grid_index = (grid_type) i; + if ((grid_index < GRID_INDEX_MIN) || (grid_index > GRID_INDEX_MAX)) + fatal(MYNAME ": Grid index out of range (%d..%d)!", + (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); + } else { + grid_index = gt_lookup_grid_type(grid_str, MYNAME); + } + } + + switch (grid_index) { + case grid_bng: /* force datum to "Ord Srvy Grt Britn" */ + datum_index = DATUM_OSGB36; + break; + case grid_swiss: /* force datum to "Ord Srvy Grt Britn" */ + datum_index = DATUM_WGS84; + break; + default: + datum_index = gt_lookup_datum_index(datum_str, MYNAME); + } + + if (opt_utc != NULL) { + if (case_ignore_strcmp(opt_utc, "utc") == 0) { + utc_offs = 0; + } else { + utc_offs = atoi(opt_utc); + } + utc_offs *= (60 * 60); + gtxt_flags.utc = 1; + } } static void garmin_txt_wr_deinit(void) { - gbfclose(fout); - xfree(date_time_format); + gbfclose(fout); + xfree(date_time_format); } static void garmin_txt_write(void) { - char *grid_str, *c; - const char *datum_str; - - grid_str = xstrdup(gt_get_mps_grid_longname(grid_index, MYNAME)); - while ((c = strchr(grid_str, '*'))) *c = 0xB0; /* degree sign */ - cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\t%s\r\n", grid_str); - xfree(grid_str); - - datum_str = gt_get_mps_datum_name(datum_index); - gbfprintf(fout, "Datum\t%s\r\n\r\n", datum_str); - - waypoints = 0; - gtxt_flags.enum_waypoints = 1; /* enum all waypoints */ - waypt_disp_all(enum_waypt_cb); - route_disp_all(NULL, NULL, enum_waypt_cb); - gtxt_flags.enum_waypoints = 0; - - if (waypoints > 0) { - int i; - - wpt_a_ct = 0; - wpt_a = (waypoint **)xcalloc(waypoints, sizeof(*wpt_a)); - waypt_disp_all(enum_waypt_cb); - route_disp_all(NULL, NULL, enum_waypt_cb); - qsort(wpt_a, waypoints, sizeof(*wpt_a), sort_waypt_cb); - - gbfprintf(fout, "Header\t%s\r\n\r\n", headers[waypt_header]); - for (i = 0; i < waypoints; i++) - { - waypoint *wpt = wpt_a[i]; - write_waypt(wpt); - } - xfree(wpt_a); - - route_idx = 0; - route_info = xcalloc(route_count(), sizeof(struct info_s)); - routepoints = 0; - route_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); - if (routepoints > 0) - { - route_idx = 0; - route_disp_all(route_disp_hdr_cb, route_disp_tlr_cb, route_disp_wpt_cb); - } - xfree(route_info); - } - - route_idx = 0; - route_info = xcalloc(track_count(), sizeof(struct info_s)); - routepoints = 0; - track_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); - - if (routepoints > 0) { - route_idx = 0; - track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); - } - xfree(route_info); + char* grid_str, *c; + const char* datum_str; + + grid_str = xstrdup(gt_get_mps_grid_longname(grid_index, MYNAME)); + while ((c = strchr(grid_str, '*'))) { + *c = 0xB0; /* degree sign */ + } + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\t%s\r\n", grid_str); + xfree(grid_str); + + datum_str = gt_get_mps_datum_name(datum_index); + gbfprintf(fout, "Datum\t%s\r\n\r\n", datum_str); + + waypoints = 0; + gtxt_flags.enum_waypoints = 1; /* enum all waypoints */ + waypt_disp_all(enum_waypt_cb); + route_disp_all(NULL, NULL, enum_waypt_cb); + gtxt_flags.enum_waypoints = 0; + + if (waypoints > 0) { + int i; + + wpt_a_ct = 0; + wpt_a = (waypoint**)xcalloc(waypoints, sizeof(*wpt_a)); + waypt_disp_all(enum_waypt_cb); + route_disp_all(NULL, NULL, enum_waypt_cb); + qsort(wpt_a, waypoints, sizeof(*wpt_a), sort_waypt_cb); + + gbfprintf(fout, "Header\t%s\r\n\r\n", headers[waypt_header]); + for (i = 0; i < waypoints; i++) { + waypoint* wpt = wpt_a[i]; + write_waypt(wpt); + } + xfree(wpt_a); + + route_idx = 0; + route_info = (info_t*) xcalloc(route_count(), sizeof(struct info_s)); + routepoints = 0; + route_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); + if (routepoints > 0) { + route_idx = 0; + route_disp_all(route_disp_hdr_cb, route_disp_tlr_cb, route_disp_wpt_cb); + } + xfree(route_info); + } + + route_idx = 0; + route_info = (info_t*) xcalloc(track_count(), sizeof(struct info_s)); + routepoints = 0; + track_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); + + if (routepoints > 0) { + route_idx = 0; + track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); + } + xfree(route_info); } /* READER *****************************************************************/ @@ -838,449 +877,546 @@ garmin_txt_write(void) static void free_header(const header_type ht) { - int i; - - for (i = 0; i < MAX_HEADER_FIELDS; i++) { - char *c = header_lines[ht][i]; - if (c != NULL) { - xfree(c); - header_lines[ht][i] = NULL; - } - } - header_ct[ht] = 0; - memset(header_fields[ht], 0, sizeof(header_fields[ht])); + int i; + + for (i = 0; i < MAX_HEADER_FIELDS; i++) { + char* c = header_lines[ht][i]; + if (c != NULL) { + xfree(c); + header_lines[ht][i] = NULL; + } + } + header_ct[ht] = 0; + memset(header_fields[ht], 0, sizeof(header_fields[ht])); } /* data parsers */ static int -parse_date_and_time(char *str, time_t *value) +parse_date_and_time(char* str, time_t* value) { - struct tm tm; - char *cerr, *cin; - - memset(&tm, 0, sizeof(tm)); - cin = lrtrim(str); - if (*cin == '\0') return 0; - - cerr = strptime(cin, date_time_format, &tm); - if (cerr == NULL) { - cerr = strptime(cin, "%m/%d/%Y %I:%M:%S %p", &tm); - is_fatal(cerr == NULL, MYNAME ": Invalid date or/and time \"%s\" at line %d!", cin, current_line); - } - + struct tm tm; + char* cerr, *cin; + + memset(&tm, 0, sizeof(tm)); + cin = lrtrim(str); + if (*cin == '\0') { + return 0; + } + + cerr = strptime(cin, date_time_format, &tm); + if (cerr == NULL) { + cerr = strptime(cin, "%m/%d/%Y %I:%M:%S %p", &tm); + is_fatal(cerr == NULL, MYNAME ": Invalid date or/and time \"%s\" at line %d!", cin, current_line); + } + // printf(MYNAME "_parse_date_and_time: %02d.%02d.%04d, %02d:%02d:%02d\n", // tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec); - *value = mklocaltime(&tm); - return 1; + *value = mklocaltime(&tm); + return 1; } static gbuint16 -parse_categories(const char *str) +parse_categories(const char* str) { - char buff[256]; - gbuint16 val; - gbuint16 res = 0; - char *cin, *cx; - - if (*str == '\0') return 0; - - strncpy(buff, str, sizeof(buff)); - cin = lrtrim(buff); - if (*cin == '\0') return 0; - - strcat(cin, ","); - - while ((cx = strchr(cin, ','))) { - *cx++ = '\0'; - cin = lrtrim(cin); - if (*cin != '\0') { - if (!garmin_fs_convert_category(cin, &val)) - warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", cin, current_line); - else - res = res | val; - } - cin = cx; - } - return res; + char buff[256]; + gbuint16 val; + gbuint16 res = 0; + char* cin, *cx; + + if (*str == '\0') { + return 0; + } + + strncpy(buff, str, sizeof(buff)); + cin = lrtrim(buff); + if (*cin == '\0') { + return 0; + } + + strcat(cin, ","); + + while ((cx = strchr(cin, ','))) { + *cx++ = '\0'; + cin = lrtrim(cin); + if (*cin != '\0') { + if (!garmin_fs_convert_category(cin, &val)) { + warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", cin, current_line); + } else { + res = res | val; + } + } + cin = cx; + } + return res; } static int -parse_temperature(const char *str, double *temperature) +parse_temperature(const char* str, double* temperature) { - double value; - unsigned char unit; - - if ((str == NULL) || (*str == '\0')) return 0; - - if (sscanf(str, "%lf %c", &value, &unit) == 2) { - unit = toupper(unit); - switch(unit) { - case 'C': *temperature = value; break; - case 'F': *temperature = FAHRENHEIT_TO_CELSIUS(value); break; - default: - fatal(MYNAME ": Unknown temperature unit \"%c\" at line %d!\n", unit, current_line); - } - return 1; - } - else - fatal(MYNAME ": Invalid temperature \"%s\" at line %d!\n", str, current_line); - return 0; + double value; + unsigned char unit; + + if ((str == NULL) || (*str == '\0')) { + return 0; + } + + if (sscanf(str, "%lf %c", &value, &unit) == 2) { + unit = toupper(unit); + switch (unit) { + case 'C': + *temperature = value; + break; + case 'F': + *temperature = FAHRENHEIT_TO_CELSIUS(value); + break; + default: + fatal(MYNAME ": Unknown temperature unit \"%c\" at line %d!\n", unit, current_line); + } + return 1; + } else { + fatal(MYNAME ": Invalid temperature \"%s\" at line %d!\n", str, current_line); + } + return 0; } static void parse_header(void) { - char *str; - int column = -1; - - free_header(unknown_header); - - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - header_lines[unknown_header][column] = strupper(xstrdup(str)); - header_ct[unknown_header]++; - if (header_ct[unknown_header] >= MAX_HEADER_FIELDS) break; - } + char* str; + int column = -1; + + free_header(unknown_header); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + header_lines[unknown_header][column] = strupper(xstrdup(str)); + header_ct[unknown_header]++; + if (header_ct[unknown_header] >= MAX_HEADER_FIELDS) { + break; + } + } } static int -parse_display(const char *str, int *val) +parse_display(const char* str, int* val) { - gt_display_modes_e i; - - if ((str == NULL) || (*str == '\0')) return 0; - - for (i = GT_DISPLAY_MODE_MIN; i <= GT_DISPLAY_MODE_MAX; i++) { - if (case_ignore_strcmp(str, gt_display_mode_names[i]) == 0) { - *val = i; - return 1; - } - } - warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", str, current_line); - return 0; + gt_display_modes_e i; + + if ((str == NULL) || (*str == '\0')) { + return 0; + } + + for (i = GT_DISPLAY_MODE_MIN; i <= GT_DISPLAY_MODE_MAX; i++) { + if (case_ignore_strcmp(str, gt_display_mode_names[i]) == 0) { + *val = i; + return 1; + } + } + warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", str, current_line); + return 0; } static void bind_fields(const header_type ht) { - int i; - char *fields, *c; - - is_fatal((grid_index < 0) || (datum_index < 0), MYNAME ": Incomplete or invalid file header!"); - - if (header_ct[unknown_header] <= 0) return; - free_header(ht); - - /* make a copy of headers[ht], uppercase, replace "\t" with "\0" */ - - i = strlen(headers[ht]); - fields = xmalloc(i + 2); - strcpy(fields, headers[ht]); - strcat(fields, "\t"); - c = strupper(fields); - while ((c = strchr(c, '\t'))) *c++ = '\0'; - - for (i = 0; i < header_ct[unknown_header]; i++) { - char *name; - int field_no; - name = header_lines[ht][i] = header_lines[unknown_header][i]; - header_lines[unknown_header][i] = NULL; - - c = fields; - field_no = 1; - while (*c) { - if (strcmp(c, name) == 0) { - header_fields[ht][i] = field_no; + int i; + char* fields, *c; + + is_fatal((grid_index < 0) || (datum_index < 0), MYNAME ": Incomplete or invalid file header!"); + + if (header_ct[unknown_header] <= 0) { + return; + } + free_header(ht); + + /* make a copy of headers[ht], uppercase, replace "\t" with "\0" */ + + i = strlen(headers[ht]); + fields = (char*) xmalloc(i + 2); + strcpy(fields, headers[ht]); + strcat(fields, "\t"); + c = strupper(fields); + while ((c = strchr(c, '\t'))) { + *c++ = '\0'; + } + + for (i = 0; i < header_ct[unknown_header]; i++) { + char* name; + int field_no; + name = header_lines[ht][i] = header_lines[unknown_header][i]; + header_lines[unknown_header][i] = NULL; + + c = fields; + field_no = 1; + while (*c) { + if (strcmp(c, name) == 0) { + header_fields[ht][i] = field_no; #if 0 - printf("Binding field \"%s\" to internal number %d (%d,%d)\n", name, field_no, ht, i); + printf("Binding field \"%s\" to internal number %d (%d,%d)\n", name, field_no, ht, i); #endif - break; - } - field_no++; - c = c + strlen(c) + 1; - } - } - header_ct[unknown_header] = 0; - xfree(fields); + break; + } + field_no++; + c = c + strlen(c) + 1; + } + } + header_ct[unknown_header] = 0; + xfree(fields); } static void parse_grid(void) { - char *str = csv_lineparse(NULL, "\t", "", 1); - - if (str != NULL) { - if (strstr(str, "dd.ddddd") != 0) grid_index = grid_lat_lon_ddd; - else if (strstr(str, "mm.mmm") != 0) grid_index = grid_lat_lon_dmm; - else if (strstr(str, "mm'ss.s") != 0) grid_index = grid_lat_lon_dms; - else grid_index = gt_lookup_grid_type(str, MYNAME); - } - else - fatal(MYNAME ": Missing grid headline!\n"); + char* str = csv_lineparse(NULL, "\t", "", 1); + + if (str != NULL) { + if (strstr(str, "dd.ddddd") != 0) { + grid_index = grid_lat_lon_ddd; + } else if (strstr(str, "mm.mmm") != 0) { + grid_index = grid_lat_lon_dmm; + } else if (strstr(str, "mm'ss.s") != 0) { + grid_index = grid_lat_lon_dms; + } else { + grid_index = gt_lookup_grid_type(str, MYNAME); + } + } else { + fatal(MYNAME ": Missing grid headline!\n"); + } } static void parse_datum(void) { - char *str = csv_lineparse(NULL, "\t", "", 1); - - if (str != NULL) - datum_index = gt_lookup_datum_index(str, MYNAME); - else - fatal(MYNAME ": Missing GPS datum headline!\n"); + char* str = csv_lineparse(NULL, "\t", "", 1); + + if (str != NULL) { + datum_index = gt_lookup_datum_index(str, MYNAME); + } else { + fatal(MYNAME ": Missing GPS datum headline!\n"); + } } static void parse_waypoint(void) { - char *str; - int column = -1; - waypoint *wpt; - garmin_fs_p gmsd = NULL; - - bind_fields(waypt_header); - - wpt = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - while ((str = csv_lineparse(NULL, "\t", "", column++))) - { - int i, dynamic; - double d; - int field_no = header_fields[waypt_header][column]; - - switch(field_no) { - case 1: wpt->shortname = DUPSTR(str); break; - case 2: wpt->notes = DUPSTR(str); break; - case 3: - for (i = 0; i <= gt_waypt_class_map_line; i++) { - if (case_ignore_strcmp(str, gt_waypt_class_names[i]) == 0) { - GMSD_SET(wpt_class, i); - break; - } - } - break; - case 4: - parse_coordinates(str, datum_index, grid_index, - &wpt->latitude, &wpt->longitude, MYNAME); - break; - case 5: if (parse_distance(str, &d, 1, MYNAME)) wpt->altitude = d; break; - case 6: if (parse_distance(str, &d, 1, MYNAME)) WAYPT_SET(wpt, depth, d); break; - case 7: if (parse_distance(str, &d, 1, MYNAME)) WAYPT_SET(wpt, proximity, d); break; - case 8: if (parse_temperature(str, &d)) WAYPT_SET(wpt, temperature, d); break; - case 9: if (parse_display(str, &i)) GMSD_SET(display, i); break; - case 10: break; /* skip color */ - case 11: - i = gt_find_icon_number_from_desc(str, GDB); - GMSD_SET(icon, i); - wpt->icon_descr = gt_find_desc_from_icon_number(i, GDB, &dynamic); - wpt->wpt_flags.icon_descr_is_dynamic = dynamic; - break; - case 12: GMSD_SETSTR(facility, str); break; - case 13: GMSD_SETSTR(city, str); break; - case 14: GMSD_SETSTR(state, str); break; - case 15: - GMSD_SETSTR(country, str); - GMSD_SETSTR(cc, gt_get_icao_cc(str, wpt->shortname)); - break; - case 16: parse_date_and_time(str, &wpt->creation_time); break; - case 17: wpt->url = DUPSTR(str); break; - case 18: GMSD_SET(category, parse_categories(str)); break; - default: break; - } - } - waypt_add(wpt); + char* str; + int column = -1; + waypoint* wpt; + garmin_fs_p gmsd = NULL; + + bind_fields(waypt_header); + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data*) gmsd); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int i, dynamic; + double d; + int field_no = header_fields[waypt_header][column]; + + switch (field_no) { + case 1: + wpt->shortname = DUPSTR(str); + break; + case 2: + wpt->notes = DUPSTR(str); + break; + case 3: + for (i = 0; i <= gt_waypt_class_map_line; i++) { + if (case_ignore_strcmp(str, gt_waypt_class_names[i]) == 0) { + GMSD_SET(wpt_class, i); + break; + } + } + break; + case 4: + parse_coordinates(str, datum_index, grid_index, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + case 5: + if (parse_distance(str, &d, 1, MYNAME)) { + wpt->altitude = d; + } + break; + case 6: + if (parse_distance(str, &d, 1, MYNAME)) { + WAYPT_SET(wpt, depth, d); + } + break; + case 7: + if (parse_distance(str, &d, 1, MYNAME)) { + WAYPT_SET(wpt, proximity, d); + } + break; + case 8: + if (parse_temperature(str, &d)) { + WAYPT_SET(wpt, temperature, d); + } + break; + case 9: + if (parse_display(str, &i)) { + GMSD_SET(display, i); + } + break; + case 10: + break; /* skip color */ + case 11: + i = gt_find_icon_number_from_desc(str, GDB); + GMSD_SET(icon, i); + wpt->icon_descr = gt_find_desc_from_icon_number(i, GDB, &dynamic); + wpt->wpt_flags.icon_descr_is_dynamic = dynamic; + break; + case 12: + GMSD_SETSTR(facility, str); + break; + case 13: + GMSD_SETSTR(city, str); + break; + case 14: + GMSD_SETSTR(state, str); + break; + case 15: + GMSD_SETSTR(country, str); + GMSD_SETSTR(cc, gt_get_icao_cc(str, wpt->shortname)); + break; + case 16: + parse_date_and_time(str, &wpt->creation_time); + break; + case 17: + wpt->url = DUPSTR(str); + break; + case 18: + GMSD_SET(category, parse_categories(str)); + break; + default: + break; + } + } + waypt_add(wpt); } static void parse_route_header(void) { - char *str; - int column = -1; - route_head *rte; - - rte = route_head_alloc(); - - bind_fields(route_header); - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - int field_no = header_fields[route_header][column]; - switch(field_no) { - case 1: rte->rte_name = DUPSTR(str); break; - case 5: rte->rte_url = DUPSTR(str); break; - } - } - route_add_head(rte); - current_rte = rte; + char* str; + int column = -1; + route_head* rte; + + rte = route_head_alloc(); + + bind_fields(route_header); + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[route_header][column]; + switch (field_no) { + case 1: + rte->rte_name = DUPSTR(str); + break; + case 5: + rte->rte_url = DUPSTR(str); + break; + } + } + route_add_head(rte); + current_rte = rte; } static void parse_track_header(void) { - char *str; - int column = -1; - route_head *trk; - - bind_fields(track_header); - trk = route_head_alloc(); - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - int field_no = header_fields[track_header][column]; - switch(field_no) { - case 1: trk->rte_name = DUPSTR(str); break; - case 6: trk->rte_url = DUPSTR(str); break; - } - } - track_add_head(trk); - current_trk = trk; + char* str; + int column = -1; + route_head* trk; + + bind_fields(track_header); + trk = route_head_alloc(); + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[track_header][column]; + switch (field_no) { + case 1: + trk->rte_name = DUPSTR(str); + break; + case 6: + trk->rte_url = DUPSTR(str); + break; + } + } + track_add_head(trk); + current_trk = trk; } static void parse_route_waypoint(void) { - char *str; - int column = -1; - waypoint *wpt = NULL; - - bind_fields(rtept_header); - - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - int field_no = header_fields[rtept_header][column]; - switch(field_no) { - case 1: - is_fatal((*str == '\0'), MYNAME ": Route waypoint without name at line %d!\n", current_line); - wpt = find_waypt_by_name(str); - is_fatal((wpt == NULL), MYNAME ": Route waypoint \"%s\" not in waypoint list (line %d)!\n", str, current_line); - wpt = waypt_dupe(wpt); - break; - } - } - if (wpt != NULL) - route_add_wpt(current_rte, wpt); + char* str; + int column = -1; + waypoint* wpt = NULL; + + bind_fields(rtept_header); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[rtept_header][column]; + switch (field_no) { + case 1: + is_fatal((*str == '\0'), MYNAME ": Route waypoint without name at line %d!\n", current_line); + wpt = find_waypt_by_name(str); + is_fatal((wpt == NULL), MYNAME ": Route waypoint \"%s\" not in waypoint list (line %d)!\n", str, current_line); + wpt = waypt_dupe(wpt); + break; + } + } + if (wpt != NULL) { + route_add_wpt(current_rte, wpt); + } } static void parse_track_waypoint(void) { - char *str; - int column = -1; - waypoint *wpt; - - bind_fields(trkpt_header); - wpt = waypt_new(); - - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - int field_no; - double x; - - if (! *str) continue; - - field_no = header_fields[trkpt_header][column]; - switch(field_no) { - case 1: - parse_coordinates(str, datum_index, grid_index, - &wpt->latitude, &wpt->longitude, MYNAME); - break; - case 2: - parse_date_and_time(str, &wpt->creation_time); - break; - case 3: - if (parse_distance(str, &x, 1, MYNAME)) - wpt->altitude = x; - break; - case 4: - if (parse_distance(str, &x, 1, MYNAME)) WAYPT_SET(wpt, depth, x); - break; - case 5: - if (parse_temperature(str, &x)) WAYPT_SET(wpt, temperature, x); - break; - case 8: - if (parse_speed(str, &x, 1, MYNAME)) WAYPT_SET(wpt, speed, x); - break; - case 9: - WAYPT_SET(wpt, course, atoi(str)); - break; - } - } - track_add_wpt(current_trk, wpt); + char* str; + int column = -1; + waypoint* wpt; + + bind_fields(trkpt_header); + wpt = waypt_new(); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no; + double x; + + if (! *str) { + continue; + } + + field_no = header_fields[trkpt_header][column]; + switch (field_no) { + case 1: + parse_coordinates(str, datum_index, grid_index, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + case 2: + parse_date_and_time(str, &wpt->creation_time); + break; + case 3: + if (parse_distance(str, &x, 1, MYNAME)) { + wpt->altitude = x; + } + break; + case 4: + if (parse_distance(str, &x, 1, MYNAME)) { + WAYPT_SET(wpt, depth, x); + } + break; + case 5: + if (parse_temperature(str, &x)) { + WAYPT_SET(wpt, temperature, x); + } + break; + case 8: + if (parse_speed(str, &x, 1, MYNAME)) { + WAYPT_SET(wpt, speed, x); + } + break; + case 9: + WAYPT_SET(wpt, course, atoi(str)); + break; + } + } + track_add_wpt(current_trk, wpt); } /***************************************************************/ static void -garmin_txt_rd_init(const char *fname) +garmin_txt_rd_init(const char* fname) { - memset(>xt_flags, 0, sizeof(gtxt_flags)); - - fin = gbfopen(fname, "rb", MYNAME); - memset(&header_ct, 0, sizeof(header_ct)); - - datum_index = -1; - grid_index = -1; - - init_date_and_time_format(); + memset(>xt_flags, 0, sizeof(gtxt_flags)); + + fin = gbfopen(fname, "rb", MYNAME); + memset(&header_ct, 0, sizeof(header_ct)); + + datum_index = -1; + grid_index = (grid_type) -1; + + init_date_and_time_format(); } -static void +static void garmin_txt_rd_deinit(void) { - header_type h; + header_type h; - for (h = waypt_header; h <= unknown_header; h++) { - free_header(h); - } - gbfclose(fin); - xfree(date_time_format); + for (h = waypt_header; h <= unknown_header; h++) { + free_header(h); + } + gbfclose(fin); + xfree(date_time_format); } static void garmin_txt_read(void) { - char *buff; - - current_line = 0; - - while ((buff = gbfgetstr(fin))) { - char *cin; - - if ((current_line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - cin = lrtrim(buff); - if (*cin == '\0') continue; - - cin = csv_lineparse(cin, "\t", "", 0); - - if (cin == NULL) continue; - - if (case_ignore_strcmp(cin, "Header") == 0) parse_header(); - else if (case_ignore_strcmp(cin, "Grid") == 0) parse_grid(); - else if (case_ignore_strcmp(cin, "Datum") == 0) parse_datum(); - else if (case_ignore_strcmp(cin, "Waypoint") == 0) parse_waypoint(); - else if (case_ignore_strcmp(cin, "Route Waypoint") == 0) parse_route_waypoint(); - else if (case_ignore_strcmp(cin, "Trackpoint") == 0) parse_track_waypoint(); - else if (case_ignore_strcmp(cin, "Route") == 0) parse_route_header(); - else if (case_ignore_strcmp(cin, "Track") == 0) parse_track_header(); - else if (case_ignore_strcmp(cin, "Map") == 0) /* do nothing */ ; - else - fatal(MYNAME ": Unknwon identifier (%s) at line %d!\n", cin, current_line); - - /* flush pending data */ - while (csv_lineparse(NULL, "\t", "", 0)); - } + char* buff; + + current_line = 0; + + while ((buff = gbfgetstr(fin))) { + char* cin; + + if ((current_line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + cin = lrtrim(buff); + if (*cin == '\0') { + continue; + } + + cin = csv_lineparse(cin, "\t", "", 0); + + if (cin == NULL) { + continue; + } + + if (case_ignore_strcmp(cin, "Header") == 0) { + parse_header(); + } else if (case_ignore_strcmp(cin, "Grid") == 0) { + parse_grid(); + } else if (case_ignore_strcmp(cin, "Datum") == 0) { + parse_datum(); + } else if (case_ignore_strcmp(cin, "Waypoint") == 0) { + parse_waypoint(); + } else if (case_ignore_strcmp(cin, "Route Waypoint") == 0) { + parse_route_waypoint(); + } else if (case_ignore_strcmp(cin, "Trackpoint") == 0) { + parse_track_waypoint(); + } else if (case_ignore_strcmp(cin, "Route") == 0) { + parse_route_header(); + } else if (case_ignore_strcmp(cin, "Track") == 0) { + parse_track_header(); + } else if (case_ignore_strcmp(cin, "Map") == 0) /* do nothing */ ; + else { + fatal(MYNAME ": Unknwon identifier (%s) at line %d!\n", cin, current_line); + } + + /* flush pending data */ + while (csv_lineparse(NULL, "\t", "", 0)); + } } ff_vecs_t garmin_txt_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - garmin_txt_rd_init, - garmin_txt_wr_init, - garmin_txt_rd_deinit, - garmin_txt_wr_deinit, - garmin_txt_read, - garmin_txt_write, - NULL, - garmin_txt_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + FF_CAP_RW_ALL, + garmin_txt_rd_init, + garmin_txt_wr_init, + garmin_txt_rd_deinit, + garmin_txt_wr_deinit, + garmin_txt_read, + garmin_txt_write, + NULL, + garmin_txt_args, + CET_CHARSET_MS_ANSI, 0 }; #endif // CSVFMTS_ENABLED diff --git a/gpsbabel/garmin_xt.c b/gpsbabel/garmin_xt.c index 84cf2a387..38fedfa04 100644 --- a/gpsbabel/garmin_xt.c +++ b/gpsbabel/garmin_xt.c @@ -31,37 +31,37 @@ #define DATABLOCKSIZE 1 #define STRK_BLOCK_SIZE 97 -static int colors[] = { - 0x000000, // Black - 0x00008b, // DarkRed - 0x006400, // DarkGreen - 0x00d7ff, // Gold - 0x8b0000, // DarkBlue - 0x8b008b, // DarkMagenta - 0x8b8b00, // DarkCyan - 0xd3d3d3, // LightGray - 0xa9a9a9, // DarkGray - 0x0000ff, // Red - 0x00ff00, // Green - 0x00ffff, // Yellow - 0xff0000, // Blue - 0xff00ff, // Magenta - 0xffff00, // Cyan - 0xffffff // White +static int colors[] = { + 0x000000, // Black + 0x00008b, // DarkRed + 0x006400, // DarkGreen + 0x00d7ff, // Gold + 0x8b0000, // DarkBlue + 0x8b008b, // DarkMagenta + 0x8b8b00, // DarkCyan + 0xd3d3d3, // LightGray + 0xa9a9a9, // DarkGray + 0x0000ff, // Red + 0x00ff00, // Green + 0x00ffff, // Yellow + 0xff0000, // Blue + 0xff00ff, // Magenta + 0xffff00, // Cyan + 0xffffff // White }; -static gbfile *fin; -static route_head *track; -static char *opt_xt_ftype = NULL; -static char *opt_trk_header = NULL; +static gbfile* fin; +static route_head* track; +static char* opt_xt_ftype = NULL; +static char* opt_trk_header = NULL; static arglist_t format_garmin_xt_args[] = { - {"ftype", &opt_xt_ftype, "Garmin Mobile XT ([ATRK]/STRK)", "ATRK", ARGTYPE_STRING | ARGTYPE_REQUIRED, ARG_NOMINMAX}, - // TODO: SHIFT - can't test behaviour, do not have appropriate files - //{"trk_header_opt", &opt_trk_header, "Track name processing option ([0]-nrm/1-ign/2-sht)", "0", ARGTYPE_INT, ARG_NOMINMAX}, - {"trk_header", &opt_trk_header, "Track name processing option ([0]-nrm/1-ign)", "0", ARGTYPE_INT, ARG_NOMINMAX}, - ARG_TERMINATOR + {"ftype", &opt_xt_ftype, "Garmin Mobile XT ([ATRK]/STRK)", "ATRK", ARGTYPE_STRING | ARGTYPE_REQUIRED, ARG_NOMINMAX}, + // TODO: SHIFT - can't test behaviour, do not have appropriate files + //{"trk_header_opt", &opt_trk_header, "Track name processing option ([0]-nrm/1-ign/2-sht)", "0", ARGTYPE_INT, ARG_NOMINMAX}, + {"trk_header", &opt_trk_header, "Track name processing option ([0]-nrm/1-ign)", "0", ARGTYPE_INT, ARG_NOMINMAX}, + ARG_TERMINATOR }; /******************************************************************************* @@ -72,80 +72,78 @@ arglist_t format_garmin_xt_args[] = { * %%% Reader callbacks %%% * *******************************************************************************/ static void -format_garmin_xt_rd_init(const char *fname) +format_garmin_xt_rd_init(const char* fname) { - fin = gbfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } -static void +static void format_garmin_xt_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static gbuint16 -format_garmin_xt_rd_st_attrs(char *p_trk_name, gbuint8 *p_track_color) +format_garmin_xt_rd_st_attrs(char* p_trk_name, gbuint8* p_track_color) { - int method = 0; - gbuint16 trackbytes = 0, TrackPoints = 0; - gbuint8 spam = 0; - gbint32 TrackMaxLat = 0, TrackMaxLon = 0, TrackMinLat = 0, TrackMinLon = 0; - char trk_name[30]=""; - // TODO: SHIFT - can't test behaviour, do not have appropriate files - //int ii; - - // get the option for the processing the track name - if ( opt_trk_header ) - { - method = atoi(opt_trk_header); - // if method is out of range set to default - if ((method < 0) || (method > 1)) - { - method = 0; - } - } - // set to RED if not specified - *p_track_color=9; - - trackbytes = gbfgetuint16(fin); - TrackPoints = gbfgetuint16(fin); - - switch (method) - { - case 1: break; // IGNORE - /* TODO: SHIFT - can't test behaviour, do not have appropriate files - case 2: { // SHIFTED method - spam = gbfgetc(fin); - gbfread(&trk_name, 30, DATABLOCKSIZE, fin); - gbfseek(fin, -1, SEEK_CUR); - for (ii = 0; ii<29; ii++) - { - trk_name[ii] = (trk_name[ii] >> 2) + ( trk_name[ii+1] % 4 ) * 64; - } - } - break; - */ - default: { // NORMAL - spam = gbfgetc(fin); - gbfread(&trk_name, 30, DATABLOCKSIZE, fin); - gbfseek(fin, -1, SEEK_CUR); - } - break; - } - spam = gbfgetc(fin); - - gbfread(&TrackMaxLat, 3, DATABLOCKSIZE, fin); - gbfread(&spam, 1, DATABLOCKSIZE, fin); - gbfread(&TrackMaxLon, 3, DATABLOCKSIZE, fin); - gbfread(&spam, 1, DATABLOCKSIZE, fin); - gbfread(&TrackMinLat, 3, DATABLOCKSIZE, fin); - gbfread(&spam, 1, DATABLOCKSIZE, fin); - gbfread(&TrackMinLon, 3, DATABLOCKSIZE, fin); - gbfread(p_track_color, 1, DATABLOCKSIZE, fin); - gbfread(&spam, 1, DATABLOCKSIZE, fin); - - strcpy( p_trk_name, trk_name ); - return trackbytes; + int method = 0; + gbuint16 trackbytes = 0, TrackPoints = 0; + gbuint8 spam = 0; + gbint32 TrackMaxLat = 0, TrackMaxLon = 0, TrackMinLat = 0, TrackMinLon = 0; + char trk_name[30]=""; + // TODO: SHIFT - can't test behaviour, do not have appropriate files + //int ii; + + // get the option for the processing the track name + if (opt_trk_header) { + method = atoi(opt_trk_header); + // if method is out of range set to default + if ((method < 0) || (method > 1)) { + method = 0; + } + } + // set to RED if not specified + *p_track_color=9; + + trackbytes = gbfgetuint16(fin); + TrackPoints = gbfgetuint16(fin); + + switch (method) { + case 1: + break; // IGNORE + /* TODO: SHIFT - can't test behaviour, do not have appropriate files + case 2: { // SHIFTED method + spam = gbfgetc(fin); + gbfread(&trk_name, 30, DATABLOCKSIZE, fin); + gbfseek(fin, -1, SEEK_CUR); + for (ii = 0; ii<29; ii++) + { + trk_name[ii] = (trk_name[ii] >> 2) + ( trk_name[ii+1] % 4 ) * 64; + } + } + break; + */ + default: { // NORMAL + spam = gbfgetc(fin); + gbfread(&trk_name, 30, DATABLOCKSIZE, fin); + gbfseek(fin, -1, SEEK_CUR); + } + break; + } + spam = gbfgetc(fin); + + gbfread(&TrackMaxLat, 3, DATABLOCKSIZE, fin); + gbfread(&spam, 1, DATABLOCKSIZE, fin); + gbfread(&TrackMaxLon, 3, DATABLOCKSIZE, fin); + gbfread(&spam, 1, DATABLOCKSIZE, fin); + gbfread(&TrackMinLat, 3, DATABLOCKSIZE, fin); + gbfread(&spam, 1, DATABLOCKSIZE, fin); + gbfread(&TrackMinLon, 3, DATABLOCKSIZE, fin); + gbfread(p_track_color, 1, DATABLOCKSIZE, fin); + gbfread(&spam, 1, DATABLOCKSIZE, fin); + + strcpy(p_trk_name, trk_name); + return trackbytes; } /* @@ -154,83 +152,78 @@ format_garmin_xt_rd_st_attrs(char *p_trk_name, gbuint8 *p_track_color) static void format_garmin_xt_decrypt_trk_blk(int Count, gbuint8 TrackBlock[]) { - gbuint8 i,j = 12; - while (j<(Count-1)) - { - for ( i = j; i < Count; i++) - { - TrackBlock[i] = TrackBlock[i] >> 1; - if (i<(Count)) - { - TrackBlock[i] = TrackBlock[i] + (TrackBlock[i+1] % 2) * 128; - } - } - j+=12; - } + gbuint8 i,j = 12; + while (j<(Count-1)) { + for (i = j; i < Count; i++) { + TrackBlock[i] = TrackBlock[i] >> 1; + if (i<(Count)) { + TrackBlock[i] = TrackBlock[i] + (TrackBlock[i+1] % 2) * 128; + } + } + j+=12; + } } /* * Function to Decompose track block of STRK_BLOCK_SIZE bytes */ static void -format_garmin_xt_decomp_trk_blk(gbuint8 ii, gbuint8 TrackBlock[], double *Ele, double *Lat, double *Lon, gbuint32 *Time) -{ - gbuint32 LatLW = 0, LonLW = 0, TimeLW = 0; - double LatF = 0, LonF = 0; - gbuint16 PrevEleW; - - //printf("%d %d %d %d %d %d\n", TrackBlock[0], TrackBlock[1], TrackBlock[2], TrackBlock[3], TrackBlock[4], TrackBlock[5]); - PrevEleW = TrackBlock[ ( ii - 1 ) * 12 + 1 ]; - PrevEleW = PrevEleW << 8; - PrevEleW = PrevEleW + TrackBlock[ ( ii - 1 ) * 12 ]; - *Ele = (double)PrevEleW * GARMIN_XT_ELE - 1500; - - LatLW = TrackBlock[(ii - 1) * 12 + 4]; - LatLW = LatLW << 8; - LatLW = LatLW + TrackBlock[(ii - 1) * 12 + 3]; - LatLW = LatLW << 8; - LatLW = LatLW + TrackBlock[(ii - 1) * 12 + 2]; - LatF = (double)LatLW; - if (LatF > 8388608) - { - LatF = LatF - 16777216; - } - *Lat = LatF * 360 / 16777216; - - LonLW = TrackBlock[(ii-1)*12+7]; - LonLW = LonLW << 8; - LonLW = LonLW+TrackBlock[(ii-1)*12+6]; - LonLW = LonLW << 8; - LonLW = LonLW+TrackBlock[(ii-1)*12+5]; - LonF = (double)LonLW; - if (LonF>8388608) - { - LonF = LonF - 16777216; - } - *Lon = LonF * 360 / 16777216; - - TimeLW = TrackBlock[(ii - 1) * 12 + 11]; - TimeLW = TimeLW << 8; - TimeLW = TimeLW+TrackBlock[(ii - 1) * 12 + 10]; - TimeLW = TimeLW << 8; - TimeLW = TimeLW+TrackBlock[(ii - 1) * 12 + 9]; - TimeLW = TimeLW << 8; - TimeLW = TimeLW + TrackBlock[(ii - 1) * 12 + 8]; - *Time = TimeLW + 631065600; +format_garmin_xt_decomp_trk_blk(gbuint8 ii, gbuint8 TrackBlock[], double* Ele, double* Lat, double* Lon, gbuint32* Time) +{ + gbuint32 LatLW = 0, LonLW = 0, TimeLW = 0; + double LatF = 0, LonF = 0; + gbuint16 PrevEleW; + + //printf("%d %d %d %d %d %d\n", TrackBlock[0], TrackBlock[1], TrackBlock[2], TrackBlock[3], TrackBlock[4], TrackBlock[5]); + PrevEleW = TrackBlock[(ii - 1) * 12 + 1 ]; + PrevEleW = PrevEleW << 8; + PrevEleW = PrevEleW + TrackBlock[(ii - 1) * 12 ]; + *Ele = (double)PrevEleW * GARMIN_XT_ELE - 1500; + + LatLW = TrackBlock[(ii - 1) * 12 + 4]; + LatLW = LatLW << 8; + LatLW = LatLW + TrackBlock[(ii - 1) * 12 + 3]; + LatLW = LatLW << 8; + LatLW = LatLW + TrackBlock[(ii - 1) * 12 + 2]; + LatF = (double)LatLW; + if (LatF > 8388608) { + LatF = LatF - 16777216; + } + *Lat = LatF * 360 / 16777216; + + LonLW = TrackBlock[(ii-1)*12+7]; + LonLW = LonLW << 8; + LonLW = LonLW+TrackBlock[(ii-1)*12+6]; + LonLW = LonLW << 8; + LonLW = LonLW+TrackBlock[(ii-1)*12+5]; + LonF = (double)LonLW; + if (LonF>8388608) { + LonF = LonF - 16777216; + } + *Lon = LonF * 360 / 16777216; + + TimeLW = TrackBlock[(ii - 1) * 12 + 11]; + TimeLW = TimeLW << 8; + TimeLW = TimeLW+TrackBlock[(ii - 1) * 12 + 10]; + TimeLW = TimeLW << 8; + TimeLW = TimeLW+TrackBlock[(ii - 1) * 12 + 9]; + TimeLW = TimeLW << 8; + TimeLW = TimeLW + TrackBlock[(ii - 1) * 12 + 8]; + *Time = TimeLW + 631065600; } /* * Decompose Last Waypoint Eleveation */ static void -format_garmin_xt_decomp_last_ele(gbuint8 ii, double *PrevEle, gbuint8 TrackBlock[]) +format_garmin_xt_decomp_last_ele(gbuint8 ii, double* PrevEle, gbuint8 TrackBlock[]) { - gbuint16 PrevEleW; + gbuint16 PrevEleW; - PrevEleW = TrackBlock[ii - 1]; - PrevEleW = PrevEleW << 8; - PrevEleW = PrevEleW + TrackBlock[ii - 2]; - *PrevEle = (double)PrevEleW * GARMIN_XT_ELE - 1500; + PrevEleW = TrackBlock[ii - 1]; + PrevEleW = PrevEleW << 8; + PrevEleW = PrevEleW + TrackBlock[ii - 2]; + *PrevEle = (double)PrevEleW * GARMIN_XT_ELE - 1500; } /* @@ -239,211 +232,205 @@ format_garmin_xt_decomp_last_ele(gbuint8 ii, double *PrevEle, gbuint8 TrackBlock static void format_garmin_xt_proc_strk(void) { - int Count = 0; // Used to obtain number of read bytes - int NumberOfTracks = 0, TracksCompleted = 0; // Number of tracks in the file and number of processed tracks - gbuint16 trackbytes = 0; // Bytes in track - gbuint8 TrackBlock[STRK_BLOCK_SIZE]; // File Block - gbuint8 ii; // temp variable - double Lat = 0, Lon = 0; // wpt data - double PrevLat = 0, PrevLon = 0, PrevEle = 0; // wpt data - gbuint32 Time = 0, PrevTime =0; // wpt data - int FirstCoo; - gbuint8 trk_color = 0xff; - - // Skip 12 bytes from the BOF - gbfseek(fin, 12, SEEK_SET); - - // read # of tracks - NumberOfTracks = gbfgetuint16(fin); - - // Skip 2 bytes - gbfseek(fin, 2, SEEK_CUR); - - // Process all tracks one by one - while ((TracksCompleted < NumberOfTracks) && (!gbfeof( fin ) ) ) - { - route_head *tmp_track; - waypoint *wpt; - char *trk_name; - trk_name = xmalloc(30); - - // Generate Track Header - trackbytes = format_garmin_xt_rd_st_attrs(trk_name, &trk_color) - 50; - - tmp_track = route_head_alloc(); - // update track color - tmp_track->line_color.bbggrr = colors[trk_color]; - tmp_track->line_color.opacity = 255; - // update track name - tmp_track->rte_name = trk_name; - track_add_head(tmp_track); - - // This is the 1st coordinate of the track - FirstCoo = TRUE; - while (trackbytes>0) - { - if (trackbytes>=STRK_BLOCK_SIZE) - { - Count = gbfread(&TrackBlock, DATABLOCKSIZE, STRK_BLOCK_SIZE, fin); - trackbytes -= STRK_BLOCK_SIZE; - } - else - { - Count = gbfread(&TrackBlock, DATABLOCKSIZE, trackbytes, fin); - trackbytes = 0; - } - - // decrypt loaded track block (Count - size of loaded TrackBlock) - format_garmin_xt_decrypt_trk_blk(Count, TrackBlock); - - // process each track point in the loaded TrackBlock - for (ii=1; ii <= ((Count-1) / 12); ii++) - { - // decompose loaded track block part (track point) - format_garmin_xt_decomp_trk_blk(ii, TrackBlock, &PrevEle, &Lat, &Lon, &Time); - - // Add point to the track if not the first point - if (!FirstCoo) - { - //create new waypoint - wpt = waypt_new(); - - //populate wpt; - wpt->latitude = PrevLat; /* Degrees */ - wpt->longitude = PrevLon; /* Degrees */ - wpt->altitude = PrevEle; /* Meters. */ - wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ - - // add way point to the track - track_add_wpt(tmp_track, wpt); - } - else - { - FirstCoo = FALSE; - } - PrevLat = Lat; - PrevLon = Lon; - PrevTime = Time; - } - } - - // decompose elevation for the last point - if (Count > 12) - { - Count--; - } - format_garmin_xt_decomp_last_ele(Count, &PrevEle, TrackBlock); - - //create new waypoint - wpt = waypt_new(); - - //populate wpt; - wpt->latitude = PrevLat; /* Degrees */ - wpt->longitude = PrevLon; /* Degrees */ - wpt->altitude = PrevEle; /* Meters. */ - wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ - - // add way point to the track - track_add_wpt(tmp_track, wpt); - - // update completed tracks counter - TracksCompleted++; - } + int Count = 0; // Used to obtain number of read bytes + int NumberOfTracks = 0, TracksCompleted = 0; // Number of tracks in the file and number of processed tracks + gbuint16 trackbytes = 0; // Bytes in track + gbuint8 TrackBlock[STRK_BLOCK_SIZE]; // File Block + gbuint8 ii; // temp variable + double Lat = 0, Lon = 0; // wpt data + double PrevLat = 0, PrevLon = 0, PrevEle = 0; // wpt data + gbuint32 Time = 0, PrevTime =0; // wpt data + int FirstCoo; + gbuint8 trk_color = 0xff; + + // Skip 12 bytes from the BOF + gbfseek(fin, 12, SEEK_SET); + + // read # of tracks + NumberOfTracks = gbfgetuint16(fin); + + // Skip 2 bytes + gbfseek(fin, 2, SEEK_CUR); + + // Process all tracks one by one + while ((TracksCompleted < NumberOfTracks) && (!gbfeof(fin))) { + route_head* tmp_track; + waypoint* wpt; + char* trk_name; + trk_name = (char*) xmalloc(30); + + // Generate Track Header + trackbytes = format_garmin_xt_rd_st_attrs(trk_name, &trk_color) - 50; + + tmp_track = route_head_alloc(); + // update track color + tmp_track->line_color.bbggrr = colors[trk_color]; + tmp_track->line_color.opacity = 255; + // update track name + tmp_track->rte_name = trk_name; + track_add_head(tmp_track); + + // This is the 1st coordinate of the track + FirstCoo = TRUE; + while (trackbytes>0) { + if (trackbytes>=STRK_BLOCK_SIZE) { + Count = gbfread(&TrackBlock, DATABLOCKSIZE, STRK_BLOCK_SIZE, fin); + trackbytes -= STRK_BLOCK_SIZE; + } else { + Count = gbfread(&TrackBlock, DATABLOCKSIZE, trackbytes, fin); + trackbytes = 0; + } + + // decrypt loaded track block (Count - size of loaded TrackBlock) + format_garmin_xt_decrypt_trk_blk(Count, TrackBlock); + + // process each track point in the loaded TrackBlock + for (ii=1; ii <= ((Count-1) / 12); ii++) { + // decompose loaded track block part (track point) + format_garmin_xt_decomp_trk_blk(ii, TrackBlock, &PrevEle, &Lat, &Lon, &Time); + + // Add point to the track if not the first point + if (!FirstCoo) { + //create new waypoint + wpt = waypt_new(); + + //populate wpt; + wpt->latitude = PrevLat; /* Degrees */ + wpt->longitude = PrevLon; /* Degrees */ + wpt->altitude = PrevEle; /* Meters. */ + wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ + + // add way point to the track + track_add_wpt(tmp_track, wpt); + } else { + FirstCoo = FALSE; + } + PrevLat = Lat; + PrevLon = Lon; + PrevTime = Time; + } + } + + // decompose elevation for the last point + if (Count > 12) { + Count--; + } + format_garmin_xt_decomp_last_ele(Count, &PrevEle, TrackBlock); + + //create new waypoint + wpt = waypt_new(); + + //populate wpt; + wpt->latitude = PrevLat; /* Degrees */ + wpt->longitude = PrevLon; /* Degrees */ + wpt->altitude = PrevEle; /* Meters. */ + wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ + + // add way point to the track + track_add_wpt(tmp_track, wpt); + + // update completed tracks counter + TracksCompleted++; + } } static void format_garmin_xt_proc_atrk(void) { - gbuint16 block=0, uu=0; - gbuint32 Lat=0, Lon=0; - gbuint32 Tim=0; - double LatF = 0, LonF = 0, AltF = 0; - waypoint *wpt; - int method = 0; - unsigned char buf[3]; - gbint32 num_trackpoints; - - // get the option for the processing the track name - if ( opt_trk_header ) - { - method = atoi(opt_trk_header); - } - - if (! track) { - track = route_head_alloc(); - // header option was not set to ignore - if ( method !=1 ) - { - track->rte_name = xstrdup("ATRK XT"); - } - track_add_head(track); - } - - // We think the word at offset 0xc is the trackpoint count. - gbfseek(fin, 12, SEEK_SET); - num_trackpoints = gbfgetuint32(fin); - - while (num_trackpoints--) { - block = gbfgetuint16(fin); - if (block != 0x0c) - break; - - gbfread(&buf, 3, DATABLOCKSIZE, fin); //1. Lat - Lat = buf[0] | (buf[1] << 8) | (buf[2] << 16); - gbfread(&buf, 3, DATABLOCKSIZE, fin); //2. Lon - Lon = buf[0] | (buf[1] << 8) | (buf[2] << 16); - - uu = gbfgetuint16(fin); - Tim = gbfgetuint32(fin); - - Tim += 631065600; // adjustment to UnixTime - LatF = Lat; - if (LatF>8388608) {LatF -= 16777216;}; - LonF = Lon; - if (LonF>8388608) {LonF -= 16777216;}; - AltF = (double)uu * GARMIN_XT_ELE - 1500; - - //create new waypoint - wpt = waypt_new(); - - //populate wpt; - wpt->latitude = LatF*180/16777216; /* Degrees */ - wpt->longitude = LonF*360/16777216; /* Degrees */ - wpt->altitude = AltF; /* Meters. */ - wpt->creation_time = Tim; /* Unix Time adjusted to Garmin time */ - - track_add_wpt(track, wpt); - } + gbuint16 block=0, uu=0; + gbuint32 Lat=0, Lon=0; + gbuint32 Tim=0; + double LatF = 0, LonF = 0, AltF = 0; + waypoint* wpt; + int method = 0; + unsigned char buf[3]; + gbint32 num_trackpoints; + + // get the option for the processing the track name + if (opt_trk_header) { + method = atoi(opt_trk_header); + } + + if (! track) { + track = route_head_alloc(); + // header option was not set to ignore + if (method !=1) { + track->rte_name = xstrdup("ATRK XT"); + } + track_add_head(track); + } + + // We think the word at offset 0xc is the trackpoint count. + gbfseek(fin, 12, SEEK_SET); + num_trackpoints = gbfgetuint32(fin); + + while (num_trackpoints--) { + block = gbfgetuint16(fin); + if (block != 0x0c) { + break; + } + + gbfread(&buf, 3, DATABLOCKSIZE, fin); //1. Lat + Lat = buf[0] | (buf[1] << 8) | (buf[2] << 16); + gbfread(&buf, 3, DATABLOCKSIZE, fin); //2. Lon + Lon = buf[0] | (buf[1] << 8) | (buf[2] << 16); + + uu = gbfgetuint16(fin); + Tim = gbfgetuint32(fin); + + Tim += 631065600; // adjustment to UnixTime + LatF = Lat; + if (LatF>8388608) { + LatF -= 16777216; + }; + LonF = Lon; + if (LonF>8388608) { + LonF -= 16777216; + }; + AltF = (double)uu * GARMIN_XT_ELE - 1500; + + //create new waypoint + wpt = waypt_new(); + + //populate wpt; + wpt->latitude = LatF*180/16777216; /* Degrees */ + wpt->longitude = LonF*360/16777216; /* Degrees */ + wpt->altitude = AltF; /* Meters. */ + wpt->creation_time = Tim; /* Unix Time adjusted to Garmin time */ + + track_add_wpt(track, wpt); + } } static void format_garmin_xt_read(void) { - // Saved Tracks file - if ( strcmp(opt_xt_ftype, "STRK") == 0 ) - format_garmin_xt_proc_strk(); - else // Active Track file - format_garmin_xt_proc_atrk(); + // Saved Tracks file + if (strcmp(opt_xt_ftype, "STRK") == 0) { + format_garmin_xt_proc_strk(); + } else { // Active Track file + format_garmin_xt_proc_atrk(); + } } /**************************************************************************/ ff_vecs_t format_garmin_xt_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - format_garmin_xt_rd_init, - NULL, - format_garmin_xt_rd_deinit, - NULL, - format_garmin_xt_read, - NULL, - NULL, - format_garmin_xt_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + format_garmin_xt_rd_init, + NULL, + format_garmin_xt_rd_deinit, + NULL, + format_garmin_xt_read, + NULL, + NULL, + format_garmin_xt_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/gbdatetime.h b/gpsbabel/gbdatetime.h new file mode 100644 index 000000000..6b56171bc --- /dev/null +++ b/gpsbabel/gbdatetime.h @@ -0,0 +1,18 @@ +// Copyright ME. + +#include + +// As this code began in C, we have several hundred places that set and +// read creation_time as a time_t. Provide some operator overloads to make +// that less painful. +class gbDateTime : public QDateTime { +public: + operator const time_t() const { + return this->toTime_t(); + } + const time_t& operator=(const time_t& t) { + this->setTime_t(t); + } +}; + + diff --git a/gpsbabel/gbfile.c b/gpsbabel/gbfile.c index c970d083b..c54133640 100644 --- a/gpsbabel/gbfile.c +++ b/gpsbabel/gbfile.c @@ -62,178 +62,188 @@ /* %%% Zlib file api %%% */ /*******************************************************************************/ -static gbfile * -gzapi_open(gbfile *self, const char *mode) +static gbfile* +gzapi_open(gbfile* self, const char* mode) { - char openmode[32]; + char openmode[32]; - self->gzapi = 1; + self->gzapi = 1; - /* under non-posix systems files MUST be opened in binary mode */ + /* under non-posix systems files MUST be opened in binary mode */ - strcpy(openmode, mode); - if (strchr(mode, 'b') == NULL) - strncat(openmode, "b", sizeof(openmode)); + strcpy(openmode, mode); + if (strchr(mode, 'b') == NULL) { + strncat(openmode, "b", sizeof(openmode)); + } - if (self->is_pipe) { - FILE *fd; - if (self->mode == 'r') - fd = stdin; - else - fd = stdout; - SET_BINARY_MODE(fd); - self->handle.gz = gzdopen(fileno(fd), openmode); - } - else - self->handle.gz = gzopen(self->name, openmode); + if (self->is_pipe) { + FILE* fd; + if (self->mode == 'r') { + fd = stdin; + } else { + fd = stdout; + } + SET_BINARY_MODE(fd); + self->handle.gz = (void**)gzdopen(fileno(fd), openmode); + } else { + self->handle.gz = (void**)gzopen(self->name, openmode); + } - if (self->handle.gz == NULL) { - fatal("%s: Cannot %s file '%s'!\n", - self->module, - (self->mode == 'r') ? "open" : "create", - self->name); - } + if (self->handle.gz == NULL) { + fatal("%s: Cannot %s file '%s'!\n", + self->module, + (self->mode == 'r') ? "open" : "create", + self->name); + } - return self; + return self; } static int -gzapi_close(gbfile *self) +gzapi_close(gbfile* self) { - return gzclose(self->handle.gz); + return gzclose(self->handle.gz); } static int -gzapi_seek(gbfile *self, gbint32 offset, int whence) +gzapi_seek(gbfile* self, gbint32 offset, int whence) { - int result; + int result; - assert(whence != SEEK_END); + assert(whence != SEEK_END); - if ((whence == SEEK_CUR) && (self->back != -1)) offset--; - result = gzseek(self->handle.gz, offset, whence); - self->back = -1; + if ((whence == SEEK_CUR) && (self->back != -1)) { + offset--; + } + result = gzseek(self->handle.gz, offset, whence); + self->back = -1; - if (result < 0) { - if (self->is_pipe) - fatal("%s: This format cannot be used in piped commands!\n", self->module); - fatal("%s: online compression not yet supported for this format!", self->module); - } - return 0; + if (result < 0) { + if (self->is_pipe) { + fatal("%s: This format cannot be used in piped commands!\n", self->module); + } + fatal("%s: online compression not yet supported for this format!", self->module); + } + return 0; } static gbsize_t -gzapi_read(void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) +gzapi_read(void* buf, const gbsize_t size, const gbsize_t members, gbfile* self) { - int result = 0; - char *target = buf; - int count = size * members; + int result = 0; + char* target = (char*) buf; + int count = size * members; - if (self->back != -1) { - *target++ = self->back; - count--; - result++; - self->back = -1; - } - result += gzread(self->handle.gz, target, count); + if (self->back != -1) { + *target++ = self->back; + count--; + result++; + self->back = -1; + } + result += gzread(self->handle.gz, target, count); - /* Check for an incomplete READ */ - if ((members == 1) && (size > 1) && (result > 0) && (result < (int)size)) - fatal("%s: Unexpected end of file (EOF)!\n", self->module); + /* Check for an incomplete READ */ + if ((members == 1) && (size > 1) && (result > 0) && (result < (int)size)) { + fatal("%s: Unexpected end of file (EOF)!\n", self->module); + } - result /= size; + result /= size; - if ((result < 0) || ((gbsize_t)result < members)) { - int errnum; - const char *errtxt; + if ((result < 0) || ((gbsize_t)result < members)) { + int errnum; + const char* errtxt; - errtxt = gzerror(self->handle.gz, &errnum); + errtxt = gzerror(self->handle.gz, &errnum); - /* Workaround for zlib bug: buffer error on empty files */ - if ((errnum == Z_BUF_ERROR) && (gztell(self->handle.gz) == 0)) { - return (gbsize_t) 0; - } - if ((errnum != Z_STREAM_END) && (errnum != 0)) - fatal("%s: zlib returned error %d ('%s')!\n", - self->module, errnum, errtxt); - } - return (gbsize_t) result; + /* Workaround for zlib bug: buffer error on empty files */ + if ((errnum == Z_BUF_ERROR) && (gztell(self->handle.gz) == 0)) { + return (gbsize_t) 0; + } + if ((errnum != Z_STREAM_END) && (errnum != 0)) + fatal("%s: zlib returned error %d ('%s')!\n", + self->module, errnum, errtxt); + } + return (gbsize_t) result; } static gbsize_t -gzapi_write(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) +gzapi_write(const void* buf, const gbsize_t size, const gbsize_t members, gbfile* self) { - return gzwrite(self->handle.gz, buf, size * members) / size; + return gzwrite(self->handle.gz, buf, size * members) / size; } static int -gzapi_flush(gbfile *self) +gzapi_flush(gbfile* self) { - return gzflush(self->handle.gz, Z_SYNC_FLUSH); + return gzflush(self->handle.gz, Z_SYNC_FLUSH); } static gbsize_t -gzapi_tell(gbfile *self) +gzapi_tell(gbfile* self) { - gbsize_t result; + gbsize_t result; - result = gztell(self->handle.gz); - if (self->back != -1) result--; + result = gztell(self->handle.gz); + if (self->back != -1) { + result--; + } - return result; + return result; } static int -gzapi_eof(gbfile *self) -{ - int res = 0; - - if (self->back != -1) return res; - - res = gzeof(self->handle.gz); - if (!res) { - unsigned char test; - int len = gzread(self->handle.gz, &test, 1); - if (len == 1) { - /* No EOF, put the single byte back into stream */ - self->back = test; - } - else { - /* we are at the end of the file */ - if (global_opts.debug_level > 0) { - /* now gzeof() should return 1 */ - is_fatal(!gzeof(self->handle.gz), "zlib gzeof error!\n"); - } - res = 1; - } - } - return res; +gzapi_eof(gbfile* self) +{ + int res = 0; + + if (self->back != -1) { + return res; + } + + res = gzeof(self->handle.gz); + if (!res) { + unsigned char test; + int len = gzread(self->handle.gz, &test, 1); + if (len == 1) { + /* No EOF, put the single byte back into stream */ + self->back = test; + } else { + /* we are at the end of the file */ + if (global_opts.debug_level > 0) { + /* now gzeof() should return 1 */ + is_fatal(!gzeof(self->handle.gz), "zlib gzeof error!\n"); + } + res = 1; + } + } + return res; } static int -gzapi_ungetc(const int c, gbfile *self) +gzapi_ungetc(const int c, gbfile* self) { - if (self->back == -1) - self->back = c; - else - fatal(MYNAME ": Cannot store more than one byte back!\n"); - return c; + if (self->back == -1) { + self->back = c; + } else { + fatal(MYNAME ": Cannot store more than one byte back!\n"); + } + return c; } static void -gzapi_clearerr(gbfile *self) +gzapi_clearerr(gbfile* self) { - gzclearerr(self->handle.gz); + gzclearerr(self->handle.gz); } static int -gzapi_error(gbfile *self) +gzapi_error(gbfile* self) { - int errnum; + int errnum; - (void)gzerror(self->handle.gz, &errnum); + (void)gzerror(self->handle.gz, &errnum); - return errnum; + return errnum; } #endif // #if !ZLIB_INHIBITED @@ -242,96 +252,102 @@ gzapi_error(gbfile *self) /* %%% Standard C file api %%% */ /*******************************************************************************/ -static gbfile * -stdapi_open(gbfile *self, const char *mode) +static gbfile* +stdapi_open(gbfile* self, const char* mode) { - self->handle.std = xfopen(self->name, mode, self->module); - return self; + self->handle.std = xfopen(self->name, mode, self->module); + return self; } static int -stdapi_close(gbfile *self) +stdapi_close(gbfile* self) { - return fclose(self->handle.std); + return fclose(self->handle.std); } static int -stdapi_seek(gbfile *self, gbint32 offset, int whence) -{ - int result; - gbsize_t pos = 0; - - if (whence != SEEK_SET) pos = ftell(self->handle.std); - - result = fseek(self->handle.std, offset, whence); - if (result != 0) { - switch (whence) { - case SEEK_CUR: - case SEEK_END: pos = pos + offset; break; - case SEEK_SET: pos = offset; break; - default: - fatal("%s: Unknown seek operation (%d) for file %s!\n", - self->module, whence, self->name); - } - fatal("%s: Unable to set file (%s) to position (%llu)!\n", - self->module, self->name, (long long unsigned) pos); - } - return 0; +stdapi_seek(gbfile* self, gbint32 offset, int whence) +{ + int result; + gbsize_t pos = 0; + + if (whence != SEEK_SET) { + pos = ftell(self->handle.std); + } + + result = fseek(self->handle.std, offset, whence); + if (result != 0) { + switch (whence) { + case SEEK_CUR: + case SEEK_END: + pos = pos + offset; + break; + case SEEK_SET: + pos = offset; + break; + default: + fatal("%s: Unknown seek operation (%d) for file %s!\n", + self->module, whence, self->name); + } + fatal("%s: Unable to set file (%s) to position (%llu)!\n", + self->module, self->name, (long long unsigned) pos); + } + return 0; } static gbsize_t -stdapi_read(void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) +stdapi_read(void* buf, const gbsize_t size, const gbsize_t members, gbfile* self) { - int errno; - gbsize_t result = fread(buf, size, members, self->handle.std); + int errno; + gbsize_t result = fread(buf, size, members, self->handle.std); - if ((result < members) && (errno = ferror(self->handle.std))) { - fatal("%s: Error %d occured during read of file '%s'!\n", - self->module, errno, self->name); - } - return result; + if ((result < members) && (errno = ferror(self->handle.std))) { + fatal("%s: Error %d occured during read of file '%s'!\n", + self->module, errno, self->name); + } + return result; } static gbsize_t -stdapi_write(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) +stdapi_write(const void* buf, const gbsize_t size, const gbsize_t members, gbfile* self) { - return fwrite(buf, size, members, self->handle.std); + return fwrite(buf, size, members, self->handle.std); } static int -stdapi_flush(gbfile *self) +stdapi_flush(gbfile* self) { - return fflush(self->handle.std); + return fflush(self->handle.std); } static gbsize_t -stdapi_tell(gbfile *self) +stdapi_tell(gbfile* self) { - return ftell(self->handle.std); + return ftell(self->handle.std); } static int -stdapi_eof(gbfile *self) +stdapi_eof(gbfile* self) { - return feof(self->handle.std); + return feof(self->handle.std); } static int -stdapi_ungetc(const int c, gbfile *self) +stdapi_ungetc(const int c, gbfile* self) { - return ungetc(c, self->handle.std); + return ungetc(c, self->handle.std); } static void -stdapi_clearerr(gbfile *self) +stdapi_clearerr(gbfile* self) { - clearerr(self->handle.std); + clearerr(self->handle.std); } static int -stdapi_error(gbfile *self) +stdapi_error(gbfile* self) { - return ferror(self->handle.std); + return ferror(self->handle.std); } @@ -339,119 +355,132 @@ stdapi_error(gbfile *self) /* %%% Memory stream (memapi) %%% */ /*******************************************************************************/ -static gbfile * -memapi_open(gbfile *self, const char *mode) +static gbfile* +memapi_open(gbfile* self, const char* mode) { - self->mempos = 0; - self->memsz = 0; - self->handle.mem = NULL; + self->mempos = 0; + self->memsz = 0; + self->handle.mem = NULL; - return self; + return self; } static int -memapi_close(gbfile *self) +memapi_close(gbfile* self) { - if (self->handle.mem) xfree(self->handle.mem); + if (self->handle.mem) { + xfree(self->handle.mem); + } - return 0; + return 0; } static int -memapi_seek(gbfile *self, gbint32 offset, int whence) +memapi_seek(gbfile* self, gbint32 offset, int whence) { - long long pos = (int)self->mempos; + long long pos = (int)self->mempos; - switch (whence) { - case SEEK_CUR: - case SEEK_END: pos = pos + offset; break; - case SEEK_SET: pos = offset; break; - } + switch (whence) { + case SEEK_CUR: + case SEEK_END: + pos = pos + offset; + break; + case SEEK_SET: + pos = offset; + break; + } - if ((pos < 0) || (pos > self->memlen)) return -1; + if ((pos < 0) || (pos > self->memlen)) { + return -1; + } - self->mempos = pos; - return 0; + self->mempos = pos; + return 0; } static gbsize_t -memapi_read(void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) +memapi_read(void* buf, const gbsize_t size, const gbsize_t members, gbfile* self) { - gbsize_t count; - gbsize_t result = (self->memlen - self->mempos) / size; + gbsize_t count; + gbsize_t result = (self->memlen - self->mempos) / size; - if (result > members) result = members; - count = result * size; - if (count) { - memcpy(buf, self->handle.mem + self->mempos, count); - self->mempos += count; - } + if (result > members) { + result = members; + } + count = result * size; + if (count) { + memcpy(buf, self->handle.mem + self->mempos, count); + self->mempos += count; + } - return result; + return result; } static gbsize_t -memapi_write(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) +memapi_write(const void* buf, const gbsize_t size, const gbsize_t members, gbfile* self) { - gbsize_t count; + gbsize_t count; - if ((size == 0) && (members == 0)) { /* truncate stream */ - self->memlen = self->mempos; - return 0; - } + if ((size == 0) && (members == 0)) { /* truncate stream */ + self->memlen = self->mempos; + return 0; + } - count = size * members; + count = size * members; - if (self->mempos + count > self->memsz) { - self->memsz = ((self->mempos + count + 4095) / 4096) * 4096; - self->handle.mem = xrealloc(self->handle.mem, self->memsz); - } - memcpy(self->handle.mem + self->mempos, buf, count); - self->mempos += count; - if (self->mempos > self->memlen) self->memlen = self->mempos; + if (self->mempos + count > self->memsz) { + self->memsz = ((self->mempos + count + 4095) / 4096) * 4096; + self->handle.mem = (unsigned char*) xrealloc(self->handle.mem, self->memsz); + } + memcpy(self->handle.mem + self->mempos, buf, count); + self->mempos += count; + if (self->mempos > self->memlen) { + self->memlen = self->mempos; + } - return members; + return members; } static int -memapi_flush(gbfile *self) +memapi_flush(gbfile* self) { - return 0; + return 0; } static gbsize_t -memapi_tell(gbfile *self) +memapi_tell(gbfile* self) { - return self->mempos; + return self->mempos; } static int -memapi_eof(gbfile *self) +memapi_eof(gbfile* self) { - return (self->mempos == self->memlen); + return (self->mempos == self->memlen); } static int -memapi_ungetc(const int c, gbfile *self) +memapi_ungetc(const int c, gbfile* self) { - if (self->mempos == 0) return EOF; - else { - self->mempos--; - self->handle.mem[self->mempos] = (unsigned char) c; - return c; - } + if (self->mempos == 0) { + return EOF; + } else { + self->mempos--; + self->handle.mem[self->mempos] = (unsigned char) c; + return c; + } } static void -memapi_clearerr(gbfile *self) +memapi_clearerr(gbfile* self) { - return; + return; } static int -memapi_error(gbfile *self) +memapi_error(gbfile* self) { - return 0; + return 0; } @@ -461,125 +490,123 @@ memapi_error(gbfile *self) * gbfopen: (as xfopen) plus the name of the calling GPSBabel module (MYNAME) */ -gbfile * -gbfopen(const char *filename, const char *mode, const char *module) +gbfile* +gbfopen(const char* filename, const char* mode, const char* module) { - gbfile *file; - const char *m; - int len; + gbfile* file; + const char* m; + int len; - file = xcalloc(1, sizeof(*file)); + file = (gbfile*) xcalloc(1, sizeof(*file)); - file->module = xstrdup(module); - file->mode = 'r'; // default - file->binary = (strchr(mode, 'b') != NULL); - file->back = -1; - file->memapi = (filename == NULL); + file->module = xstrdup(module); + file->mode = 'r'; // default + file->binary = (strchr(mode, 'b') != NULL); + file->back = -1; + file->memapi = (filename == NULL); - for (m = mode; *m; m++) { - switch(tolower(*m)) { - case 'r': - file->mode = 'r'; + for (m = mode; *m; m++) { + switch (tolower(*m)) { + case 'r': + file->mode = 'r'; #if !ZLIB_INHIBITED - file->gzapi = 1; /* native or transparent */ + file->gzapi = 1; /* native or transparent */ #endif - break; - case 'w': - file->mode = 'w'; - break; - } - } - - if (file->memapi) { - file->gzapi = 0; - file->name = xstrdup("(Memory stream)"); - - file->fileclearerr = memapi_clearerr; - file->fileclose = memapi_close; - file->fileeof = memapi_eof; - file->fileerror = memapi_error; - file->fileflush = memapi_flush; - file->fileopen = memapi_open; - file->fileread = memapi_read; - file->fileseek = memapi_seek; - file->filetell = memapi_tell; - file->fileungetc = memapi_ungetc; - file->filewrite = memapi_write; - } - else { - file->name = xstrdup(filename); - file->is_pipe = (strcmp(filename, "-") == 0); - - /* Do we have a '.gz' extension in the filename ? */ - len = strlen(file->name); - if ((len > 3) && (case_ignore_strcmp(&file->name[len-3], ".gz") == 0)) { + break; + case 'w': + file->mode = 'w'; + break; + } + } + + if (file->memapi) { + file->gzapi = 0; + file->name = xstrdup("(Memory stream)"); + + file->fileclearerr = memapi_clearerr; + file->fileclose = memapi_close; + file->fileeof = memapi_eof; + file->fileerror = memapi_error; + file->fileflush = memapi_flush; + file->fileopen = memapi_open; + file->fileread = memapi_read; + file->fileseek = memapi_seek; + file->filetell = memapi_tell; + file->fileungetc = memapi_ungetc; + file->filewrite = memapi_write; + } else { + file->name = xstrdup(filename); + file->is_pipe = (strcmp(filename, "-") == 0); + + /* Do we have a '.gz' extension in the filename ? */ + len = strlen(file->name); + if ((len > 3) && (case_ignore_strcmp(&file->name[len-3], ".gz") == 0)) { #if !ZLIB_INHIBITED - /* force gzipped files on output */ - file->gzapi = 1; + /* force gzipped files on output */ + file->gzapi = 1; #else - fatal(NO_ZLIB); + fatal(NO_ZLIB); #endif - } + } - if (file->gzapi) { + if (file->gzapi) { #if !ZLIB_INHIBITED - file->fileclearerr = gzapi_clearerr; - file->fileclose = gzapi_close; - file->fileeof = gzapi_eof; - file->fileerror = gzapi_error; - file->fileflush = gzapi_flush; - file->fileopen = gzapi_open; - file->fileread = gzapi_read; - file->fileseek = gzapi_seek; - file->filetell = gzapi_tell; - file->fileungetc = gzapi_ungetc; - file->filewrite = gzapi_write; + file->fileclearerr = gzapi_clearerr; + file->fileclose = gzapi_close; + file->fileeof = gzapi_eof; + file->fileerror = gzapi_error; + file->fileflush = gzapi_flush; + file->fileopen = gzapi_open; + file->fileread = gzapi_read; + file->fileseek = gzapi_seek; + file->filetell = gzapi_tell; + file->fileungetc = gzapi_ungetc; + file->filewrite = gzapi_write; #else - /* This is the only runtime test we make */ - fatal("%s: Zlib was not included in this build.\n", file->module); + /* This is the only runtime test we make */ + fatal("%s: Zlib was not included in this build.\n", file->module); #endif - } - else { - file->fileclearerr = stdapi_clearerr; - file->fileclose = stdapi_close; - file->fileeof = stdapi_eof; - file->fileerror = stdapi_error; - file->fileflush = stdapi_flush; - file->fileopen = stdapi_open; - file->fileread = stdapi_read; - file->fileseek = stdapi_seek; - file->filetell = stdapi_tell; - file->fileungetc = stdapi_ungetc; - file->filewrite = stdapi_write; - } - } - - file->fileopen(file, mode); + } else { + file->fileclearerr = stdapi_clearerr; + file->fileclose = stdapi_close; + file->fileeof = stdapi_eof; + file->fileerror = stdapi_error; + file->fileflush = stdapi_flush; + file->fileopen = stdapi_open; + file->fileread = stdapi_read; + file->fileseek = stdapi_seek; + file->filetell = stdapi_tell; + file->fileungetc = stdapi_ungetc; + file->filewrite = stdapi_write; + } + } + + file->fileopen(file, mode); #ifdef DEBUG_MEM - file->buffsz = 1; + file->buffsz = 1; #else - file->buffsz = 256; + file->buffsz = 256; #endif - file->buff = xmalloc(file->buffsz); + file->buff = (char*) xmalloc(file->buffsz); - return file; + return file; } /* * gbfopen_be: as gbfopen, but set the BIG-ENDIAN flag */ -gbfile * -gbfopen_be(const char *filename, const char *mode, const char *module) +gbfile* +gbfopen_be(const char* filename, const char* mode, const char* module) { - gbfile *result; + gbfile* result; - result = gbfopen(filename, mode, module); - result->big_endian = 1; + result = gbfopen(filename, mode, module); + result->big_endian = 1; - return result; + return result; } /* @@ -587,16 +614,18 @@ gbfopen_be(const char *filename, const char *mode, const char *module) */ void -gbfclose(gbfile *file) +gbfclose(gbfile* file) { - if (!file) return; + if (!file) { + return; + } - file->fileclose(file); + file->fileclose(file); - xfree(file->name); - xfree(file->module); - xfree(file->buff); - xfree(file); + xfree(file->name); + xfree(file->module); + xfree(file->buff); + xfree(file); } /* @@ -604,46 +633,49 @@ gbfclose(gbfile *file) */ int -gbfgetc(gbfile *file) +gbfgetc(gbfile* file) { - unsigned char c; + unsigned char c; - /* errors are caught in gbfread */ - if (gbfread(&c, 1, 1, file) == 0) { - return EOF; - } - else { - return (unsigned int)c; - } + /* errors are caught in gbfread */ + if (gbfread(&c, 1, 1, file) == 0) { + return EOF; + } else { + return (unsigned int)c; + } } /* * gbfgets: (as fgets) */ -char * -gbfgets(char *buf, int len, gbfile *file) +char* +gbfgets(char* buf, int len, gbfile* file) { - char *result = buf; + char* result = buf; - while (--len > 0) { - int c = gbfgetc(file); + while (--len > 0) { + int c = gbfgetc(file); - if (c == EOF) break; + if (c == EOF) { + break; + } - *(unsigned char *)buf = (unsigned char)c; - buf++; + *(unsigned char*)buf = (unsigned char)c; + buf++; - if (c == '\r') { - c = gbfgetc(file); - if ((c != '\n') && (c != EOF)) gbfungetc(c, file); - break; - } - else if (c == '\n') - break; - } - *buf = '\0'; - return (*result != '\0') ? result : NULL; + if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) { + gbfungetc(c, file); + } + break; + } else if (c == '\n') { + break; + } + } + *buf = '\0'; + return (*result != '\0') ? result : NULL; } /* @@ -651,50 +683,54 @@ gbfgets(char *buf, int len, gbfile *file) */ gbsize_t -gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) +gbfread(void* buf, const gbsize_t size, const gbsize_t members, gbfile* file) { - if ((size == 0) || (members == 0)) return 0; - return file->fileread(buf, size, members, file); + if ((size == 0) || (members == 0)) { + return 0; + } + return file->fileread(buf, size, members, file); } /* * gbvfprintf: (as vfprintf) */ -int gbvfprintf(gbfile *file, const char *format, va_list ap) +int gbvfprintf(gbfile* file, const char* format, va_list ap) { - int len; + int len; - for (;;) { - va_list args; + for (;;) { + va_list args; - va_copy(args, ap); - len = vsnprintf(file->buff, file->buffsz, format, args); - va_end(args); + va_copy(args, ap); + len = vsnprintf(file->buff, file->buffsz, format, args); + va_end(args); - /* Unambiguous Success */ - if ((len > -1) && (len < file->buffsz)) - break; + /* Unambiguous Success */ + if ((len > -1) && (len < file->buffsz)) { + break; + } - /* First case: C99 behaviour. Len is correctly sized. - * add space for null terminator. Next time through the - * loop we're guaranteed success. - * - * Second case: SUS (and Windows) behaviour. We know it - * doesn't fit, but we don't know how big it has to be. -` * double it and try again. We'll loop until we succeed. - * - * Since we keep the I/O buffer in the file handle, we - * quickly reach a steady state on the size of these buffers. - */ - if (len > -1) - file->buffsz = len + 1; - else - file->buffsz *= 2; + /* First case: C99 behaviour. Len is correctly sized. + * add space for null terminator. Next time through the + * loop we're guaranteed success. + * + * Second case: SUS (and Windows) behaviour. We know it + * doesn't fit, but we don't know how big it has to be. + ` * double it and try again. We'll loop until we succeed. + * + * Since we keep the I/O buffer in the file handle, we + * quickly reach a steady state on the size of these buffers. + */ + if (len > -1) { + file->buffsz = len + 1; + } else { + file->buffsz *= 2; + } - file->buff = xrealloc(file->buff, file->buffsz); - } - return gbfwrite(file->buff, 1, len, file); + file->buff = (char*) xrealloc(file->buff, file->buffsz); + } + return gbfwrite(file->buff, 1, len, file); } /* @@ -702,16 +738,16 @@ int gbvfprintf(gbfile *file, const char *format, va_list ap) */ int -gbfprintf(gbfile *file, const char *format, ...) +gbfprintf(gbfile* file, const char* format, ...) { - va_list args; - int result; + va_list args; + int result; - va_start(args, format); - result = gbvfprintf(file, format, args); - va_end(args); + va_start(args, format); + result = gbvfprintf(file, format, args); + va_end(args); - return result; + return result; } /* @@ -719,13 +755,13 @@ gbfprintf(gbfile *file, const char *format, ...) */ int -gbfputc(int c, gbfile *file) +gbfputc(int c, gbfile* file) { - unsigned char temp = (unsigned int) c; + unsigned char temp = (unsigned int) c; - gbfwrite(&temp, 1, 1, file); + gbfwrite(&temp, 1, 1, file); - return c; + return c; } /* @@ -733,9 +769,9 @@ gbfputc(int c, gbfile *file) */ int -gbfputs(const char *s, gbfile *file) +gbfputs(const char* s, gbfile* file) { - return gbfwrite(s, 1, strlen(s), file); + return gbfwrite(s, 1, strlen(s), file); } /* @@ -743,20 +779,20 @@ gbfputs(const char *s, gbfile *file) */ int -gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) +gbfwrite(const void* buf, const gbsize_t size, const gbsize_t members, gbfile* file) { - int result; + int result; - result = file->filewrite(buf, size, members, file); - if (result != members) { - fatal("%s: Could not write %lld bytes to %s (result %d)!\n", - file->module, - (long long int) (members - result) * size, - file->name, - result); - } + result = file->filewrite(buf, size, members, file); + if (result != members) { + fatal("%s: Could not write %lld bytes to %s (result %d)!\n", + file->module, + (long long int)(members - result) * size, + file->name, + result); + } - return result; + return result; } /* @@ -764,9 +800,9 @@ gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *f */ int -gbfflush(gbfile *file) +gbfflush(gbfile* file) { - return file->fileflush(file); + return file->fileflush(file); } /* @@ -774,9 +810,9 @@ gbfflush(gbfile *file) */ void -gbfclearerr(gbfile *file) +gbfclearerr(gbfile* file) { - file->fileclearerr(file); + file->fileclearerr(file); } /* @@ -784,9 +820,9 @@ gbfclearerr(gbfile *file) */ int -gbferror(gbfile *file) +gbferror(gbfile* file) { - return file->fileerror(file); + return file->fileerror(file); } /* @@ -794,10 +830,10 @@ gbferror(gbfile *file) */ void -gbfrewind(gbfile *file) +gbfrewind(gbfile* file) { - (void) gbfseek(file, 0, SEEK_SET); - gbfclearerr(file); + (void) gbfseek(file, 0, SEEK_SET); + gbfclearerr(file); } /* @@ -805,9 +841,9 @@ gbfrewind(gbfile *file) */ int -gbfseek(gbfile *file, gbint32 offset, int whence) +gbfseek(gbfile* file, gbint32 offset, int whence) { - return file->fileseek(file, offset, whence); + return file->fileseek(file, offset, whence); } /* @@ -815,13 +851,13 @@ gbfseek(gbfile *file, gbint32 offset, int whence) */ gbsize_t -gbftell(gbfile *file) +gbftell(gbfile* file) { - gbsize_t result = file->filetell(file); - if ((signed) result == -1) - fatal("%s: Could not determine position of file '%s'!\n", - file->module, file->name); - return result; + gbsize_t result = file->filetell(file); + if ((signed) result == -1) + fatal("%s: Could not determine position of file '%s'!\n", + file->module, file->name); + return result; } /* @@ -829,9 +865,9 @@ gbftell(gbfile *file) */ int -gbfeof(gbfile *file) +gbfeof(gbfile* file) { - return file->fileeof(file); + return file->fileeof(file); } /* @@ -839,9 +875,9 @@ gbfeof(gbfile *file) */ int -gbfungetc(const int c, gbfile *file) +gbfungetc(const int c, gbfile* file) { - return file->fileungetc(c, file); + return file->fileungetc(c, file); } /* GPSBabel 'file' enhancements */ @@ -851,17 +887,18 @@ gbfungetc(const int c, gbfile *file) */ gbint32 -gbfgetint32(gbfile *file) +gbfgetint32(gbfile* file) { - char buf[4]; + char buf[4]; - is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), - "%s: Unexpected end of file (%s)!\n", file->module, file->name); + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); - if (file->big_endian) - return be_read32(buf); - else - return le_read32(buf); + if (file->big_endian) { + return be_read32(buf); + } else { + return le_read32(buf); + } } /* @@ -869,17 +906,18 @@ gbfgetint32(gbfile *file) */ gbint16 -gbfgetint16(gbfile *file) +gbfgetint16(gbfile* file) { - char buf[2]; + char buf[2]; - is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), - "%s: Unexpected end of file (%s)!\n", file->module, file->name); + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); - if (file->big_endian) - return be_read16(buf); - else - return le_read16(buf); + if (file->big_endian) { + return be_read16(buf); + } else { + return le_read16(buf); + } } /* @@ -887,14 +925,14 @@ gbfgetint16(gbfile *file) */ double -gbfgetdbl(gbfile *file) +gbfgetdbl(gbfile* file) { - char buf[8]; + char buf[8]; - is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), - "%s: Unexpected end of file (%s)!\n", file->module, file->name); + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); - return endian_read_double(buf, ! file->big_endian); + return endian_read_double(buf, ! file->big_endian); } /* @@ -902,14 +940,14 @@ gbfgetdbl(gbfile *file) */ float -gbfgetflt(gbfile *file) +gbfgetflt(gbfile* file) { - char buf[4]; + char buf[4]; - is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), - "%s: Unexpected end of file (%s)!\n", file->module, file->name); + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); - return endian_read_float(buf, ! file->big_endian); + return endian_read_float(buf, ! file->big_endian); } /* @@ -917,32 +955,35 @@ gbfgetflt(gbfile *file) * The result is a temporary allocated entity: use it or free it! */ -char * -gbfgetcstr(gbfile *file) +char* +gbfgetcstr(gbfile* file) { - char *result; - int len = 0; - char *str = file->buff; + char* result; + int len = 0; + char* str = file->buff; - for (;;) { - int c = gbfgetc(file); + for (;;) { + int c = gbfgetc(file); - if ((c == 0) || (c == EOF)) break; + if ((c == 0) || (c == EOF)) { + break; + } - if (len == file->buffsz) { - file->buffsz += 64; - str = file->buff = xrealloc(file->buff, file->buffsz + 1); - } - str[len] = c; - len++; - } + if (len == file->buffsz) { + file->buffsz += 64; + str = file->buff = (char*) xrealloc(file->buff, file->buffsz + 1); + } + str[len] = c; + len++; + } - result = (char *) xmalloc(len + 1); - if (len > 0) - memcpy(result, str, len); - result[len] = '\0'; + result = (char*) xmalloc(len + 1); + if (len > 0) { + memcpy(result, str, len); + } + result[len] = '\0'; - return result; + return result; } /* @@ -950,70 +991,84 @@ gbfgetcstr(gbfile *file) * The result is a temporary allocated entity: use it or free it! */ -char * -gbfgetpstr(gbfile *file) -{ - int len; - char *result; - - len = gbfgetc(file); - result = xmalloc(len + 1); - if (len > 0) { - gbfread(result, 1, len, file); - } - result[len] = '\0'; - - return result; -} - -static char * -gbfgetucs2str(gbfile *file) -{ - int len = 0; - char *result = file->buff; - - for (;;) { - char buff[8]; - int clen; - int c0, c1; - - c0 = gbfgetc(file); - if ((c0 == EOF) && (len == 0)) return NULL; - c1 = gbfgetc(file); - if ((c1 == EOF) && (len == 0)) return NULL; - - if (file->big_endian) c0 = c1 | (c0 << 8); - else c0 = c0 | (c1 << 8); - - if (c0 == '\r') { - - c0 = gbfgetc(file); - if ((c0 == EOF) && (len == 0)) return NULL; - c1 = gbfgetc(file); - if ((c1 == EOF) && (len == 0)) return NULL; - - if (file->big_endian) c0 = c1 | (c0 << 8); - else c0 = c0 | (c1 << 8); - - if (c0 != '\n') - fatal("%s: Invalid unicode (UCS-2/%s endian) line break!\n", - file->module, - file->big_endian ? "Big" : "Little"); - break; - } - - clen = cet_ucs4_to_utf8(buff, sizeof(buff), c0); - - if (len+clen >= file->buffsz) { - file->buffsz += 64; - result = file->buff = xrealloc(file->buff, file->buffsz + 1); - } - memcpy(&result[len], buff, clen); - len += clen; - } - result[len] = '\0'; // terminate resulting string - - return result; +char* +gbfgetpstr(gbfile* file) +{ + int len; + char* result; + + len = gbfgetc(file); + result = (char*) xmalloc(len + 1); + if (len > 0) { + gbfread(result, 1, len, file); + } + result[len] = '\0'; + + return result; +} + +static char* +gbfgetucs2str(gbfile* file) +{ + int len = 0; + char* result = file->buff; + + for (;;) { + char buff[8]; + int clen; + int c0, c1; + + c0 = gbfgetc(file); + if ((c0 == EOF) && (len == 0)) { + return NULL; + } + c1 = gbfgetc(file); + if ((c1 == EOF) && (len == 0)) { + return NULL; + } + + if (file->big_endian) { + c0 = c1 | (c0 << 8); + } else { + c0 = c0 | (c1 << 8); + } + + if (c0 == '\r') { + + c0 = gbfgetc(file); + if ((c0 == EOF) && (len == 0)) { + return NULL; + } + c1 = gbfgetc(file); + if ((c1 == EOF) && (len == 0)) { + return NULL; + } + + if (file->big_endian) { + c0 = c1 | (c0 << 8); + } else { + c0 = c0 | (c1 << 8); + } + + if (c0 != '\n') + fatal("%s: Invalid unicode (UCS-2/%s endian) line break!\n", + file->module, + file->big_endian ? "Big" : "Little"); + break; + } + + clen = cet_ucs4_to_utf8(buff, sizeof(buff), c0); + + if (len+clen >= file->buffsz) { + file->buffsz += 64; + result = file->buff = (char*) xrealloc(file->buff, file->buffsz + 1); + } + memcpy(&result[len], buff, clen); + len += clen; + } + result[len] = '\0'; // terminate resulting string + + return result; } /* @@ -1021,63 +1076,63 @@ gbfgetucs2str(gbfile *file) * except xfree and free you can do all possible things with the result */ -char * -gbfgetstr(gbfile *file) -{ - int len = 0; - char *result = file->buff; - - if (file->unicode) return gbfgetucs2str(file); - - for (;;) { - int c = gbfgetc(file); - - if ((c == EOF) || (c == 0x1A)) { - if (len == 0) { - return NULL; - } - break; - } - else if (c == '\r') { - c = gbfgetc(file); - if ((c != '\n') && (c != EOF)) - gbfungetc(c, file); - break; - } - else if (c == '\n') { - break; - } - else if (((c == 0xFE) || (c == 0xFF)) && (! file->unicode_checked)) { - int cx; - int c1 = gbfgetc(file); - if (c1 != EOF) { - cx = c | (c1 << 8); - if (cx == 0xFEFF) { - file->unicode = 1; - file->big_endian = 0; - return gbfgetucs2str(file); - } - else if (cx == 0xFFFE) { - file->unicode = 1; - file->big_endian = 1; - return gbfgetucs2str(file); - } - else gbfungetc(c1, file); - } - } - - file->unicode_checked = 1; - - if ((len + 1) == file->buffsz) { - file->buffsz += 64; - result = file->buff = xrealloc(file->buff, file->buffsz + 1); - } - result[len] = (char)c; - len++; - } - result[len] = '\0'; // terminate resulting string - - return result; +char* +gbfgetstr(gbfile* file) +{ + int len = 0; + char* result = file->buff; + + if (file->unicode) { + return gbfgetucs2str(file); + } + + for (;;) { + int c = gbfgetc(file); + + if ((c == EOF) || (c == 0x1A)) { + if (len == 0) { + return NULL; + } + break; + } else if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) { + gbfungetc(c, file); + } + break; + } else if (c == '\n') { + break; + } else if (((c == 0xFE) || (c == 0xFF)) && (! file->unicode_checked)) { + int cx; + int c1 = gbfgetc(file); + if (c1 != EOF) { + cx = c | (c1 << 8); + if (cx == 0xFEFF) { + file->unicode = 1; + file->big_endian = 0; + return gbfgetucs2str(file); + } else if (cx == 0xFFFE) { + file->unicode = 1; + file->big_endian = 1; + return gbfgetucs2str(file); + } else { + gbfungetc(c1, file); + } + } + } + + file->unicode_checked = 1; + + if ((len + 1) == file->buffsz) { + file->buffsz += 64; + result = file->buff = (char*) xrealloc(file->buff, file->buffsz + 1); + } + result[len] = (char)c; + len++; + } + result[len] = '\0'; // terminate resulting string + + return result; } /* @@ -1085,15 +1140,16 @@ gbfgetstr(gbfile *file) */ int -gbfputint16(const gbint16 i, gbfile *file) +gbfputint16(const gbint16 i, gbfile* file) { - char buf[2]; + char buf[2]; - if (file->big_endian) - be_write16(buf, i); - else - le_write16(buf, i); - return gbfwrite(buf, 1, sizeof(buf), file); + if (file->big_endian) { + be_write16(buf, i); + } else { + le_write16(buf, i); + } + return gbfwrite(buf, 1, sizeof(buf), file); } /* @@ -1101,15 +1157,16 @@ gbfputint16(const gbint16 i, gbfile *file) */ int -gbfputint32(const gbint32 i, gbfile *file) +gbfputint32(const gbint32 i, gbfile* file) { - char buf[4]; + char buf[4]; - if (file->big_endian) - be_write32(buf, i); - else - le_write32(buf, i); - return gbfwrite(buf, 1, sizeof(buf), file); + if (file->big_endian) { + be_write32(buf, i); + } else { + le_write32(buf, i); + } + return gbfwrite(buf, 1, sizeof(buf), file); } /* @@ -1117,12 +1174,12 @@ gbfputint32(const gbint32 i, gbfile *file) */ int -gbfputdbl(const double d, gbfile *file) +gbfputdbl(const double d, gbfile* file) { - char buf[8]; + char buf[8]; - endian_write_double(buf, d, ! file->big_endian); - return gbfwrite(buf, 1, sizeof(buf), file); + endian_write_double(buf, d, ! file->big_endian); + return gbfwrite(buf, 1, sizeof(buf), file); } /* @@ -1130,12 +1187,12 @@ gbfputdbl(const double d, gbfile *file) */ int -gbfputflt(const float f, gbfile *file) +gbfputflt(const float f, gbfile* file) { - char buf[4]; + char buf[4]; - endian_write_float(buf, f, ! file->big_endian); - return gbfwrite(buf, 1, sizeof(buf), file); + endian_write_float(buf, f, ! file->big_endian); + return gbfwrite(buf, 1, sizeof(buf), file); } /* @@ -1144,17 +1201,17 @@ gbfputflt(const float f, gbfile *file) */ int -gbfputcstr(const char *s, gbfile *file) +gbfputcstr(const char* s, gbfile* file) { - int len; + int len; - len = (s == NULL) ? 0 : strlen(s); - if (len > 0) { - return gbfwrite(s, 1, len + 1, file); - } else { - gbfputc(0, file); - return 1; - } + len = (s == NULL) ? 0 : strlen(s); + if (len > 0) { + return gbfwrite(s, 1, len + 1, file); + } else { + gbfputc(0, file); + return 1; + } } /* @@ -1163,37 +1220,40 @@ gbfputcstr(const char *s, gbfile *file) */ int -gbfputpstr(const char *s, gbfile *file) +gbfputpstr(const char* s, gbfile* file) { - int len; + int len; - len = (s == NULL) ? 0 : strlen(s); - if (len > 255) len = 255; /* the maximum size of a standard pascal string */ - gbfputc(len, file); - if (len > 0) { - gbfwrite(s, 1, len, file); - } - return (len + 1); + len = (s == NULL) ? 0 : strlen(s); + if (len > 255) { + len = 255; /* the maximum size of a standard pascal string */ + } + gbfputc(len, file); + if (len > 0) { + gbfwrite(s, 1, len, file); + } + return (len + 1); } /* Much more higher level functions */ gbsize_t -gbfcopyfrom(gbfile *file, gbfile *src, gbsize_t count) -{ - char buf[1024]; - gbsize_t copied = 0; - - while (count) { - gbsize_t n = gbfread(buf, 1, (count < sizeof(buf)) ? count : sizeof(buf), src); - if (n > 0) { - gbfwrite(buf, 1, n, file); - count -= n; - copied += n; - } - else break; - } - return copied; +gbfcopyfrom(gbfile* file, gbfile* src, gbsize_t count) +{ + char buf[1024]; + gbsize_t copied = 0; + + while (count) { + gbsize_t n = gbfread(buf, 1, (count < sizeof(buf)) ? count : sizeof(buf), src); + if (n > 0) { + gbfwrite(buf, 1, n, file); + count -= n; + copied += n; + } else { + break; + } + } + return copied; } diff --git a/gpsbabel/gbfile.h b/gpsbabel/gbfile.h index 432c44e6e..4bb73c45e 100644 --- a/gpsbabel/gbfile.h +++ b/gpsbabel/gbfile.h @@ -32,103 +32,103 @@ struct gbfile_s; typedef struct gbfile_s gbfile; -typedef void (*gbfclearerr_cb) (gbfile *self); -typedef int (*gbfclose_cb) (gbfile *self); -typedef int (*gbfeof_cb) (gbfile *self); -typedef int (*gbferror_cb) (gbfile *self); -typedef int (*gbfflush_cb) (gbfile *self); -typedef gbfile* (*gbfopen_cb) (gbfile *self, const char *mode); -typedef gbsize_t (*gbfread_cb) (void *buf, const gbsize_t size, const gbsize_t members, gbfile *self); -typedef int (*gbfseek_cb) (gbfile *self, gbint32 offset, int whence); -typedef gbsize_t (*gbftell_cb) (gbfile *self); -typedef gbsize_t (*gbfwrite_cb) (const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self); -typedef int (*gbfungetc_cb) (const int c, gbfile *self); +typedef void (*gbfclearerr_cb)(gbfile* self); +typedef int (*gbfclose_cb)(gbfile* self); +typedef int (*gbfeof_cb)(gbfile* self); +typedef int (*gbferror_cb)(gbfile* self); +typedef int (*gbfflush_cb)(gbfile* self); +typedef gbfile* (*gbfopen_cb)(gbfile* self, const char* mode); +typedef gbsize_t (*gbfread_cb)(void* buf, const gbsize_t size, const gbsize_t members, gbfile* self); +typedef int (*gbfseek_cb)(gbfile* self, gbint32 offset, int whence); +typedef gbsize_t (*gbftell_cb)(gbfile* self); +typedef gbsize_t (*gbfwrite_cb)(const void* buf, const gbsize_t size, const gbsize_t members, gbfile* self); +typedef int (*gbfungetc_cb)(const int c, gbfile* self); typedef struct gbfile_s { #ifdef DEBUG_MEM - void *dummy; /* ZERO pointer for stdio oop's */ + void* dummy; /* ZERO pointer for stdio oop's */ #endif - union { - FILE *std; - unsigned char *mem; + union { + FILE* std; + unsigned char* mem; #if !ZLIB_INHIBITED - gzFile *gz; + gzFile* gz; #endif - } handle; - char *name; - char *module; - char *buff; /* static growing buffer, primary used by gbprintf */ - int buffsz; - char mode; - int back; - gbsize_t mempos; /* curr. position in memory */ - gbsize_t memlen; /* max. number of written bytes to memory */ - gbsize_t memsz; /* curr. size of allocated memory */ - unsigned char big_endian:1; - unsigned char binary:1; - unsigned char gzapi:1; - unsigned char memapi:1; - unsigned char unicode:1; - unsigned char unicode_checked:1; - unsigned char is_pipe:1; - gbfclearerr_cb fileclearerr; - gbfclose_cb fileclose; - gbfeof_cb fileeof; - gbferror_cb fileerror; - gbfflush_cb fileflush; - gbfopen_cb fileopen; - gbfread_cb fileread; - gbfseek_cb fileseek; - gbftell_cb filetell; - gbfungetc_cb fileungetc; - gbfwrite_cb filewrite; + } handle; + char* name; + char* module; + char* buff; /* static growing buffer, primary used by gbprintf */ + int buffsz; + char mode; + int back; + gbsize_t mempos; /* curr. position in memory */ + gbsize_t memlen; /* max. number of written bytes to memory */ + gbsize_t memsz; /* curr. size of allocated memory */ + unsigned char big_endian:1; + unsigned char binary:1; + unsigned char gzapi:1; + unsigned char memapi:1; + unsigned char unicode:1; + unsigned char unicode_checked:1; + unsigned char is_pipe:1; + gbfclearerr_cb fileclearerr; + gbfclose_cb fileclose; + gbfeof_cb fileeof; + gbferror_cb fileerror; + gbfflush_cb fileflush; + gbfopen_cb fileopen; + gbfread_cb fileread; + gbfseek_cb fileseek; + gbftell_cb filetell; + gbfungetc_cb fileungetc; + gbfwrite_cb filewrite; } gbfile_t; -gbfile *gbfopen(const char *filename, const char *mode, const char *module); -gbfile *gbfopen_be(const char *filename, const char *mode, const char *module); +gbfile* gbfopen(const char* filename, const char* mode, const char* module); +gbfile* gbfopen_be(const char* filename, const char* mode, const char* module); #define gbfopen_le gbfopen -void gbfclose(gbfile *file); - -gbsize_t gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file); -int gbfgetc(gbfile *file); -char *gbfgets(char *buf, int len, gbfile *file); - -int gbvfprintf(gbfile *file, const char *format, va_list ap); -int gbfprintf(gbfile *file, const char *format, ...); -int gbfputc(int c, gbfile *file); -int gbfputs(const char *s, gbfile *file); -int gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file); -int gbfflush(gbfile *file); - -void gbfclearerr(gbfile *file); -int gbferror(gbfile *file); -void gbfrewind(gbfile *file); -int gbfseek(gbfile *file, gbint32 offset, int whence); -gbsize_t gbftell(gbfile *file); -int gbfeof(gbfile *file); -int gbfungetc(const int c, gbfile *file); - -gbint32 gbfgetint32(gbfile *file); +void gbfclose(gbfile* file); + +gbsize_t gbfread(void* buf, const gbsize_t size, const gbsize_t members, gbfile* file); +int gbfgetc(gbfile* file); +char* gbfgets(char* buf, int len, gbfile* file); + +int gbvfprintf(gbfile* file, const char* format, va_list ap); +int gbfprintf(gbfile* file, const char* format, ...); +int gbfputc(int c, gbfile* file); +int gbfputs(const char* s, gbfile* file); +int gbfwrite(const void* buf, const gbsize_t size, const gbsize_t members, gbfile* file); +int gbfflush(gbfile* file); + +void gbfclearerr(gbfile* file); +int gbferror(gbfile* file); +void gbfrewind(gbfile* file); +int gbfseek(gbfile* file, gbint32 offset, int whence); +gbsize_t gbftell(gbfile* file); +int gbfeof(gbfile* file); +int gbfungetc(const int c, gbfile* file); + +gbint32 gbfgetint32(gbfile* file); #define gbfgetuint32 (gbuint32)gbfgetint32 -gbint16 gbfgetint16(gbfile *file); +gbint16 gbfgetint16(gbfile* file); #define gbfgetuint16 (gbuint16)gbfgetint16 -double gbfgetdbl(gbfile *file); // read a double value -float gbfgetflt(gbfile *file); // read a float value -char *gbfgetstr(gbfile *file); // read until any type of line-breaks or EOF -char *gbfgetpstr(gbfile *file); // read a pascal string -char *gbfgetcstr(gbfile *file); // read a null terminated string +double gbfgetdbl(gbfile* file); // read a double value +float gbfgetflt(gbfile* file); // read a float value +char* gbfgetstr(gbfile* file); // read until any type of line-breaks or EOF +char* gbfgetpstr(gbfile* file); // read a pascal string +char* gbfgetcstr(gbfile* file); // read a null terminated string -int gbfputint16(const gbint16 i, gbfile *file); +int gbfputint16(const gbint16 i, gbfile* file); #define gbfputuint16(a,b) gbfputint16((gbuint16)(a),(b)) -int gbfputint32(const gbint32 i, gbfile *file); +int gbfputint32(const gbint32 i, gbfile* file); #define gbfputuint32(a,b) gbfputint32((gbuint32)(a),(b)) -int gbfputdbl(const double d, gbfile *file); // write a double value -int gbfputflt(const float f, gbfile *file); // write a float value -int gbfputcstr(const char *s, gbfile *file); // write string including '\0' -int gbfputpstr(const char *s, gbfile *file); // write as pascal string +int gbfputdbl(const double d, gbfile* file); // write a double value +int gbfputflt(const float f, gbfile* file); // write a float value +int gbfputcstr(const char* s, gbfile* file); // write string including '\0' +int gbfputpstr(const char* s, gbfile* file); // write as pascal string -gbsize_t gbfcopyfrom(gbfile *file, gbfile *src, gbsize_t count); +gbsize_t gbfcopyfrom(gbfile* file, gbfile* src, gbsize_t count); #endif diff --git a/gpsbabel/gbser.c b/gpsbabel/gbser.c index a43777c5a..9cb2fc9a9 100644 --- a/gpsbabel/gbser.c +++ b/gpsbabel/gbser.c @@ -1,6 +1,6 @@ /* Serial interface - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -26,32 +26,38 @@ #include #include -void gbser__db(int l, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - vprintf(msg, ap); - } - va_end(ap); +void gbser__db(int l, const char* msg, ...) +{ + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); } /* Set the serial port speed. */ -int gbser_set_speed(void *handle, unsigned speed) { - return gbser_set_port(handle, speed, 8, 0, 1); +int gbser_set_speed(void* handle, unsigned speed) +{ + return gbser_set_port(handle, speed, 8, 0, 1); } -static int parity_letter(char c) { - switch (c) { - case 'N': case 'n': - return 0; - case 'O': case 'o': - return 1; - case 'E': case 'e': - return 2; - default: - return -1; - } +static int parity_letter(char c) +{ + switch (c) { + case 'N': + case 'n': + return 0; + case 'O': + case 'o': + return 1; + case 'E': + case 'e': + return 2; + default: + return -1; + } } /* Set the serial port up by parsing the supplied parameter string. @@ -59,123 +65,141 @@ static int parity_letter(char c) { * insensitive, spaces are allowed around the commas and omitted * trailing fields will default to '8', 'N' and '1' */ -int gbser_setup(void *handle, const char *spec) { - unsigned arg[] = { 4800, 8, 0, 1 }; - int ap; - - for (ap = 0; ap < sizeof(arg) / sizeof(arg[0]); ap++) { - unsigned t = 0; - int pl; - while (isspace(*spec)) { spec++; } - /* Allow 'N', 'O' or 'E' as the parity spec */ - if (ap == 2 && (pl = parity_letter(*spec), pl >= 0)) { - t = pl; - spec++; - } else { - if (!isdigit(*spec)) { break; } - while (isdigit(*spec)) { t = t * 10 + *spec++ - '0'; } - } - arg[ap] = t; - while (isspace(*spec)) { spec++; } - if (*spec != ',') { break; } - spec++; +int gbser_setup(void* handle, const char* spec) +{ + unsigned arg[] = { 4800, 8, 0, 1 }; + int ap; + + for (ap = 0; ap < sizeof(arg) / sizeof(arg[0]); ap++) { + unsigned t = 0; + int pl; + while (isspace(*spec)) { + spec++; + } + /* Allow 'N', 'O' or 'E' as the parity spec */ + if (ap == 2 && (pl = parity_letter(*spec), pl >= 0)) { + t = pl; + spec++; + } else { + if (!isdigit(*spec)) { + break; + } + while (isdigit(*spec)) { + t = t * 10 + *spec++ - '0'; + } + } + arg[ap] = t; + while (isspace(*spec)) { + spec++; } - - if (*spec != '\0') { - return gbser_ERROR; + if (*spec != ',') { + break; } - - return gbser_set_port(handle, arg[0], arg[1], arg[2], arg[3]); + spec++; + } + + if (*spec != '\0') { + return gbser_ERROR; + } + + return gbser_set_port(handle, arg[0], arg[1], arg[2], arg[3]); } /* Return true if there are characters available on the serial port */ -int gbser_avail(void *handle) { - return gbser__fill_buffer(handle, 1, NULL); +int gbser_avail(void* handle) +{ + return gbser__fill_buffer(handle, 1, NULL); } /* Read as many bytes as are available without blocking. At most |len| * bytes will be read. Returns the number of bytes read or gbser_ERROR if an * error occurs. */ -int gbser_read(void *handle, void *buf, unsigned len) { - int got = 0; - - while (len > 0) { - int rc = gbser__fill_buffer(handle, len, NULL); - if (rc < 0) { - /* error */ - return rc; - } else if (rc == 0) { - /* nothing available */ - break; - } - got += gbser__read_buffer(handle, &buf, &len); - } - - return got; +int gbser_read(void* handle, void* buf, unsigned len) +{ + int got = 0; + + while (len > 0) { + int rc = gbser__fill_buffer(handle, len, NULL); + if (rc < 0) { + /* error */ + return rc; + } else if (rc == 0) { + /* nothing available */ + break; + } + got += gbser__read_buffer(handle, &buf, &len); + } + + return got; } /* Read the specified number of bytes. Block until the requested number * of bytes have been read or the timeout (in ms) is exceeded. */ -int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms) { - int got = 0; - - while (len > 0 && ms != 0) { - int rc; - if (rc = gbser__fill_buffer(handle, len, &ms), rc < 0) { - return rc; - } - got += gbser__read_buffer(handle, &buf, &len); - } - - return got; +int gbser_read_wait(void* handle, void* buf, unsigned len, unsigned ms) +{ + int got = 0; + + while (len > 0 && ms != 0) { + int rc; + if (rc = gbser__fill_buffer(handle, len, &ms), rc < 0) { + return rc; + } + got += gbser__read_buffer(handle, &buf, &len); + } + + return got; } /* Read a single character from the port, returning immediately if * none are available. */ -int gbser_readc(void *handle) { - unsigned char buf; - int rc; - - rc = gbser_read(handle, &buf, 1); - if (rc > 0) { - return buf; - } else if (rc == 0) { - return gbser_NOTHING; - } else { - return gbser_ERROR; - } +int gbser_readc(void* handle) +{ + unsigned char buf; + int rc; + + rc = gbser_read(handle, &buf, 1); + if (rc > 0) { + return buf; + } else if (rc == 0) { + return gbser_NOTHING; + } else { + return gbser_ERROR; + } } /* Read a single character from the port, waiting up to |ms| * milliseconds for a character to be available. */ -int gbser_readc_wait(void *handle, unsigned ms) { - unsigned char buf; - int rc; - - rc = gbser_read_wait(handle, &buf, 1, ms); - if (rc > 0) { - return buf; - } else if (rc == 0) { - return gbser_NOTHING; - } else { - return gbser_ERROR; - } +int gbser_readc_wait(void* handle, unsigned ms) +{ + unsigned char buf; + int rc; + + rc = gbser_read_wait(handle, &buf, 1, ms); + if (rc > 0) { + return buf; + } else if (rc == 0) { + return gbser_NOTHING; + } else { + return gbser_ERROR; + } } /* Write a null terminated string in |str| to the serial * port. */ -int gbser_print(void *handle, const char *str) { - return gbser_write(handle, str, (unsigned) strlen(str)); +int gbser_print(void* handle, const char* str) +{ + return gbser_write(handle, str, (unsigned) strlen(str)); } /* Write a single character to the serial port. - */ -int gbser_writec(void *handle, int c) { - return gbser_write(handle, &c, 1); + */ +int gbser_writec(void* handle, int c) +{ + return gbser_write(handle, &c, 1); } diff --git a/gpsbabel/gbser.h b/gpsbabel/gbser.h index 97e871db7..55e53eb23 100644 --- a/gpsbabel/gbser.h +++ b/gpsbabel/gbser.h @@ -38,91 +38,91 @@ * ('com1:') are translated into the equivalent name required by * WIN32 */ -void *gbser_init(const char *port_name); +void* gbser_init(const char* port_name); /* Close a serial port */ -void gbser_deinit(void *handle); +void gbser_deinit(void* handle); /* Set the serial port speed. */ -int gbser_set_speed(void *handle, unsigned speed); +int gbser_set_speed(void* handle, unsigned speed); /* Set the serial port speed, start, parity and stop bits */ -int gbser_set_port(void *handle, unsigned speed, - unsigned bits, - unsigned parity, - unsigned stop); +int gbser_set_port(void* handle, unsigned speed, + unsigned bits, + unsigned parity, + unsigned stop); /* Set the serial port up by parsing the supplied parameter string. * Valid parameter strings look like '4800,8,N,1'. Parsing is case- * insensitive, spaces are allowed around the commas and omitted * trailing fields will default to '8', 'N' and '1' */ -int gbser_setup(void *handle, const char *spec); +int gbser_setup(void* handle, const char* spec); /* Return true if there are characters available on the serial port */ -int gbser_avail(void *handle); +int gbser_avail(void* handle); /* Read as many bytes as are available without blocking. At most |len| * bytes will be read. Returns the number of bytes read or gbser_ERROR if an * error occurs. */ -int gbser_read(void *handle, void *buf, unsigned len); +int gbser_read(void* handle, void* buf, unsigned len); /* Read the specified number of bytes. Block until the requested number * of bytes have been read or the timeout (in ms) is exceeded. */ -int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms); +int gbser_read_wait(void* handle, void* buf, unsigned len, unsigned ms); /* Read from the serial port until the specified |eol| character is * found. Any character matching |discard| will be discarded. To * read lines terminated by 0x0A0x0D discarding linefeeds use * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); */ -int gbser_read_line(void *handle, void *buf, +int gbser_read_line(void* handle, void* buf, unsigned len, unsigned ms, int eol, int discard); /* Read a single character from the port, returning immediately if * none are available. TODO: Define return values */ -int gbser_readc(void *handle); +int gbser_readc(void* handle); /* Read a single character from the port, waiting up to |ms| * milliseconds for a character to be available. */ -int gbser_readc_wait(void *handle, unsigned ms); +int gbser_readc_wait(void* handle, unsigned ms); /* Discard any pending input on the serial port. - */ -int gbser_flush(void *handle); + */ +int gbser_flush(void* handle); /* Write |len| bytes from |buf| to the serial port. */ -int gbser_write(void *handle, const void *buf, unsigned len); +int gbser_write(void* handle, const void* buf, unsigned len); /* Write a null terminated string in |str| to the serial * port. */ -int gbser_print(void *handle, const char *str); +int gbser_print(void* handle, const char* str); /* Write a single character to the serial port. - */ -int gbser_writec(void *handle, int c); + */ +int gbser_writec(void* handle, int c); /* Return true if a port name seems to refer to a serial port. * On Windows this tests the filename (against the regex * /^(\\\\\.\\\\)?com\d+:?$/i). On Posix it returns the value of * isatty() */ -int gbser_is_serial(const char *port_name); +int gbser_is_serial(const char* port_name); -/* This isn't part of the above abstraction; it's just a helper for +/* This isn't part of the above abstraction; it's just a helper for * the other serial modules in the tree. * - * Windows does a weird thing with serial ports. + * Windows does a weird thing with serial ports. * COM ports 1 - 9 are "COM1:" through "COM9:" * The one after that is \\.\\com10 - this function tries to plaster over * that. @@ -131,7 +131,7 @@ int gbser_is_serial(const char *port_name); * call to this function. */ -const char *fix_win_serial_name_r(const char *comname, char *obuf, size_t len); -const char *fix_win_serial_name(const char *comname); +const char* fix_win_serial_name_r(const char* comname, char* obuf, size_t len); +const char* fix_win_serial_name(const char* comname); #endif /* GBSER_H */ diff --git a/gpsbabel/gbser_posix.c b/gpsbabel/gbser_posix.c index ecf1095ad..aaeb0ca57 100644 --- a/gpsbabel/gbser_posix.c +++ b/gpsbabel/gbser_posix.c @@ -1,6 +1,6 @@ /* Serial interface for POSIX tty handling. - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -33,77 +33,95 @@ #include typedef struct { - struct termios old_tio; - struct termios new_tio; - int fd; - unsigned vmin, vtime; - unsigned long magic; - - unsigned char inbuf[BUFSIZE]; - unsigned inbuf_used; + struct termios old_tio; + struct termios new_tio; + int fd; + unsigned vmin, vtime; + unsigned long magic; + + unsigned char inbuf[BUFSIZE]; + unsigned inbuf_used; } gbser_handle; /* Wrapper to safely cast a void * into a gbser_handle */ -static gbser_handle *gbser__get_handle(void *p) { - gbser_handle *h = (gbser_handle *) p; - assert(h->magic == MYMAGIC); - return h; +static gbser_handle* gbser__get_handle(void* p) +{ + gbser_handle* h = (gbser_handle*) p; + assert(h->magic == MYMAGIC); + return h; } -static speed_t mkspeed(unsigned br) { - switch (br) { - case 1200: return B1200; - case 2400: return B2400; - case 4800: return B4800; - case 9600: return B9600; - case 19200: return B19200; - case 38400: return B38400; +static speed_t mkspeed(unsigned br) +{ + switch (br) { + case 1200: + return B1200; + case 2400: + return B2400; + case 4800: + return B4800; + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; #if defined B57600 - case 57600: return B57600; + case 57600: + return B57600; #endif #if defined B115200 - case 115200: return B115200; + case 115200: + return B115200; #endif #if defined B230400 - case 230400: return B230400; + case 230400: + return B230400; #endif - default: - fatal("Unsupported serial speed: %d\n", br); - return 0; /* keep compiler happy */ - } + default: + fatal("Unsupported serial speed: %d\n", br); + return 0; /* keep compiler happy */ + } } typedef struct timeval hp_time; -static void get_time(hp_time *tv) { - gettimeofday(tv, NULL); +static void get_time(hp_time* tv) +{ + gettimeofday(tv, NULL); } -static double elapsed(hp_time *tv) { - hp_time now; - double ot = (double) tv->tv_sec * 1000 + - (double) tv->tv_usec / 1000; - double nt; - gettimeofday(&now, NULL); - nt = (double) now.tv_sec * 1000 + - (double) now.tv_usec / 1000; - /*printf("elapsed -> %f\n", nt - ot);*/ - return nt - ot; +static double elapsed(hp_time* tv) +{ + hp_time now; + double ot = (double) tv->tv_sec * 1000 + + (double) tv->tv_usec / 1000; + double nt; + gettimeofday(&now, NULL); + nt = (double) now.tv_sec * 1000 + + (double) now.tv_usec / 1000; + /*printf("elapsed -> %f\n", nt - ot);*/ + return nt - ot; } -static int set_rx_timeout(gbser_handle *h, unsigned vmin, unsigned vtime) { - if (vmin > 255) { vmin = 255; } - if (vtime > 255) { vtime = 255; } - if (vmin != h->vmin || vtime != h->vtime) { - h->vmin = h->new_tio.c_cc[VMIN] = vmin; - h->vtime = h->new_tio.c_cc[VTIME] = vtime; - - /*printf("VMIN=%d, VTIME=%d\n", h->vmin, h->vtime);*/ - - return tcsetattr(h->fd, TCSANOW, &h->new_tio) ? gbser_ERROR : gbser_OK; - } else { - return 0; - } +static int set_rx_timeout(gbser_handle* h, unsigned vmin, unsigned vtime) +{ + if (vmin > 255) { + vmin = 255; + } + if (vtime > 255) { + vtime = 255; + } + if (vmin != h->vmin || vtime != h->vtime) { + h->vmin = h->new_tio.c_cc[VMIN] = vmin; + h->vtime = h->new_tio.c_cc[VTIME] = vtime; + + /*printf("VMIN=%d, VTIME=%d\n", h->vmin, h->vtime);*/ + + return tcsetattr(h->fd, TCSANOW, &h->new_tio) ? gbser_ERROR : gbser_OK; + } else { + return 0; + } } /* Open a serial port. |port_name| is the (platform specific) name @@ -111,142 +129,145 @@ static int set_rx_timeout(gbser_handle *h, unsigned vmin, unsigned vtime) { * ('com1:') are translated into the equivalent name required by * WIN32 */ -void *gbser_init(const char *port_name) { - gbser_handle *h; +void* gbser_init(const char* port_name) +{ + gbser_handle* h; - gbser__db(4, "gbser_init(\"%s\")\n", port_name); + gbser__db(4, "gbser_init(\"%s\")\n", port_name); - h = (gbser_handle*) xcalloc(sizeof *h, 1); - h->magic = MYMAGIC; - h->vmin = h->vtime = 0; + h = (gbser_handle*) xcalloc(sizeof *h, 1); + h->magic = MYMAGIC; + h->vmin = h->vtime = 0; - if (0 == strcmp(port_name, "-")) { - h->fd = 0; - return h; - } - else if (h->fd = open(port_name, O_RDWR | O_NOCTTY), h->fd == -1) { - warning("Failed to open port (%s)\n", strerror(errno)); - goto failed; - } + if (0 == strcmp(port_name, "-")) { + h->fd = 0; + return h; + } else if (h->fd = open(port_name, O_RDWR | O_NOCTTY), h->fd == -1) { + warning("Failed to open port (%s)\n", strerror(errno)); + goto failed; + } - if (!isatty(h->fd)) { - warning("%s is not a TTY\n", port_name); - goto failed; - } + if (!isatty(h->fd)) { + warning("%s is not a TTY\n", port_name); + goto failed; + } - if (gbser_set_port(h, 4800, 8, 0, 1)) { - warning("gbser_set_port() failed\n"); - goto failed; - } + if (gbser_set_port(h, 4800, 8, 0, 1)) { + warning("gbser_set_port() failed\n"); + goto failed; + } - return h; + return h; failed: - if (h->fd != -1) { - close(h->fd); - } - - xfree(h); - - return NULL; + if (h->fd != -1) { + close(h->fd); + } + + xfree(h); + + return NULL; } /* Close a serial port */ -void gbser_deinit(void *handle) { - gbser_handle *h = gbser__get_handle(handle); +void gbser_deinit(void* handle) +{ + gbser_handle* h = gbser__get_handle(handle); - tcsetattr(h->fd, TCSAFLUSH, &h->old_tio); - close(h->fd); + tcsetattr(h->fd, TCSAFLUSH, &h->old_tio); + close(h->fd); - xfree(h); + xfree(h); } -int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) { - gbser_handle *h = gbser__get_handle(handle); - speed_t s; - - static unsigned bit_flags[] = { - 0, 0, 0, 0, 0, CS5, CS6, CS7, CS8 - }; +int gbser_set_port(void* handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) +{ + gbser_handle* h = gbser__get_handle(handle); + speed_t s; - if (bits < 5 || bits > 8) { - fatal("Unsupported bits setting: %d\n", bits); - } + static unsigned bit_flags[] = { + 0, 0, 0, 0, 0, CS5, CS6, CS7, CS8 + }; - if (parity > 2) { - fatal("Unsupported parity setting: %d\n", parity); - } - - if (stop < 1 || stop > 2) { - fatal("Unsupported stop setting: %d\n", stop); - } + if (bits < 5 || bits > 8) { + fatal("Unsupported bits setting: %d\n", bits); + } + + if (parity > 2) { + fatal("Unsupported parity setting: %d\n", parity); + } - s = mkspeed(speed); + if (stop < 1 || stop > 2) { + fatal("Unsupported stop setting: %d\n", stop); + } - /* TODO: We don't /fully/ initialise the port's stat here... */ + s = mkspeed(speed); - tcgetattr(h->fd, &h->old_tio); + /* TODO: We don't /fully/ initialise the port's stat here... */ - h->new_tio = h->old_tio; + tcgetattr(h->fd, &h->old_tio); - /* clear bits */ + h->new_tio = h->old_tio; + + /* clear bits */ // cfmakeraw(&h->new_tio); - h->new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP - |INLCR|IGNCR|ICRNL|IXON); - h->new_tio.c_oflag &= ~OPOST; - h->new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - h->new_tio.c_cflag &= ~(CSIZE|PARENB); - h->new_tio.c_cflag |= CS8; - - h->new_tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | - INLCR | IGNCR | IXON); - h->new_tio.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); - - /* set data bits, */ - h->new_tio.c_cflag |= bit_flags[bits]; - - /* stop bits and... */ - if (stop == 2) { - h->new_tio.c_cflag |= CSTOPB; - } - - /* parity */ - if (parity != 0) { - h->new_tio.c_cflag |= PARENB; - if (parity == 1) { - h->new_tio.c_cflag |= PARODD; - } - } - - h->new_tio.c_oflag = 0; - h->new_tio.c_lflag = 0; - - h->new_tio.c_cc[VMIN] = h->vmin; - h->new_tio.c_cc[VTIME] = h->vtime; - - cfsetospeed(&h->new_tio, s); - cfsetispeed(&h->new_tio, s); - - return tcsetattr(h->fd, TCSADRAIN, &h->new_tio) ? gbser_ERROR : gbser_OK; + h->new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + h->new_tio.c_oflag &= ~OPOST; + h->new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + h->new_tio.c_cflag &= ~(CSIZE|PARENB); + h->new_tio.c_cflag |= CS8; + + h->new_tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | + INLCR | IGNCR | IXON); + h->new_tio.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); + + /* set data bits, */ + h->new_tio.c_cflag |= bit_flags[bits]; + + /* stop bits and... */ + if (stop == 2) { + h->new_tio.c_cflag |= CSTOPB; + } + + /* parity */ + if (parity != 0) { + h->new_tio.c_cflag |= PARENB; + if (parity == 1) { + h->new_tio.c_cflag |= PARODD; + } + } + + h->new_tio.c_oflag = 0; + h->new_tio.c_lflag = 0; + + h->new_tio.c_cc[VMIN] = h->vmin; + h->new_tio.c_cc[VTIME] = h->vtime; + + cfsetospeed(&h->new_tio, s); + cfsetispeed(&h->new_tio, s); + + return tcsetattr(h->fd, TCSADRAIN, &h->new_tio) ? gbser_ERROR : gbser_OK; } -unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { - gbser_handle *h = gbser__get_handle(handle); - unsigned count = *len; - unsigned char *cp = (unsigned char *) *buf; - if (count > h->inbuf_used) { - count = h->inbuf_used; - } - - memcpy(cp, h->inbuf, count); - memmove(h->inbuf, h->inbuf + count, - h->inbuf_used - count); - h->inbuf_used -= count; - *len -= count; - cp += count; - *buf = (void *) cp; - return count; +unsigned gbser__read_buffer(void* handle, void** buf, unsigned* len) +{ + gbser_handle* h = gbser__get_handle(handle); + unsigned count = *len; + unsigned char* cp = (unsigned char*) *buf; + if (count > h->inbuf_used) { + count = h->inbuf_used; + } + + memcpy(cp, h->inbuf, count); + memmove(h->inbuf, h->inbuf + count, + h->inbuf_used - count); + h->inbuf_used -= count; + *len -= count; + cp += count; + *buf = (void*) cp; + return count; } /* Return when the input buffer contains at least |want| bytes or |*ms| @@ -255,111 +276,114 @@ unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { * be updated to indicate the remaining time on exit. * Returns the number of bytes available (>=0) or an error code (<0). */ -int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) { - int rc; - gbser_handle *h = gbser__get_handle(handle); - - if (want > BUFSIZE) { - want = BUFSIZE; - } +int gbser__fill_buffer(void* handle, unsigned want, unsigned* ms) +{ + int rc; + gbser_handle* h = gbser__get_handle(handle); + + if (want > BUFSIZE) { + want = BUFSIZE; + } + + /* Already got enough bytes? */ + if (h->inbuf_used >= want) { + return h->inbuf_used; + } - /* Already got enough bytes? */ - if (h->inbuf_used >= want) { - return h->inbuf_used; + if (NULL == ms || 0 == *ms) { + if ((rc = set_rx_timeout(h, 0, 0), rc < 0) || + (rc = read(h->fd, h->inbuf + h->inbuf_used, + want - h->inbuf_used), rc < 0)) { + return gbser_ERROR; } + h->inbuf_used += rc; + /*printf("Got %d bytes\n", rc);*/ + } else { + double time_left = *ms; + hp_time tv; + get_time(&tv); - if (NULL == ms || 0 == *ms) { - if ((rc = set_rx_timeout(h, 0, 0), rc < 0) || - (rc = read(h->fd, h->inbuf + h->inbuf_used, - want - h->inbuf_used), rc < 0)) { - return gbser_ERROR; + for (;;) { + fd_set rec; + struct timeval t; + + time_left = *ms - elapsed(&tv); + if (time_left <= 0 || h->inbuf_used >= want) { + break; + } + + FD_ZERO(&rec); + FD_SET(h->fd, &rec); + + t.tv_sec = (time_t) time_left / 1000; + t.tv_usec = ((unsigned) time_left % 1000) * 1000; + + if (select(h->fd + 1, &rec, NULL, NULL, &t) < 0) { + return gbser_ERROR; + } + + time_left = *ms - elapsed(&tv); + + if (FD_ISSET(h->fd, &rec)) { + unsigned vmin = 0, vtime = 0; + if (time_left >= 100) { + vmin = want - h->inbuf_used; + vtime = (unsigned) time_left / 100; + } + // The commented out call to set_rx_timeout here is totally + // legal by POSIX standards but does result in a flurry of + // of tcsetattrs that slightly tweak VMIN/VTIME while there + // is incoming data. This has been shown to trigger driver + // bugs in the Prolific drivers for Mac and in certain Linux + // kernels, thought the latter has since been fixed. + // So althogh removing this means that the timeout behaviour + // is actually different on POSIX and WIN32, it triggers + // fewer buts this way. 2/12/2008 RJL + if (/* (rc = set_rx_timeout(h, vmin, vtime), rc < 0) || */ + (rc = read(h->fd, h->inbuf + h->inbuf_used, + want - h->inbuf_used), rc < 0)) { + return gbser_ERROR; } h->inbuf_used += rc; /*printf("Got %d bytes\n", rc);*/ - } else { - double time_left = *ms; - hp_time tv; - get_time(&tv); - - for (;;) { - fd_set rec; - struct timeval t; - - time_left = *ms - elapsed(&tv); - if (time_left <= 0 || h->inbuf_used >= want) { - break; - } - - FD_ZERO(&rec); - FD_SET(h->fd, &rec); - - t.tv_sec = (time_t) time_left / 1000; - t.tv_usec = ((unsigned) time_left % 1000) * 1000; - - if (select(h->fd + 1, &rec, NULL, NULL, &t) < 0) { - return gbser_ERROR; - } - - time_left = *ms - elapsed(&tv); - - if (FD_ISSET(h->fd, &rec)) { - unsigned vmin = 0, vtime = 0; - if (time_left >= 100) { - vmin = want - h->inbuf_used; - vtime = (unsigned) time_left / 100; - } - // The commented out call to set_rx_timeout here is totally - // legal by POSIX standards but does result in a flurry of - // of tcsetattrs that slightly tweak VMIN/VTIME while there - // is incoming data. This has been shown to trigger driver - // bugs in the Prolific drivers for Mac and in certain Linux - // kernels, thought the latter has since been fixed. - // So althogh removing this means that the timeout behaviour - // is actually different on POSIX and WIN32, it triggers - // fewer buts this way. 2/12/2008 RJL - if (/* (rc = set_rx_timeout(h, vmin, vtime), rc < 0) || */ - (rc = read(h->fd, h->inbuf + h->inbuf_used, - want - h->inbuf_used), rc < 0)) { - return gbser_ERROR; - } - h->inbuf_used += rc; - /*printf("Got %d bytes\n", rc);*/ - } - } - *ms = (time_left < 0) ? 0 : time_left; + } } + *ms = (time_left < 0) ? 0 : time_left; + } - return h->inbuf_used; + return h->inbuf_used; } /* Discard any pending input on the serial port. - */ -int gbser_flush(void *handle) { - gbser_handle *h = gbser__get_handle(handle); - h->inbuf_used = 0; - if (tcflush(h->fd, TCIFLUSH)) { - return gbser_ERROR; - } - - return gbser_OK; + */ +int gbser_flush(void* handle) +{ + gbser_handle* h = gbser__get_handle(handle); + h->inbuf_used = 0; + if (tcflush(h->fd, TCIFLUSH)) { + return gbser_ERROR; + } + + return gbser_OK; } /* Write |len| bytes from |buf| to the serial port. */ -int gbser_write(void *handle, const void *buf, unsigned len) { - gbser_handle *h = gbser__get_handle(handle); - const char *bp = (const char *) buf; - int rc; - while (len > 0) { - /*printf("write(%d, %p, %d)\n", h->fd, bp, len);*/ - if (rc = write(h->fd, bp, len), rc < 0) { - printf("rc = %d, errno = %d (%s)\n", rc, errno, strerror(errno)); - return gbser_ERROR; - } - len -= rc; - bp += rc; +int gbser_write(void* handle, const void* buf, unsigned len) +{ + gbser_handle* h = gbser__get_handle(handle); + const char* bp = (const char*) buf; + int rc; + while (len > 0) { + /*printf("write(%d, %p, %d)\n", h->fd, bp, len);*/ + if (rc = write(h->fd, bp, len), rc < 0) { + printf("rc = %d, errno = %d (%s)\n", rc, errno, strerror(errno)); + return gbser_ERROR; } - return gbser_OK; + len -= rc; + bp += rc; + } + return gbser_OK; } /* Return true if a port name seems to refer to a serial port. @@ -368,26 +392,27 @@ int gbser_write(void *handle, const void *buf, unsigned len) { * isatty() */ -int gbser_is_serial(const char *port_name) { - int fd; - int is_port = 0; +int gbser_is_serial(const char* port_name) +{ + int fd; + int is_port = 0; - if (fd = open(port_name, O_RDWR | O_NOCTTY), fd == -1) { - gbser__db(1, "Failed to open port (%s) to check its type\n", strerror(errno)); - return 0; - } + if (fd = open(port_name, O_RDWR | O_NOCTTY), fd == -1) { + gbser__db(1, "Failed to open port (%s) to check its type\n", strerror(errno)); + return 0; + } - is_port = isatty(fd); + is_port = isatty(fd); - close(fd); + close(fd); - return is_port; + return is_port; } -/* This isn't part of the above abstraction; it's just a helper for +/* This isn't part of the above abstraction; it's just a helper for * the other serial modules in the tree. * - * Windows does a weird thing with serial ports. + * Windows does a weird thing with serial ports. * COM ports 1 - 9 are "COM1:" through "COM9:" * The one after that is \\.\\com10 - this function tries to plaster over * that. @@ -396,15 +421,17 @@ int gbser_is_serial(const char *port_name) { * call to this function. */ -const char *fix_win_serial_name_r(const char *comname, char *obuf, size_t len) { - strncpy(obuf, comname, len); - return obuf; +const char* fix_win_serial_name_r(const char* comname, char* obuf, size_t len) +{ + strncpy(obuf, comname, len); + return obuf; } static char gb_com_buffer[100]; -const char *fix_win_serial_name(const char *comname) { - return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); +const char* fix_win_serial_name(const char* comname) +{ + return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); } /* Read from the serial port until the specified |eol| character is @@ -414,28 +441,29 @@ const char *fix_win_serial_name(const char *comname) { * The terminating character and any discarded characters are not * stored in the buffer. */ -int gbser_read_line(void *handle, void *buf, unsigned len, unsigned ms, int eol, int discard) { - char *bp = buf; - unsigned pos = 0; - hp_time tv; - get_time(&tv); - bp[pos] = '\0'; - for (;;) { - signed time_left = ms - elapsed(&tv); - int c; - - if (time_left <= 0) { - return gbser_TIMEOUT; - } - c = gbser_readc_wait(handle, time_left); - if (c == gbser_ERROR) { - return c; - } else if (c == eol) { - return gbser_OK; - } - if (c != gbser_NOTHING && c != discard && pos < len - 1) { - bp[pos++] = c; - bp[pos] = '\0'; - } +int gbser_read_line(void* handle, void* buf, unsigned len, unsigned ms, int eol, int discard) +{ + char* bp = (char*) buf; + unsigned pos = 0; + hp_time tv; + get_time(&tv); + bp[pos] = '\0'; + for (;;) { + signed time_left = ms - elapsed(&tv); + int c; + + if (time_left <= 0) { + return gbser_TIMEOUT; + } + c = gbser_readc_wait(handle, time_left); + if (c == gbser_ERROR) { + return c; + } else if (c == eol) { + return gbser_OK; + } + if (c != gbser_NOTHING && c != discard && pos < len - 1) { + bp[pos++] = c; + bp[pos] = '\0'; } + } } diff --git a/gpsbabel/gbser_private.h b/gpsbabel/gbser_private.h index 318455e80..01f46e6b4 100644 --- a/gpsbabel/gbser_private.h +++ b/gpsbabel/gbser_private.h @@ -1,6 +1,6 @@ /* Serial interface - private header for gbser*.c - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -22,6 +22,6 @@ #define MYMAGIC 0x91827364 #define BUFSIZE 512 -void gbser__db(int l, const char *msg, ...); -int gbser__fill_buffer(void *h, unsigned want, unsigned *ms); -unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len); +void gbser__db(int l, const char* msg, ...); +int gbser__fill_buffer(void* h, unsigned want, unsigned* ms); +unsigned gbser__read_buffer(void* handle, void** buf, unsigned* len); diff --git a/gpsbabel/gbser_win.c b/gpsbabel/gbser_win.c index 26bf5d068..e60850074 100644 --- a/gpsbabel/gbser_win.c +++ b/gpsbabel/gbser_win.c @@ -1,6 +1,6 @@ /* Serial interface - Windows layer. - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -30,89 +30,102 @@ #include typedef struct { - HANDLE comport; - DWORD timeout; - unsigned long magic; + HANDLE comport; + DWORD timeout; + unsigned long magic; - unsigned char inbuf[BUFSIZE]; - unsigned inbuf_used; + unsigned char inbuf[BUFSIZE]; + unsigned inbuf_used; } gbser_handle; #define DEV_PREFIX "\\\\.\\\\" /* Wrapper to safely cast a void * into a gbser_handle */ -static gbser_handle *gbser__get_handle(void *p) { - gbser_handle *h = (gbser_handle *) p; - assert(h->magic == MYMAGIC); - return h; +static gbser_handle* gbser__get_handle(void* p) +{ + gbser_handle* h = (gbser_handle*) p; + assert(h->magic == MYMAGIC); + return h; } -static DWORD mkspeed(unsigned br) { - switch (br) { - case 1200: return CBR_1200; - case 2400: return CBR_2400; - case 4800: return CBR_4800; - case 9600: return CBR_9600; - case 19200: return CBR_19200; - case 38400: return CBR_38400; - case 57600: return CBR_57600; - case 115200: return CBR_115200; - default: - fatal("Unsupported serial speed: %d\n", br); - return 0; /* keep compiler happy */ - } +static DWORD mkspeed(unsigned br) +{ + switch (br) { + case 1200: + return CBR_1200; + case 2400: + return CBR_2400; + case 4800: + return CBR_4800; + case 9600: + return CBR_9600; + case 19200: + return CBR_19200; + case 38400: + return CBR_38400; + case 57600: + return CBR_57600; + case 115200: + return CBR_115200; + default: + fatal("Unsupported serial speed: %d\n", br); + return 0; /* keep compiler happy */ + } } typedef LARGE_INTEGER hp_time; -static void get_time(hp_time *tv) { - QueryPerformanceCounter(tv); +static void get_time(hp_time* tv) +{ + QueryPerformanceCounter(tv); } -static double elapsed(hp_time *tv) { - hp_time now; - LARGE_INTEGER tps; +static double elapsed(hp_time* tv) +{ + hp_time now; + LARGE_INTEGER tps; - QueryPerformanceFrequency(&tps); - QueryPerformanceCounter(&now); + QueryPerformanceFrequency(&tps); + QueryPerformanceCounter(&now); - return ((double) (now.QuadPart - tv->QuadPart) / - (double) tps.QuadPart) * 1000; + return ((double)(now.QuadPart - tv->QuadPart) / + (double) tps.QuadPart) * 1000; } -static int set_rx_timeout(gbser_handle *h, DWORD timeout) { - if (timeout != h->timeout) { - COMMTIMEOUTS to; +static int set_rx_timeout(gbser_handle* h, DWORD timeout) +{ + if (timeout != h->timeout) { + COMMTIMEOUTS to; - if (!GetCommTimeouts(h->comport, &to)) { - return gbser_ERROR; - } - - to.ReadIntervalTimeout = timeout; - to.ReadTotalTimeoutMultiplier = 0; - to.ReadTotalTimeoutConstant = timeout; - to.WriteTotalTimeoutMultiplier = 0; - to.WriteTotalTimeoutConstant = 0; - - if (!SetCommTimeouts(h->comport, &to)) { - return gbser_ERROR; - } else { - h->timeout = timeout; - return gbser_OK; - } + if (!GetCommTimeouts(h->comport, &to)) { + return gbser_ERROR; + } + + to.ReadIntervalTimeout = timeout; + to.ReadTotalTimeoutMultiplier = 0; + to.ReadTotalTimeoutConstant = timeout; + to.WriteTotalTimeoutMultiplier = 0; + to.WriteTotalTimeoutConstant = 0; + + if (!SetCommTimeouts(h->comport, &to)) { + return gbser_ERROR; } else { - return gbser_OK; + h->timeout = timeout; + return gbser_OK; } + } else { + return gbser_OK; + } } -/* This isn't part of the above abstraction; it's just a helper for +/* This isn't part of the above abstraction; it's just a helper for * the other serial modules in the tree. * - * Windows does a weird thing with serial ports. + * Windows does a weird thing with serial ports. * COM ports 1 - 9 are "COM1:" through "COM9:" * The one after that is \\.\\com10 - this function tries to plaster over * that. - * + * * Worse still, Win98 and ME fail the open if you rename com1 to be \\.\\com1: * * It returns a pointer to a staticly allocated buffer and is therefore not @@ -120,31 +133,31 @@ static int set_rx_timeout(gbser_handle *h, DWORD timeout) { * call to this function. */ -const char * -fix_win_serial_name_r(const char *comname, char *obuf, size_t len) +const char* +fix_win_serial_name_r(const char* comname, char* obuf, size_t len) { - if (!gbser_is_serial(comname) || - ((strlen(comname) == 5) && (comname[4] == ':')) || - ((strlen(comname) == 4) && (case_ignore_strncmp(comname, "com", 3) == 0)) - ) { - strncpy(obuf, comname, len); - } else { - size_t l; - snprintf(obuf, len, DEV_PREFIX "%s", comname); - l = strlen(obuf); - if (obuf[l - 1] == ':') { - obuf[l - 1] = '\0'; - } - } - - return obuf; + if (!gbser_is_serial(comname) || + ((strlen(comname) == 5) && (comname[4] == ':')) || + ((strlen(comname) == 4) && (case_ignore_strncmp(comname, "com", 3) == 0)) + ) { + strncpy(obuf, comname, len); + } else { + size_t l; + snprintf(obuf, len, DEV_PREFIX "%s", comname); + l = strlen(obuf); + if (obuf[l - 1] == ':') { + obuf[l - 1] = '\0'; + } + } + + return obuf; } static char gb_com_buffer[100]; -const char *fix_win_serial_name(const char *comname) +const char* fix_win_serial_name(const char* comname) { - return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); + return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); } /* Open a serial port. |port_name| is the (platform specific) name @@ -152,110 +165,113 @@ const char *fix_win_serial_name(const char *comname) * ('com1:') are translated into the equivalent name required by * WIN32 */ -void *gbser_init(const char *port_name) +void* gbser_init(const char* port_name) { - HANDLE comport; - gbser_handle* h = xcalloc(1, sizeof(*h)); - const char *xname = fix_win_serial_name(port_name); - - gbser__db(2, "Translated port name: \"%s\"\n", xname); - - h->magic = MYMAGIC; - - comport = CreateFileA(xname, GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, 0, NULL); - - if (comport == INVALID_HANDLE_VALUE) { - goto failed; - } - - h->comport = comport; - h->timeout = 1; - if (gbser_set_port(h, 4800, 8, 0, 1) || set_rx_timeout(h, 0)) { - goto failed; - } - - return h; - + HANDLE comport; + gbser_handle* h = xcalloc(1, sizeof(*h)); + const char* xname = fix_win_serial_name(port_name); + + gbser__db(2, "Translated port name: \"%s\"\n", xname); + + h->magic = MYMAGIC; + + comport = CreateFileA(xname, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + if (comport == INVALID_HANDLE_VALUE) { + goto failed; + } + + h->comport = comport; + h->timeout = 1; + if (gbser_set_port(h, 4800, 8, 0, 1) || set_rx_timeout(h, 0)) { + goto failed; + } + + return h; + failed: - if (comport) { - CloseHandle(h->comport); - } - xfree(h); - - return NULL; + if (comport) { + CloseHandle(h->comport); + } + xfree(h); + + return NULL; } /* Close a serial port */ -void gbser_deinit(void *handle) { - gbser_handle *h = gbser__get_handle(handle); +void gbser_deinit(void* handle) +{ + gbser_handle* h = gbser__get_handle(handle); - CloseHandle(h->comport); + CloseHandle(h->comport); - xfree(h); + xfree(h); } -int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) { - gbser_handle *h = gbser__get_handle(handle); - DCB tio; - - if (bits < 5 || bits > 8) { - fatal("Unsupported bits setting: %d\n", bits); - } - - if (parity > 2) { - fatal("Unsupported parity setting: %d\n", parity); - } - - if (stop < 1 || stop > 2) { - fatal("Unsupported stop setting: %d\n", stop); - } - - tio.DCBlength = sizeof(DCB); - GetCommState(h->comport, &tio); - - tio.BaudRate = mkspeed(speed); - tio.fBinary = TRUE; - tio.fParity = TRUE; - tio.fOutxCtsFlow = FALSE; - tio.fOutxDsrFlow = FALSE; - tio.fDtrControl = DTR_CONTROL_ENABLE; - tio.fDsrSensitivity = FALSE; - tio.fTXContinueOnXoff = TRUE; - tio.fOutX = FALSE; - tio.fInX = FALSE; - tio.fErrorChar = FALSE; - tio.fNull = FALSE; - tio.fRtsControl = RTS_CONTROL_ENABLE; - tio.fAbortOnError = FALSE; - tio.ByteSize = bits; - tio.Parity = parity == 0 ? NOPARITY : - (parity == 1 ? ODDPARITY : EVENPARITY); - tio.StopBits = stop == 1 ? ONESTOPBIT : TWOSTOPBITS; - - if (!SetCommState(h->comport, &tio)) { - return gbser_ERROR; - } - return gbser_OK; +int gbser_set_port(void* handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) +{ + gbser_handle* h = gbser__get_handle(handle); + DCB tio; + + if (bits < 5 || bits > 8) { + fatal("Unsupported bits setting: %d\n", bits); + } + + if (parity > 2) { + fatal("Unsupported parity setting: %d\n", parity); + } + + if (stop < 1 || stop > 2) { + fatal("Unsupported stop setting: %d\n", stop); + } + + tio.DCBlength = sizeof(DCB); + GetCommState(h->comport, &tio); + + tio.BaudRate = mkspeed(speed); + tio.fBinary = TRUE; + tio.fParity = TRUE; + tio.fOutxCtsFlow = FALSE; + tio.fOutxDsrFlow = FALSE; + tio.fDtrControl = DTR_CONTROL_ENABLE; + tio.fDsrSensitivity = FALSE; + tio.fTXContinueOnXoff = TRUE; + tio.fOutX = FALSE; + tio.fInX = FALSE; + tio.fErrorChar = FALSE; + tio.fNull = FALSE; + tio.fRtsControl = RTS_CONTROL_ENABLE; + tio.fAbortOnError = FALSE; + tio.ByteSize = bits; + tio.Parity = parity == 0 ? NOPARITY : + (parity == 1 ? ODDPARITY : EVENPARITY); + tio.StopBits = stop == 1 ? ONESTOPBIT : TWOSTOPBITS; + + if (!SetCommState(h->comport, &tio)) { + return gbser_ERROR; + } + return gbser_OK; } -unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { - gbser_handle *h = gbser__get_handle(handle); - unsigned count = *len; - unsigned char *cp = *buf; - if (count > h->inbuf_used) { - count = h->inbuf_used; - } - - memcpy(cp, h->inbuf, count); - memmove(h->inbuf, h->inbuf + count, - h->inbuf_used - count); - h->inbuf_used -= count; - *len -= count; - cp += count; - *buf = (void *) cp; - return count; +unsigned gbser__read_buffer(void* handle, void** buf, unsigned* len) +{ + gbser_handle* h = gbser__get_handle(handle); + unsigned count = *len; + unsigned char* cp = *buf; + if (count > h->inbuf_used) { + count = h->inbuf_used; + } + + memcpy(cp, h->inbuf, count); + memmove(h->inbuf, h->inbuf + count, + h->inbuf_used - count); + h->inbuf_used -= count; + *len -= count; + cp += count; + *buf = (void*) cp; + return count; } /* Return when the input buffer contains at least |want| bytes or |*ms| @@ -264,90 +280,93 @@ unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { * be updated to indicate the remaining time on exit. * Returns the number of bytes available (>=0) or an error code (<0). */ -int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) { - int rc; - gbser_handle *h = gbser__get_handle(handle); - - if (want > BUFSIZE) { - want = BUFSIZE; - } +int gbser__fill_buffer(void* handle, unsigned want, unsigned* ms) +{ + int rc; + gbser_handle* h = gbser__get_handle(handle); - /* Already got enough bytes? */ - if (h->inbuf_used >= want) { - return h->inbuf_used; - } - - if (NULL == ms || 0 == *ms) { - DWORD err, nread; - COMSTAT stat; - ClearCommError(h->comport, &err, &stat); - if (stat.cbInQue > 0) { - DWORD count = want - h->inbuf_used; - if (count > stat.cbInQue) { - count = stat.cbInQue; - } - if (rc = set_rx_timeout(h, 1), rc) { - return rc; - } - if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, - count, &nread, NULL)) { - err = GetLastError(); - if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { - return gbser_ERROR; - } - } - h->inbuf_used += nread; - } - } else { - hp_time tv; - double time_left; - DWORD err, nread; - get_time(&tv); - if (rc = set_rx_timeout(h, *ms), rc) { - return rc; + if (want > BUFSIZE) { + want = BUFSIZE; + } + + /* Already got enough bytes? */ + if (h->inbuf_used >= want) { + return h->inbuf_used; + } + + if (NULL == ms || 0 == *ms) { + DWORD err, nread; + COMSTAT stat; + ClearCommError(h->comport, &err, &stat); + if (stat.cbInQue > 0) { + DWORD count = want - h->inbuf_used; + if (count > stat.cbInQue) { + count = stat.cbInQue; + } + if (rc = set_rx_timeout(h, 1), rc) { + return rc; + } + if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, + count, &nread, NULL)) { + err = GetLastError(); + if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { + return gbser_ERROR; } - if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, - want - h->inbuf_used, - &nread, NULL)) { - err = GetLastError(); - if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { - return gbser_ERROR; - } - } - h->inbuf_used += nread; - time_left = *ms - elapsed(&tv); - *ms = time_left < 0 ? 0 : (unsigned) time_left; + } + h->inbuf_used += nread; } + } else { + hp_time tv; + double time_left; + DWORD err, nread; + get_time(&tv); + if (rc = set_rx_timeout(h, *ms), rc) { + return rc; + } + if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, + want - h->inbuf_used, + &nread, NULL)) { + err = GetLastError(); + if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { + return gbser_ERROR; + } + } + h->inbuf_used += nread; + time_left = *ms - elapsed(&tv); + *ms = time_left < 0 ? 0 : (unsigned) time_left; + } - return h->inbuf_used; + return h->inbuf_used; } /* Discard any pending input on the serial port. - */ -int gbser_flush(void *handle) { - gbser_handle *h = gbser__get_handle(handle); - h->inbuf_used = 0; - if (!PurgeComm(h->comport, PURGE_RXCLEAR)) { - return gbser_ERROR; - } - return gbser_OK; + */ +int gbser_flush(void* handle) +{ + gbser_handle* h = gbser__get_handle(handle); + h->inbuf_used = 0; + if (!PurgeComm(h->comport, PURGE_RXCLEAR)) { + return gbser_ERROR; + } + return gbser_OK; } /* Write |len| bytes from |buf| to the serial port. */ -int gbser_write(void *handle, const void *buf, unsigned len) { - gbser_handle *h = gbser__get_handle(handle); - DWORD nwritten; - const char *bp = buf; - /* Not sure we need to spin here - but this'll work even if we don't */ - while (len > 0) { - if (!WriteFile(h->comport, bp, len, &nwritten, NULL)) { - return gbser_ERROR; - } - len -= nwritten; - bp += nwritten; +int gbser_write(void* handle, const void* buf, unsigned len) +{ + gbser_handle* h = gbser__get_handle(handle); + DWORD nwritten; + const char* bp = buf; + /* Not sure we need to spin here - but this'll work even if we don't */ + while (len > 0) { + if (!WriteFile(h->comport, bp, len, &nwritten, NULL)) { + return gbser_ERROR; } - return gbser_OK; + len -= nwritten; + bp += nwritten; + } + return gbser_OK; } /* Return true if a port name seems to refer to a serial port. @@ -356,45 +375,46 @@ int gbser_write(void *handle, const void *buf, unsigned len) { * isatty() */ -int gbser_is_serial(const char *port_name) { - const char *pfx = DEV_PREFIX; - size_t pfx_l = strlen(pfx); - const char *com = "COM"; - size_t com_l = strlen(com); - unsigned digits; - - if (NULL == port_name) { - return 0; - } - - /* Skip any prefix */ - if (memcmp(port_name, pfx, pfx_l) == 0) { - port_name += pfx_l; - } - - if (case_ignore_strncmp(port_name, com, com_l) != 0) { - return 0; - } - - port_name += com_l; - for (digits = 0; isdigit(*port_name); port_name++, digits++) { - /* do nothing */ - } - - if (digits == 0) { - return 0; - } - - if (*port_name == ':') { - port_name++; - } - - if (*port_name != '\0') { - return 0; - } - - /* Success! */ - return 1; +int gbser_is_serial(const char* port_name) +{ + const char* pfx = DEV_PREFIX; + size_t pfx_l = strlen(pfx); + const char* com = "COM"; + size_t com_l = strlen(com); + unsigned digits; + + if (NULL == port_name) { + return 0; + } + + /* Skip any prefix */ + if (memcmp(port_name, pfx, pfx_l) == 0) { + port_name += pfx_l; + } + + if (case_ignore_strncmp(port_name, com, com_l) != 0) { + return 0; + } + + port_name += com_l; + for (digits = 0; isdigit(*port_name); port_name++, digits++) { + /* do nothing */ + } + + if (digits == 0) { + return 0; + } + + if (*port_name == ':') { + port_name++; + } + + if (*port_name != '\0') { + return 0; + } + + /* Success! */ + return 1; } /* Read from the serial port until the specified |eol| character is @@ -402,29 +422,30 @@ int gbser_is_serial(const char *port_name) { * read lines terminated by 0x0A0x0D discarding linefeeds use * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); */ -int gbser_read_line(void *handle, void *buf, +int gbser_read_line(void* handle, void* buf, unsigned len, unsigned ms, - int eol, int discard) { - char *bp = buf; - unsigned pos = 0; - hp_time tv; - get_time(&tv); - bp[pos] = '\0'; - for (;;) { - signed time_left = ms - elapsed(&tv); - int c; - if (time_left <= 0) { - return gbser_TIMEOUT; - } - c = gbser_readc_wait(handle, time_left); - if (c == gbser_ERROR) { - return c; - } else if (c == eol) { - return gbser_OK; - } - if (c != gbser_NOTHING && c != discard && pos < len - 1) { - bp[pos++] = c; - bp[pos] = '\0'; - } + int eol, int discard) +{ + char* bp = buf; + unsigned pos = 0; + hp_time tv; + get_time(&tv); + bp[pos] = '\0'; + for (;;) { + signed time_left = ms - elapsed(&tv); + int c; + if (time_left <= 0) { + return gbser_TIMEOUT; + } + c = gbser_readc_wait(handle, time_left); + if (c == gbser_ERROR) { + return c; + } else if (c == eol) { + return gbser_OK; + } + if (c != gbser_NOTHING && c != discard && pos < len - 1) { + bp[pos++] = c; + bp[pos] = '\0'; } + } } diff --git a/gpsbabel/gbsleep.c b/gpsbabel/gbsleep.c index 63f1fa0ba..5a26dffec 100644 --- a/gpsbabel/gbsleep.c +++ b/gpsbabel/gbsleep.c @@ -28,7 +28,7 @@ void gb_sleep(unsigned long microseconds) { - Sleep(microseconds/1000 + 1); + Sleep(microseconds/1000 + 1); } #elif defined HAVE_NANOSLEEP @@ -37,10 +37,10 @@ gb_sleep(unsigned long microseconds) void gb_sleep(unsigned long microseconds) { - struct timespec req; - req.tv_sec = microseconds / 1000000; - req.tv_nsec = (microseconds * 1000) % 1000000000; - nanosleep(&req, NULL); + struct timespec req; + req.tv_sec = microseconds / 1000000; + req.tv_nsec = (microseconds * 1000) % 1000000000; + nanosleep(&req, NULL); } #elif defined HAVE_SLEEP /* Amazingly underachieving, but probably "good enough" */ @@ -48,6 +48,6 @@ gb_sleep(unsigned long microseconds) void gb_sleep(unsigned long microseconds) { - sleep(microseconds / 1000000); + sleep(microseconds / 1000000); } #endif diff --git a/gpsbabel/gbversion.h b/gpsbabel/gbversion.h index cd23a18e3..5f8e2f06d 100644 --- a/gpsbabel/gbversion.h +++ b/gpsbabel/gbversion.h @@ -4,5 +4,5 @@ * * Isn't simplification via automation grand? */ -#define VERSION "1.4.2" -#define WEB_DOC_DIR "http://www.gpsbabel.org/htmldoc-1.4.2" +#define VERSION "1.4.3" +#define WEB_DOC_DIR "http://www.gpsbabel.org/htmldoc-1.4.3" diff --git a/gpsbabel/gcdb.c b/gpsbabel/gcdb.c index a3c782b28..76a744b06 100644 --- a/gpsbabel/gcdb.c +++ b/gpsbabel/gcdb.c @@ -28,293 +28,284 @@ #define MYCREATOR 0x42726174 /* Brat */ #define MAXRECSZ 500 /* This is overkill as the records seem to be around 100 - bytes a piece, but being conservative and dealing - with realloc issues just doesn't seem worth it. */ +bytes a piece, but being conservative and dealing +with realloc issues just doesn't seem worth it. */ typedef enum { - RECTYPE_TEXT = 0, - RECTYPE_DATE = 2 +RECTYPE_TEXT = 0, +RECTYPE_DATE = 2 } gcdb_rectype; struct dbfld { - char fldname[4]; - pdb_16 fldtype; - pdb_16 fldlen; +char fldname[4]; +pdb_16 fldtype; +pdb_16 fldlen; }; struct dbrec { - pdb_16 nflds; - struct dbfld dbfld[1]; +pdb_16 nflds; +struct dbfld dbfld[1]; }; -static pdbfile *file_in, *file_out; -static const char *out_fname; +static pdbfile* file_in, *file_out; +static const char* out_fname; static int ct; -static char *tbuf = NULL; -static char *tbufp = NULL; +static char* tbuf = NULL; +static char* tbufp = NULL; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); +file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); +pdb_close(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; +file_out = pdb_create(fname, MYNAME); +out_fname = fname; +ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - if ( tbuf ) - xfree(tbuf); +pdb_close(file_out); +if (tbuf) { +xfree(tbuf); +} } static void data_read(void) { - pdbrec_t *pdb_rec; - - if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { - fatal(MYNAME ": Not a GeocachingDB file.\n"); - } - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { - waypoint *wpt = waypt_new(); - struct dbrec *rec = (struct dbrec *) pdb_rec->data; - int nflds; - int length; - int type; - int i; - char *recdata; - int lat_dir = 0; - int lat_deg = 0; - float lat_min = 0.0; - int lon_dir = 0; - int lon_deg = 0; - float lon_min = 0.0; - - nflds = be_read16(&rec->nflds); - recdata = (char *) &rec->dbfld[nflds]; - - for (i = 0; i < nflds; i++) { - length = (unsigned short) be_read16(&rec->dbfld[i].fldlen); - type = be_read16(&rec->dbfld[i].fldtype); - - switch(type) { - case RECTYPE_TEXT: /* Text */ - if (!strncmp("gcid", rec->dbfld[i].fldname,4)) { - wpt->shortname = xstrdup(recdata); - } else - if (!strncmp("gcna", rec->dbfld[i].fldname,4)) { - wpt->description = xstrdup(recdata); - } else - if (!strncmp("lat0", rec->dbfld[i].fldname,4)) { - lat_dir = *recdata == 'N' ? 1 : -1; - } else - if (!strncmp("lat1", rec->dbfld[i].fldname,4)) { - lat_deg = atoi(recdata); - } else - if (!strncmp("lat2", rec->dbfld[i].fldname,4)) { - lat_min = atof(recdata); - } - if (!strncmp("lon0", rec->dbfld[i].fldname,4)) { - lon_dir = *recdata == 'E' ? 1 : -1; - } else - if (!strncmp("lon1", rec->dbfld[i].fldname,4)) { - lon_deg = atoi(recdata); - } else - if (!strncmp("lon2", rec->dbfld[i].fldname,4)) { - lon_min = atof(recdata); - } else - if (!strncmp("take", rec->dbfld[i].fldname,4)) { - wpt->notes = xstrappend(wpt->notes, " Took "); - wpt->notes = xstrappend(wpt->notes, recdata); - } else - if (!strncmp("left", rec->dbfld[i].fldname,4)) { - wpt->notes = xstrappend(wpt->notes, " Left "); - wpt->notes = xstrappend(wpt->notes, recdata); - } else - if (!strncmp("diff", rec->dbfld[i].fldname,4)) { - waypt_alloc_gc_data(wpt)->diff = 10 * atof(recdata); - } else - if (!strncmp("terr", rec->dbfld[i].fldname,4)) { - waypt_alloc_gc_data(wpt)->terr = 10 * atof(recdata); - } - break; +pdbrec_t* pdb_rec; + +if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { +fatal(MYNAME ": Not a GeocachingDB file.\n"); +} + +for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { +waypoint* wpt = waypt_new(); +struct dbrec* rec = (struct dbrec*) pdb_rec->data; +int nflds; +int length; +int type; +int i; +char* recdata; +int lat_dir = 0; +int lat_deg = 0; +float lat_min = 0.0; +int lon_dir = 0; +int lon_deg = 0; +float lon_min = 0.0; + +nflds = be_read16(&rec->nflds); +recdata = (char*) &rec->dbfld[nflds]; + +for (i = 0; i < nflds; i++) { +length = (unsigned short) be_read16(&rec->dbfld[i].fldlen); +type = be_read16(&rec->dbfld[i].fldtype); + +switch (type) { +case RECTYPE_TEXT: /* Text */ +if (!strncmp("gcid", rec->dbfld[i].fldname,4)) { +wpt->shortname = xstrdup(recdata); +} else if (!strncmp("gcna", rec->dbfld[i].fldname,4)) { +wpt->description = xstrdup(recdata); +} else if (!strncmp("lat0", rec->dbfld[i].fldname,4)) { +lat_dir = *recdata == 'N' ? 1 : -1; +} else if (!strncmp("lat1", rec->dbfld[i].fldname,4)) { +lat_deg = atoi(recdata); +} else if (!strncmp("lat2", rec->dbfld[i].fldname,4)) { +lat_min = atof(recdata); +} +if (!strncmp("lon0", rec->dbfld[i].fldname,4)) { +lon_dir = *recdata == 'E' ? 1 : -1; +} else if (!strncmp("lon1", rec->dbfld[i].fldname,4)) { +lon_deg = atoi(recdata); +} else if (!strncmp("lon2", rec->dbfld[i].fldname,4)) { +lon_min = atof(recdata); +} else if (!strncmp("take", rec->dbfld[i].fldname,4)) { +wpt->notes = xstrappend(wpt->notes, " Took "); +wpt->notes = xstrappend(wpt->notes, recdata); +} else if (!strncmp("left", rec->dbfld[i].fldname,4)) { +wpt->notes = xstrappend(wpt->notes, " Left "); +wpt->notes = xstrappend(wpt->notes, recdata); +} else if (!strncmp("diff", rec->dbfld[i].fldname,4)) { +waypt_alloc_gc_data(wpt)->diff = 10 * atof(recdata); +} else if (!strncmp("terr", rec->dbfld[i].fldname,4)) { +waypt_alloc_gc_data(wpt)->terr = 10 * atof(recdata); +} +break; #if 0 - /* This really is the date of the find, - * not the cache creation date. - */ - case RECTYPE_DATE: - if (!strncmp("date", rec->dbfld[i].fldname,4)) { - time_t tm; - tm = be_read32(recdata) * 24 * 3600; - tm -= EPOCH_1904; - wpt->creation_time = tm; - warning( "date %d\n", tm); - } - break; +/* This really is the date of the find, +* not the cache creation date. +*/ +case RECTYPE_DATE: +if (!strncmp("date", rec->dbfld[i].fldname,4)) { +time_t tm; +tm = be_read32(recdata) * 24 * 3600; +tm -= EPOCH_1904; +wpt->creation_time = tm; +warning("date %d\n", tm); +} +break; #endif - } - recdata += (length + 1) & (~1); - } - wpt->latitude = lat_dir * (lat_deg + lat_min/60); - wpt->longitude = lon_dir * (lon_deg + lon_min/60); - waypt_add(wpt); - } +} +recdata += (length + 1) & (~1); +} +wpt->latitude = lat_dir * (lat_deg + lat_min/60); +wpt->longitude = lon_dir * (lon_deg + lon_min/60); +waypt_add(wpt); +} } -static int -gcdb_add_to_rec(struct dbrec *rec, const char *fldname, gcdb_rectype rectype, void *data) +static int +gcdb_add_to_rec(struct dbrec* rec, const char* fldname, gcdb_rectype rectype, const void* data) { - int length; - static int rec_cnt; - - if (!tbuf) { - tbuf = xcalloc(MAXRECSZ, 1); - tbufp = tbuf; - } - - if (fldname == NULL) { - length = tbufp - tbuf; - be_write16(&rec->nflds, rec_cnt); - memcpy(&rec->dbfld[rec_cnt],tbuf, length); - tbufp = tbuf; - length += 4 + sizeof(struct dbfld) * rec_cnt; - rec_cnt = 0; - return length; - } - - be_write16(&rec->dbfld[rec_cnt].fldtype,rectype); - strncpy(rec->dbfld[rec_cnt].fldname, fldname, 4); - - switch (rectype) { - case RECTYPE_TEXT: - length = 1 + strlen(data); - be_write16(&rec->dbfld[rec_cnt].fldlen, length); - strcpy(tbufp, data); - tbufp += (length + 1) & (~1); - break; - case RECTYPE_DATE: - length = 4; - be_write16(&rec->dbfld[rec_cnt].fldlen, length); - be_write32(tbufp, ((time_t)data - EPOCH_1904)/ (3600 * 24)); - tbufp += length; - break; - default: - abort(); - } - rec_cnt++; - - return length; +int length; +static int rec_cnt; + +if (!tbuf) { +tbuf = (char*) xcalloc(MAXRECSZ, 1); +tbufp = tbuf; +} + +if (fldname == NULL) { +length = tbufp - tbuf; +be_write16(&rec->nflds, rec_cnt); +memcpy(&rec->dbfld[rec_cnt],tbuf, length); +tbufp = tbuf; +length += 4 + sizeof(struct dbfld) * rec_cnt; +rec_cnt = 0; +return length; +} + +be_write16(&rec->dbfld[rec_cnt].fldtype,rectype); +strncpy(rec->dbfld[rec_cnt].fldname, fldname, 4); + +switch (rectype) { +case RECTYPE_TEXT: +length = 1 + strlen((const char*)data); +be_write16(&rec->dbfld[rec_cnt].fldlen, length); +strcpy(tbufp, (const char*)data); +tbufp += (length + 1) & (~1); +break; +case RECTYPE_DATE: +length = 4; +be_write16(&rec->dbfld[rec_cnt].fldlen, length); +be_write32(tbufp, ((time_t)data - EPOCH_1904)/ (3600 * 24)); +tbufp += length; +break; +default: +abort(); +} +rec_cnt++; + +return length; } static void -gcdb_write_wpt(const waypoint *wpt) +gcdb_write_wpt(const waypoint* wpt) { - struct dbrec *rec; - int reclen; - char tbuf[100]; +struct dbrec* rec; +int reclen; +char tbuf[100]; - /* - * We don't really know how many fields we'll have or how long - * they'll be so we'll just lazily create a huge place to hold them. - */ - rec = xcalloc(sizeof(*rec) + 500, 1); +/* +* We don't really know how many fields we'll have or how long +* they'll be so we'll just lazily create a huge place to hold them. +*/ +rec = (struct dbrec*) xcalloc(sizeof(*rec) + 500, 1); - gcdb_add_to_rec(rec, "gcna", RECTYPE_TEXT, wpt->description); - gcdb_add_to_rec(rec, "gcid", RECTYPE_TEXT, wpt->shortname); +gcdb_add_to_rec(rec, "gcna", RECTYPE_TEXT, wpt->description); +gcdb_add_to_rec(rec, "gcid", RECTYPE_TEXT, wpt->shortname); - gcdb_add_to_rec(rec, "lat0", RECTYPE_TEXT, - wpt->latitude < 0 ? "S" : "N"); +gcdb_add_to_rec(rec, "lat0", RECTYPE_TEXT, +wpt->latitude < 0 ? "S" : "N"); - sprintf(tbuf, "%d", (int) wpt->latitude); - gcdb_add_to_rec(rec, "lat1", RECTYPE_TEXT, tbuf); +sprintf(tbuf, "%d", (int) wpt->latitude); +gcdb_add_to_rec(rec, "lat1", RECTYPE_TEXT, tbuf); - sprintf(tbuf, "%f", 60 * (wpt->latitude - - (int) wpt->latitude)); - gcdb_add_to_rec(rec, "lat2", RECTYPE_TEXT, tbuf); +sprintf(tbuf, "%f", 60 * (wpt->latitude - +(int) wpt->latitude)); +gcdb_add_to_rec(rec, "lat2", RECTYPE_TEXT, tbuf); - gcdb_add_to_rec(rec, "lon0", RECTYPE_TEXT, - wpt->longitude < 0 ? "W" : "E"); +gcdb_add_to_rec(rec, "lon0", RECTYPE_TEXT, +wpt->longitude < 0 ? "W" : "E"); - sprintf(tbuf, "%d", (int) wpt->longitude); - gcdb_add_to_rec(rec, "lon1", RECTYPE_TEXT, tbuf); +sprintf(tbuf, "%d", (int) wpt->longitude); +gcdb_add_to_rec(rec, "lon1", RECTYPE_TEXT, tbuf); - sprintf(tbuf, "%f", 60 * (wpt->longitude - - (int) wpt->longitude)); - gcdb_add_to_rec(rec, "lon2", RECTYPE_TEXT, tbuf); +sprintf(tbuf, "%f", 60 * (wpt->longitude - +(int) wpt->longitude)); +gcdb_add_to_rec(rec, "lon2", RECTYPE_TEXT, tbuf); - if (wpt->gc_data->diff) { - sprintf(tbuf, "%f", wpt->gc_data->diff / 10.0); - gcdb_add_to_rec(rec, "diff", RECTYPE_TEXT, tbuf); - } +if (wpt->gc_data->diff) { +sprintf(tbuf, "%f", wpt->gc_data->diff / 10.0); +gcdb_add_to_rec(rec, "diff", RECTYPE_TEXT, tbuf); +} - if (wpt->gc_data->terr) { - sprintf(tbuf, "%f", wpt->gc_data->terr / 10.0); - gcdb_add_to_rec(rec, "terr", RECTYPE_TEXT, tbuf); - } +if (wpt->gc_data->terr) { +sprintf(tbuf, "%f", wpt->gc_data->terr / 10.0); +gcdb_add_to_rec(rec, "terr", RECTYPE_TEXT, tbuf); +} #if 0 - /* This really is the date of the find, - * not the cache creation date. - */ - if (wpt->creation_time) { - gcdb_add_to_rec(rec, "date", RECTYPE_DATE, (void *) wpt->creation_time); - } +/* This really is the date of the find, +* not the cache creation date. +*/ +if (wpt->creation_time) { +gcdb_add_to_rec(rec, "date", RECTYPE_DATE, (void*) wpt->creation_time); +} #endif - /* - * We're done. Build the record. - */ - reclen = gcdb_add_to_rec(rec, NULL, 0, NULL); +/* +* We're done. Build the record. +*/ +reclen = gcdb_add_to_rec(rec, NULL, (gcdb_rectype)0, NULL); - pdb_write_rec(file_out, 0, 2, ct++, rec, reclen); - xfree(rec); +pdb_write_rec(file_out, 0, 2, ct++, rec, reclen); +xfree(rec); } static void data_write(void) { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - strncpy(file_out->name, "GeocachingDB", PDB_DBNAMELEN); - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - - waypt_disp_all(gcdb_write_wpt); + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + strncpy(file_out->name, "GeocachingDB", PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + waypt_disp_all(gcdb_write_wpt); } ff_vecs_t gcdb_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/gdb.c b/gpsbabel/gdb.c index 01b263425..0e5d6af4e 100644 --- a/gpsbabel/gdb.c +++ b/gpsbabel/gdb.c @@ -1,10 +1,10 @@ /* Garmin GPS Database Reader/Writer - + Copyright (C) 2005-2008 Olaf Klein, o.b.klein@gpsbabel.org Mainly based on mapsource.c, Copyright (C) 2005 Robert Lipe, robertlipe@usa.net - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,7 +23,7 @@ /* History: - + 2005/06/27: initial release (reader only) 2005/07/26: added write support 2005/07/27: replaced "tricky code" in route reader @@ -110,20 +110,20 @@ /*******************************************************************************/ -/* static char gdb_release[] = "$Revision: 1.72 $"; */ -static char gdb_release_date[] = "$Date: 2010/04/11 22:41:17 $"; +/* static char gdb_release[] = "$Revision: 1.74 $"; */ +static char gdb_release_date[] = "$Date: 2011-04-14 01:30:01 $"; -static gbfile *fin, *fout, *ftmp; +static gbfile* fin, *fout, *ftmp; static int gdb_ver, gdb_category, gdb_via, gdb_roadbook; static queue wayptq_in, wayptq_out, wayptq_in_hidden; static short_handle short_h; -static char *gdb_opt_category; -static char *gdb_opt_ver; -static char *gdb_opt_via; -static char *gdb_opt_roadbook; -static char *gdb_opt_bitcategory; +static char* gdb_opt_category; +static char* gdb_opt_ver; +static char* gdb_opt_via; +static char* gdb_opt_roadbook; +static char* gdb_opt_bitcategory; static int waypt_flag; static int route_flag; @@ -141,44 +141,51 @@ static int trk_ct; /* informational: total number of tracks in/out */ #define NOT_EMPTY(a) (a && *a) static void -gdb_flush_waypt_queue(queue *Q) +gdb_flush_waypt_queue(queue* Q) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(Q, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - dequeue(elem); - if (wpt->extra_data) - xfree(wpt->extra_data); - waypt_free(wpt); - } + queue* elem, *tmp; + + QUEUE_FOR_EACH(Q, elem, tmp) { + waypoint* wpt = (waypoint*)elem; + dequeue(elem); + if (wpt->extra_data) { + xfree(wpt->extra_data); + } + waypt_free(wpt); + } } #if GDB_DEBUG static void -disp_summary(const gbfile *f) +disp_summary(const gbfile* f) { - int i, len; - - len = strlen(f->name); - - warning(MYNAME ": ====================="); - for (i = 0; i < len; i++) warning("="); - warning("\n" MYNAME ": %s summary for \"%s\"\n", - (f->mode == 'r') ? "Reader" : "Writer", f->name); - - warning(MYNAME ": ---------------------"); - for (i = 0; i < len; i++) warning("-"); - - warning("\n" MYNAME ": %d waypoint(s)\n", waypt_ct - waypth_ct); - warning(MYNAME ": %d hidden waypoint(s)\n", waypth_ct); - warning(MYNAME ": %d route(s) with total %d point(s)\n", rte_ct, rtept_ct); - warning(MYNAME ": %d track(s) with total %d point(s)\n", trk_ct, trkpt_ct); - warning(MYNAME ": ---------------------"); - - for (i = 0; i < len; i++) warning("-"); - warning("\n"); + int i, len; + + len = strlen(f->name); + + warning(MYNAME ": ====================="); + for (i = 0; i < len; i++) { + warning("="); + } + warning("\n" MYNAME ": %s summary for \"%s\"\n", + (f->mode == 'r') ? "Reader" : "Writer", f->name); + + warning(MYNAME ": ---------------------"); + for (i = 0; i < len; i++) { + warning("-"); + } + + warning("\n" MYNAME ": %d waypoint(s)\n", waypt_ct - waypth_ct); + warning(MYNAME ": %d hidden waypoint(s)\n", waypth_ct); + warning(MYNAME ": %d route(s) with total %d point(s)\n", rte_ct, rtept_ct); + warning(MYNAME ": %d track(s) with total %d point(s)\n", trk_ct, trkpt_ct); + warning(MYNAME ": ---------------------"); + + for (i = 0; i < len; i++) { + warning("-"); + } + warning("\n"); } #else #define disp_summary(a) @@ -198,149 +205,165 @@ disp_summary(const gbfile *f) #define FREAD_LATLON GPS_Math_Semi_To_Deg(gbfgetint32(fin)) #if GDB_DEBUG -static char * -nice(const char *str) +static char* +nice(const char* str) { - char *res, *env; - cet_cs_vec_t *vec; - - if (!(str && *str)) return ""; - - env = getenv("LANG"); - if (env == NULL) return (char *)str; - - if ((res = strchr(env, '.'))) env = ++res; - vec = cet_find_cs_by_name(env); - - if ((vec != NULL) && (vec != global_opts.charset)) { - static char buf[128]; - res = cet_str_any_to_any(str, global_opts.charset, vec); - strncpy(buf, res, sizeof(buf)); - xfree(res); - return buf; - } - else return (char *)str; + char* res, *env; + cet_cs_vec_t* vec; + + if (!(str && *str)) { + return ""; + } + + env = getenv("LANG"); + if (env == NULL) { + return (char*)str; + } + + if ((res = strchr(env, '.'))) { + env = ++res; + } + vec = cet_find_cs_by_name(env); + + if ((vec != NULL) && (vec != global_opts.charset)) { + static char buf[128]; + res = cet_str_any_to_any(str, global_opts.charset, vec); + strncpy(buf, res, sizeof(buf)); + xfree(res); + return buf; + } else { + return (char*)str; + } } -#endif +#endif -static char * -gdb_fread_cstr(gbfile *fin) +static char* +gdb_fread_cstr(gbfile* fin) { - char *result = gbfgetcstr(fin); - - if (result && (*result == '\0')) { - xfree(result); - result = NULL; - } - return result; + char* result = gbfgetcstr(fin); + + if (result && (*result == '\0')) { + xfree(result); + result = NULL; + } + return result; } static int -gdb_fread_str(char *buf, int size, gbfile *fin) +gdb_fread_str(char* buf, int size, gbfile* fin) { - char c; - int res = 0; - - while (size--) { - gbfread(&c, 1, 1, fin); - buf[res] = c; - if (c == '\0') return res; - res++; - } - buf[res] = '\0'; - return res; + char c; + int res = 0; + + while (size--) { + gbfread(&c, 1, 1, fin); + buf[res] = c; + if (c == '\0') { + return res; + } + res++; + } + buf[res] = '\0'; + return res; } -static char * +static char* gdb_fread_strlist(void) { - char *res = NULL; - int count; - - count = FREAD_i32; - - while (count > 0) { - char *str = FREAD_CSTR; - if (str != NULL) { - if (*str && (res == NULL)) res = str; - else xfree(str); - } - count--; - } - - return res; + char* res = NULL; + int count; + + count = FREAD_i32; + + while (count > 0) { + char* str = FREAD_CSTR; + if (str != NULL) { + if (*str && (res == NULL)) { + res = str; + } else { + xfree(str); + } + } + count--; + } + + return res; } -static waypoint * -gdb_find_wayptq(const queue *Q, const waypoint *wpt, const char exact) +static waypoint* +gdb_find_wayptq(const queue* Q, const waypoint* wpt, const char exact) { - queue *elem, *tmp; - const char *name = wpt->shortname; - - QUEUE_FOR_EACH(Q, elem, tmp) { - waypoint *tmp = (waypoint *)elem; - if (case_ignore_strcmp(name, tmp->shortname) == 0) { - - if (! exact) return tmp; - - if ((tmp->latitude == wpt->latitude) && - (tmp->longitude == wpt->longitude)) - return tmp; - } - } - return NULL; + queue* elem, *tmp; + const char* name = wpt->shortname; + + QUEUE_FOR_EACH(Q, elem, tmp) { + waypoint* tmp = (waypoint*)elem; + if (case_ignore_strcmp(name, tmp->shortname) == 0) { + + if (! exact) { + return tmp; + } + + if ((tmp->latitude == wpt->latitude) && + (tmp->longitude == wpt->longitude)) { + return tmp; + } + } + } + return NULL; } -static waypoint * -gdb_reader_find_waypt(const waypoint *wpt, const char exact) +static waypoint* +gdb_reader_find_waypt(const waypoint* wpt, const char exact) { - waypoint *res; - res = gdb_find_wayptq(&wayptq_in, wpt, exact); - if (res == NULL) - res = gdb_find_wayptq(&wayptq_in_hidden, wpt, exact); - return res; + waypoint* res; + res = gdb_find_wayptq(&wayptq_in, wpt, exact); + if (res == NULL) { + res = gdb_find_wayptq(&wayptq_in_hidden, wpt, exact); + } + return res; } -static waypoint * -gdb_add_route_waypt(route_head *rte, waypoint *ref, const int wpt_class) +static waypoint* +gdb_add_route_waypt(route_head* rte, waypoint* ref, const int wpt_class) { - waypoint *tmp, *res; - int turn_point; - - tmp = gdb_reader_find_waypt(ref, 1); - if (tmp == NULL) { - double dist; - - tmp = find_waypt_by_name(ref->shortname); - if (tmp == NULL) { - route_add_wpt(rte, ref); - return ref; - } - - /* At this point we have found a waypoint with same name, - but probably from another data stream. Check coordinates! - */ - dist = radtometers(gcdist( - RAD(ref->latitude), RAD(ref->longitude), - RAD(tmp->latitude), RAD(tmp->longitude))); - - if (fabs(dist) > 100) { - warning(MYNAME ": Route point mismatch!\n"); - warning(MYNAME ": \"%s\" from waypoints differs to \"%s\"\n", - tmp->shortname, ref->shortname); - fatal(MYNAME ": from route table by more than %0.1f meters!\n", - dist); - - } - } - res = NULL; - turn_point = (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && tmp->description); - if (turn_point || (gdb_via == 0) || (wpt_class < gt_waypt_class_map_point)) { - res = waypt_dupe(tmp); - route_add_wpt(rte, res); - } - waypt_free(ref); - return res; + waypoint* tmp, *res; + int turn_point; + + tmp = gdb_reader_find_waypt(ref, 1); + if (tmp == NULL) { + double dist; + + tmp = find_waypt_by_name(ref->shortname); + if (tmp == NULL) { + route_add_wpt(rte, ref); + return ref; + } + + /* At this point we have found a waypoint with same name, + but probably from another data stream. Check coordinates! + */ + dist = radtometers(gcdist( + RAD(ref->latitude), RAD(ref->longitude), + RAD(tmp->latitude), RAD(tmp->longitude))); + + if (fabs(dist) > 100) { + warning(MYNAME ": Route point mismatch!\n"); + warning(MYNAME ": \"%s\" from waypoints differs to \"%s\"\n", + tmp->shortname, ref->shortname); + fatal(MYNAME ": from route table by more than %0.1f meters!\n", + dist); + + } + } + res = NULL; + turn_point = (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && tmp->description); + if (turn_point || (gdb_via == 0) || (wpt_class < gt_waypt_class_map_point)) { + res = waypt_dupe(tmp); + route_add_wpt(rte, res); + } + waypt_free(ref); + return res; } /*******************************************************************************/ @@ -358,34 +381,36 @@ gdb_add_route_waypt(route_head *rte, waypoint *ref, const int wpt_class) #define FWRITE_LATLON(a) gbfputint32(GPS_Math_Deg_To_Semi((a)),fout) static void -gdb_write_cstr_list(const char *str) +gdb_write_cstr_list(const char* str) { - if NOT_EMPTY(str) { - gbfputint32(1, fout); - gbfputcstr(str, fout); - } else - gbfputint32(0, fout); + if NOT_EMPTY(str) { + gbfputint32(1, fout); + gbfputcstr(str, fout); + } else { + gbfputint32(0, fout); + } } static void gdb_write_dbl(const double value, const double def) { - if (value == def) gbfputc(0, fout); - else { - gbfputc(1, fout); - gbfputdbl(value, fout); - } + if (value == def) { + gbfputc(0, fout); + } else { + gbfputc(1, fout); + gbfputdbl(value, fout); + } } static void gdb_write_time(const int time) { - if (time > 0) { - gbfputc(1, fout); - gbfputint32(time, fout); - } - else - gbfputc(0, fout); + if (time > 0) { + gbfputc(1, fout); + gbfputint32(time, fout); + } else { + gbfputc(0, fout); + } } /*******************************************************************************/ @@ -395,689 +420,729 @@ gdb_write_time(const int time) static void read_file_header(void) { - char buf[128]; - int i, reclen; - -/* - We are beginning with a simple binary read. -*/ - FREAD(buf, 6); -/* - A "gbfgetcstr" (FREAD_CSTR) works too, but if we get a wrong file as input, - the file validation my be comes too late. For example a XML base file normally - has no binary zeros inside and produce, if big enought, a buffer overflow. - The following message "local buffer overflow detected..." could be - misinterpreted. -*/ - is_fatal(strcmp(buf, "MsRcf") != 0, MYNAME ": Invalid file \"%s\"!", fin->name); - - reclen = FREAD_i32; - i = FREAD_STR(buf); - is_fatal(buf[0] != 'D', MYNAME ": Invalid file \"%s\"!", fin->name); - - gdb_ver = buf[1] - 'k' + 1; - is_fatal((gdb_ver < GDB_VER_MIN) || (gdb_ver > GDB_VER_MAX), - MYNAME ": Unknown or/and unsupported GDB version (%d.0)!", gdb_ver); - - if (global_opts.verbose_status > 0) - printf(MYNAME ": Reading Garmin GPS Database version %d.0\n", gdb_ver); - - reclen = FREAD_i32; - i = FREAD(buf, reclen + 1); - if (global_opts.verbose_status > 0) { - char *name = buf+2; - if (strstr(name, "SQA") == 0) name = "MapSource"; - else if (strstr(name, "neaderhi") == 0) name = "MapSource BETA"; - warning(MYNAME ": File created with \"%s\"\n", name); - } - - i = FREAD_STR(buf); - is_fatal(!(((i == 9) && (strcmp(buf, "MapSource") == 0)) || ((i == 8) && (strcmp(buf, "BaseCamp") == 0))), MYNAME ": Not a recognized signature in header"); + char buf[128]; + int i, reclen; + + /* + We are beginning with a simple binary read. + */ + FREAD(buf, 6); + /* + A "gbfgetcstr" (FREAD_CSTR) works too, but if we get a wrong file as input, + the file validation my be comes too late. For example a XML base file normally + has no binary zeros inside and produce, if big enought, a buffer overflow. + The following message "local buffer overflow detected..." could be + misinterpreted. + */ + is_fatal(strcmp(buf, "MsRcf") != 0, MYNAME ": Invalid file \"%s\"!", fin->name); + + reclen = FREAD_i32; + i = FREAD_STR(buf); + is_fatal(buf[0] != 'D', MYNAME ": Invalid file \"%s\"!", fin->name); + + gdb_ver = buf[1] - 'k' + 1; + is_fatal((gdb_ver < GDB_VER_MIN) || (gdb_ver > GDB_VER_MAX), + MYNAME ": Unknown or/and unsupported GDB version (%d.0)!", gdb_ver); + + if (global_opts.verbose_status > 0) { + printf(MYNAME ": Reading Garmin GPS Database version %d.0\n", gdb_ver); + } + + reclen = FREAD_i32; + i = FREAD(buf, reclen + 1); + if (global_opts.verbose_status > 0) { + char* name = buf+2; + if (strstr(name, "SQA") == 0) { + name = "MapSource"; + } else if (strstr(name, "neaderhi") == 0) { + name = "MapSource BETA"; + } + warning(MYNAME ": File created with \"%s\"\n", name); + } + + i = FREAD_STR(buf); + is_fatal(!(((i == 9) && (strcmp(buf, "MapSource") == 0)) || ((i == 8) && (strcmp(buf, "BaseCamp") == 0))), MYNAME ": Not a recognized signature in header"); } /*-----------------------------------------------------------------------------*/ -static waypoint * -read_waypoint(gt_waypt_classes_e *waypt_class_out) +static waypoint* +read_waypoint(gt_waypt_classes_e* waypt_class_out) { - char buf[128]; /* used for temporary stuff */ - int display, icon, dynamic; - gt_waypt_classes_e wpt_class; - int i; - waypoint *res; - garmin_fs_t *gmsd; - char *str; - char *bufp = buf; + char buf[128]; /* used for temporary stuff */ + int display, icon, dynamic; + gt_waypt_classes_e wpt_class; + int i; + waypoint* res; + garmin_fs_t* gmsd; + char* str; + char* bufp = buf; #ifdef GMSD_EXPERIMENTAL - char subclass[22]; + char subclass[22]; #endif #if GDB_DEBUG - char *sn; + char* sn; #endif - waypt_ct++; - res = waypt_new(); + waypt_ct++; + res = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&res->fs, (format_specific_data *) gmsd); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&res->fs, (format_specific_data*) gmsd); - res->shortname = FREAD_CSTR; + res->shortname = FREAD_CSTR; #if GDB_DEBUG - sn = xstrdup(nice(res->shortname)); + sn = xstrdup(nice(res->shortname)); #endif - wpt_class = FREAD_i32; - GMSD_SET(wpt_class, wpt_class); - if (wpt_class != 0) waypth_ct++; - - FREAD_STR(buf); /* Country code */ - GMSD_SETSTR(cc, bufp); - + wpt_class = (gt_waypt_classes_e) FREAD_i32; + GMSD_SET(wpt_class, wpt_class); + if (wpt_class != 0) { + waypth_ct++; + } + + FREAD_STR(buf); /* Country code */ + GMSD_SETSTR(cc, bufp); + #ifdef GMSD_EXPERIMENTAL - FREAD(subclass, sizeof(subclass)); - if (gmsd && (wpt_class >= gt_waypt_class_map_point)) { - memcpy(gmsd->subclass, subclass, sizeof(gmsd->subclass)); - gmsd->flags.subclass = 1; - } + FREAD(subclass, sizeof(subclass)); + if (gmsd && (wpt_class >= gt_waypt_class_map_point)) { + memcpy(gmsd->subclass, subclass, sizeof(gmsd->subclass)); + gmsd->flags.subclass = 1; + } #else - FREAD(buf, 22); + FREAD(buf, 22); #endif - res->latitude = FREAD_LATLON; - res->longitude = FREAD_LATLON; + res->latitude = FREAD_LATLON; + res->longitude = FREAD_LATLON; - if (FREAD_C == 1) { - double alt = FREAD_DBL; - if (alt < 1.0e24) { - res->altitude = alt; + if (FREAD_C == 1) { + double alt = FREAD_DBL; + if (alt < 1.0e24) { + res->altitude = alt; #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): Altitude = %.1f\n", - sn, wpt_class, alt); -#endif - } - } + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Altitude = %.1f\n", + sn, wpt_class, alt); +#endif + } + } #if GDB_DEBUG - DBG(GDB_DBG_WPT, 1) - printf(MYNAME "-wpt \"%s\": coordinates = %c%0.6f %c%0.6f\n", - sn, - res->latitude < 0 ? 'S' : 'N', res->latitude, - res->longitude < 0 ? 'W' : 'E', res->longitude); -#endif - res->notes = FREAD_CSTR; + DBG(GDB_DBG_WPT, 1) + printf(MYNAME "-wpt \"%s\": coordinates = %c%0.6f %c%0.6f\n", + sn, + res->latitude < 0 ? 'S' : 'N', res->latitude, + res->longitude < 0 ? 'W' : 'E', res->longitude); +#endif + res->notes = FREAD_CSTR; #if GDB_DEBUG - DBG(GDB_DBG_WPTe, res->notes) { - char *str = gstrsub(res->notes, "\r\n", ", "); - printf(MYNAME "-wpt \"%s\" (%d): notes = %s\n", - sn, wpt_class, nice(str)); - xfree(str); - } + DBG(GDB_DBG_WPTe, res->notes) { + char* str = gstrsub(res->notes, "\r\n", ", "); + printf(MYNAME "-wpt \"%s\" (%d): notes = %s\n", + sn, wpt_class, nice(str)); + xfree(str); + } #endif - if (FREAD_C == 1) { - WAYPT_SET(res, proximity, FREAD_DBL); + if (FREAD_C == 1) { + WAYPT_SET(res, proximity, FREAD_DBL); #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): Proximity = %.1f\n", - sn, wpt_class, res->proximity / 1000); -#endif - } - i = FREAD_i32; + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Proximity = %.1f\n", + sn, wpt_class, res->proximity / 1000); +#endif + } + i = FREAD_i32; #if GDB_DEBUG - DBG(GDB_DBG_WPTe, i) - printf(MYNAME "-wpt \"%s\" (%d): display = %d\n", - sn, wpt_class, i); + DBG(GDB_DBG_WPTe, i) + printf(MYNAME "-wpt \"%s\" (%d): display = %d\n", + sn, wpt_class, i); #endif - switch(i) { /* display value */ - case gt_gdb_display_mode_symbol: - display = gt_display_mode_symbol; break; - case gt_gdb_display_mode_symbol_and_comment: - display = gt_display_mode_symbol_and_comment; break; - default: - display = gt_display_mode_symbol_and_name; break; - } - GMSD_SET(display, display); - - FREAD_i32; /* color !not implemented! */ - icon = FREAD_i32; - GMSD_SET(icon, icon); /* icon */ - FREAD_STR(buf); /* city */ - GMSD_SETSTR(city, bufp); - FREAD_STR(buf); /* state */ - GMSD_SETSTR(state, bufp); - FREAD_STR(buf); /* facility */ - GMSD_SETSTR(facility, bufp); - - FREAD(buf, 1); - - if (FREAD_C == 1) { - WAYPT_SET(res, depth, FREAD_DBL); + switch (i) { /* display value */ + case gt_gdb_display_mode_symbol: + display = gt_display_mode_symbol; + break; + case gt_gdb_display_mode_symbol_and_comment: + display = gt_display_mode_symbol_and_comment; + break; + default: + display = gt_display_mode_symbol_and_name; + break; + } + GMSD_SET(display, display); + + FREAD_i32; /* color !not implemented! */ + icon = FREAD_i32; + GMSD_SET(icon, icon); /* icon */ + FREAD_STR(buf); /* city */ + GMSD_SETSTR(city, bufp); + FREAD_STR(buf); /* state */ + GMSD_SETSTR(state, bufp); + FREAD_STR(buf); /* facility */ + GMSD_SETSTR(facility, bufp); + + FREAD(buf, 1); + + if (FREAD_C == 1) { + WAYPT_SET(res, depth, FREAD_DBL); #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): Depth = %.1f\n", - sn, wpt_class, res->depth); -#endif - } - - /* VERSION DEPENDENT CODE */ - - if (gdb_ver <= GDB_VER_2) { - char *temp; - - FREAD(buf, 2); /* ?????????????????????????????????? */ - waypt_flag = FREAD_C; - if (waypt_flag == 0) - FREAD(buf, 3); - else - FREAD(buf, 2); - - temp = FREAD_CSTR; /* undocumented & unused string */ + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Depth = %.1f\n", + sn, wpt_class, res->depth); +#endif + } + + /* VERSION DEPENDENT CODE */ + + if (gdb_ver <= GDB_VER_2) { + char* temp; + + FREAD(buf, 2); /* ?????????????????????????????????? */ + waypt_flag = FREAD_C; + if (waypt_flag == 0) { + FREAD(buf, 3); + } else { + FREAD(buf, 2); + } + + temp = FREAD_CSTR; /* undocumented & unused string */ #if GDB_DEBUG - DBG(GDB_DBG_WPTe, temp) - printf(MYNAME "-wpt \"%s\" (%d): Unknown string = %s\n", - sn, wpt_class, nice(temp)); -#endif - if (temp) xfree(temp); - - res->url = FREAD_CSTR; - if (wpt_class != 0) { - res->description = res->url; - res->url = NULL; - } - } - else { // if (gdb_ver >= GDB_VER_3) - int i, url_ct; - - waypt_flag = 0; - - FREAD_STR(buf); /* street address */ - GMSD_SETSTR(addr, bufp); - - FREAD(buf, 5); /* instruction depended */ - res->description = FREAD_CSTR; /* instruction */ - - url_ct = FREAD_i32; - for (i = url_ct; (i); i--) { - char *str = FREAD_CSTR; - if (str && *str) { - waypt_add_url(res, str, NULL); + DBG(GDB_DBG_WPTe, temp) + printf(MYNAME "-wpt \"%s\" (%d): Unknown string = %s\n", + sn, wpt_class, nice(temp)); +#endif + if (temp) { + xfree(temp); + } + + res->url = FREAD_CSTR; + if (wpt_class != 0) { + res->description = res->url; + res->url = NULL; + } + } else { // if (gdb_ver >= GDB_VER_3) + int i, url_ct; + + waypt_flag = 0; + + FREAD_STR(buf); /* street address */ + GMSD_SETSTR(addr, bufp); + + FREAD(buf, 5); /* instruction depended */ + res->description = FREAD_CSTR; /* instruction */ + + url_ct = FREAD_i32; + for (i = url_ct; (i); i--) { + char* str = FREAD_CSTR; + if (str && *str) { + waypt_add_url(res, str, NULL); #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): url(%d) = %s\n", - sn, wpt_class, url_ct - i, str); + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): url(%d) = %s\n", + sn, wpt_class, url_ct - i, str); #endif - } - } - } + } + } + } #if GDB_DEBUG - DBG(GDB_DBG_WPTe, res->description) - printf(MYNAME "-wpt \"%s\" (%d): description = %s\n", - sn, wpt_class, nice(res->description)); - DBG(GDB_DBG_WPTe, res->url) - printf(MYNAME "-wpt \"%s\" (%d): url = %s\n", - sn, wpt_class, nice(res->url)); + DBG(GDB_DBG_WPTe, res->description) + printf(MYNAME "-wpt \"%s\" (%d): description = %s\n", + sn, wpt_class, nice(res->description)); + DBG(GDB_DBG_WPTe, res->url) + printf(MYNAME "-wpt \"%s\" (%d): url = %s\n", + sn, wpt_class, nice(res->url)); #endif - i = FREAD_i16; - if (i != 0) GMSD_SET(category, i); + i = FREAD_i16; + if (i != 0) { + GMSD_SET(category, i); + } #if GDB_DEBUG - DBG(GDB_DBG_WPTe, i) - printf(MYNAME "-wpt \"%s\" (%d): category = %d\n", - sn, wpt_class, i); + DBG(GDB_DBG_WPTe, i) + printf(MYNAME "-wpt \"%s\" (%d): category = %d\n", + sn, wpt_class, i); #endif - - if (FREAD_C == 1) { - WAYPT_SET(res, temperature, FREAD_DBL); + + if (FREAD_C == 1) { + WAYPT_SET(res, temperature, FREAD_DBL); #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): temperature = %.1f\n", - sn, wpt_class, res->temperature); + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): temperature = %.1f\n", + sn, wpt_class, res->temperature); #endif - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - if (waypt_flag != 0) FREAD(buf, 1); - } - if (FREAD_C == 1) { - res->creation_time = FREAD_i32; - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_3) { - if (FREAD_i32 == 1) { - FREAD_STR(buf); /* phone number */ - GMSD_SETSTR(phone_nr, bufp); - FREAD_STR(buf); /* ?? fax / mobile ?? */ - } - FREAD_STR(buf); /* country */ - GMSD_SETSTR(country, bufp); - FREAD_STR(buf); /* postal code */ - GMSD_SETSTR(postal_code, bufp); - } - - res->icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); - res->wpt_flags.icon_descr_is_dynamic = dynamic; + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + if (waypt_flag != 0) { + FREAD(buf, 1); + } + } + if (FREAD_C == 1) { + res->creation_time = FREAD_i32; + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + if (FREAD_i32 == 1) { + FREAD_STR(buf); /* phone number */ + GMSD_SETSTR(phone_nr, bufp); + FREAD_STR(buf); /* ?? fax / mobile ?? */ + } + FREAD_STR(buf); /* country */ + GMSD_SETSTR(country, bufp); + FREAD_STR(buf); /* postal code */ + GMSD_SETSTR(postal_code, bufp); + } + + res->icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); + res->wpt_flags.icon_descr_is_dynamic = dynamic; #if GDB_DEBUG - DBG(GDB_DBG_WPTe, icon != GDB_DEF_ICON) - printf(MYNAME "-wpt \"%s\" (%d): icon = \"%s\" (MapSource symbol %d)\n", - sn, wpt_class, nice(res->icon_descr), icon); + DBG(GDB_DBG_WPTe, icon != GDB_DEF_ICON) + printf(MYNAME "-wpt \"%s\" (%d): icon = \"%s\" (MapSource symbol %d)\n", + sn, wpt_class, nice(res->icon_descr), icon); #endif - if ((str = GMSD_GET(cc, NULL))) { - if (! GMSD_HAS(country)) - GMSD_SETSTR(country, gt_get_icao_country(str)); - } - - if (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && res->description) { - wpt_class = gt_waypt_class_user_waypoint; - GMSD_SET(wpt_class, wpt_class); + if ((str = GMSD_GET(cc, NULL))) { + if (! GMSD_HAS(country)) { + GMSD_SETSTR(country, gt_get_icao_country(str)); + } + } + + if (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && res->description) { + wpt_class = gt_waypt_class_user_waypoint; + GMSD_SET(wpt_class, wpt_class); #ifdef GMSD_EXPERIMENTAL - GMSD_UNSET(subclass); + GMSD_UNSET(subclass); #endif - } + } #if GDB_DEBUG - xfree(sn); + xfree(sn); #endif - *waypt_class_out = wpt_class; - return res; + *waypt_class_out = wpt_class; + return res; } /*-----------------------------------------------------------------------------*/ -static route_head * +static route_head* read_route(void) { - route_head *rte; - int points, warnings, links, i; - char buf[128]; - bounds bounds; - int color_idx; - - rte_ct++; - warnings = 0; - - rte = route_head_alloc(); - rte->rte_name = FREAD_CSTR; - FREAD(buf, 1); /* display/autoname - 1 byte */ - - if (FREAD_C == 0) { /* max. data flag */ - /* maxlat = */ (void) FREAD_i32; - /* maxlon = */ (void) FREAD_i32; - if (FREAD_C == 1) /* maxalt = */ FREAD_DBL; - /* minlat = */ (void) FREAD_i32; - /* minlon = */ (void) FREAD_i32; - if (FREAD_C == 1) /* minalt = */ FREAD_DBL; - } - - links = 0; - points = FREAD_i32; - + route_head* rte; + int points, warnings, links, i; + char buf[128]; + bounds bounds; + int color_idx; + + rte_ct++; + warnings = 0; + + rte = route_head_alloc(); + rte->rte_name = FREAD_CSTR; + FREAD(buf, 1); /* display/autoname - 1 byte */ + + if (FREAD_C == 0) { /* max. data flag */ + /* maxlat = */ (void) FREAD_i32; + /* maxlon = */ + (void) FREAD_i32; + if (FREAD_C == 1) { /* maxalt = */ + FREAD_DBL; + } + /* minlat = */ (void) FREAD_i32; + /* minlon = */ + (void) FREAD_i32; + if (FREAD_C == 1) { /* minalt = */ + FREAD_DBL; + } + } + + links = 0; + points = FREAD_i32; + #if GDB_DEBUG - DBG(GDB_DBG_RTE, 1) - printf(MYNAME "-rte \"%s\": loading route with %d point(s)...\n", - nice(rte->rte_name), points); + DBG(GDB_DBG_RTE, 1) + printf(MYNAME "-rte \"%s\": loading route with %d point(s)...\n", + nice(rte->rte_name), points); #endif - for (i = 0; i < points; i++) { - int wpt_class, j; - char buf[128]; - garmin_ilink_t *il_root, *il_anchor; - - waypoint *wpt; - - wpt = waypt_new(); - rtept_ct++; - - wpt->shortname = FREAD_CSTR; /* shortname */ - wpt_class = FREAD_i32; /* waypoint class */ - FREAD_STR(buf); /* country code */ - FREAD(buf, 18 + 4); /* subclass part 1-3 / unknown */ - - if (FREAD_C != 0) { - FREAD(buf, 8); /* aviation data (?); only seen with class "1" (Airport) */ - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_3) - FREAD(buf, 8); /* a second block since V3 */ - } - - FREAD(buf, 18); /* unknown 18 bytes; but first should be 0x01 or 0x03 */ - /* seen also 0 with VER3 */ - if ((buf[0] != 0x00) && (buf[0] != 0x01) && (buf[0] != 0x03)) { - int i; - - warnings++; - if (warnings > 3) - fatal(MYNAME "-rte_pt \"%s\": too many warnings!\n", wpt->shortname); - warning(MYNAME "-rte_pt \"%s\" (class %d): possible error in route.\n", wpt->shortname, wpt_class); - warning(MYNAME "-rte_pt (dump):"); - for (i = 0; i < 18; i++) { - warning(" %02x", (unsigned char)buf[i]); - } - warning("\n"); - } - - links = FREAD_i32; - il_anchor = NULL; - il_root = NULL; + for (i = 0; i < points; i++) { + int wpt_class, j; + char buf[128]; + garmin_ilink_t* il_root, *il_anchor; + + waypoint* wpt; + + wpt = waypt_new(); + rtept_ct++; + + wpt->shortname = FREAD_CSTR; /* shortname */ + wpt_class = FREAD_i32; /* waypoint class */ + FREAD_STR(buf); /* country code */ + FREAD(buf, 18 + 4); /* subclass part 1-3 / unknown */ + + if (FREAD_C != 0) { + FREAD(buf, 8); /* aviation data (?); only seen with class "1" (Airport) */ + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + FREAD(buf, 8); /* a second block since V3 */ + } + } + + FREAD(buf, 18); /* unknown 18 bytes; but first should be 0x01 or 0x03 */ + /* seen also 0 with VER3 */ + if ((buf[0] != 0x00) && (buf[0] != 0x01) && (buf[0] != 0x03)) { + int i; + + warnings++; + if (warnings > 3) { + fatal(MYNAME "-rte_pt \"%s\": too many warnings!\n", wpt->shortname); + } + warning(MYNAME "-rte_pt \"%s\" (class %d): possible error in route.\n", wpt->shortname, wpt_class); + warning(MYNAME "-rte_pt (dump):"); + for (i = 0; i < 18; i++) { + warning(" %02x", (unsigned char)buf[i]); + } + warning("\n"); + } + + links = FREAD_i32; + il_anchor = NULL; + il_root = NULL; #if GDB_DEBUG - DBG(GDB_DBG_RTE, links) - printf(MYNAME "-rte_pt \"%s\" (%d): %d interlink step(s)\n", - nice(wpt->shortname), wpt_class, links); -#endif - for (j = 0; j < links; j++) { - garmin_ilink_t *il_step = xmalloc(sizeof(*il_step)); - - il_step->ref_count = 1; - - il_step->lat = FREAD_LATLON; - il_step->lon = FREAD_LATLON; - if (FREAD_C == 1) il_step->alt = FREAD_DBL; - else il_step->alt = unknown_alt; - - if (j == 0) { - wpt->latitude = il_step->lat; - wpt->longitude = il_step->lon; - wpt->altitude = il_step->alt; - } - - il_step->next = NULL; - if (il_anchor == NULL) - il_root = il_step; - else - il_anchor->next = il_step; - il_anchor = il_step; + DBG(GDB_DBG_RTE, links) + printf(MYNAME "-rte_pt \"%s\" (%d): %d interlink step(s)\n", + nice(wpt->shortname), wpt_class, links); +#endif + for (j = 0; j < links; j++) { + garmin_ilink_t* il_step = (garmin_ilink_t*) xmalloc(sizeof(*il_step)); + + il_step->ref_count = 1; + + il_step->lat = FREAD_LATLON; + il_step->lon = FREAD_LATLON; + if (FREAD_C == 1) { + il_step->alt = FREAD_DBL; + } else { + il_step->alt = unknown_alt; + } + + if (j == 0) { + wpt->latitude = il_step->lat; + wpt->longitude = il_step->lon; + wpt->altitude = il_step->alt; + } + + il_step->next = NULL; + if (il_anchor == NULL) { + il_root = il_step; + } else { + il_anchor->next = il_step; + } + il_anchor = il_step; #if GDB_DEBUG - DBG(GDB_DBG_RTEe, 1) { - printf(MYNAME "-rte_il \"%s\" (%d of %d): %c%0.6f %c%0.6f\n", - nice(wpt->shortname), j + 1, links, - il_step->lat < 0 ? 'S' : 'N', il_step->lat, - il_step->lon < 0 ? 'W' : 'E', il_step->lon); - } -#endif - } - - waypt_init_bounds(&bounds); - - if (FREAD_C == 0) { /* interlink bounds */ - bounds.max_lat = FREAD_LATLON; - bounds.max_lon = FREAD_LATLON; - if (FREAD_C == 1) - bounds.max_alt = FREAD_DBL; - bounds.min_lat = FREAD_LATLON; - bounds.min_lat = FREAD_LATLON; - if (FREAD_C == 1) - bounds.min_alt = FREAD_DBL; - } - - if (links == 0) { - /* Without links we need all informations from wpt */ - waypoint *tmp = gdb_reader_find_waypt(wpt, 0); - if (tmp != NULL) { - waypt_free(wpt); - wpt = waypt_dupe(tmp); - } - else { - if (waypt_bounds_valid(&bounds)) - warning(MYNAME ": (has bounds)\n"); - - warning(MYNAME ": Data corruption detected!\n"); - fatal(MYNAME ": Sleeping route point without coordinates!\n"); - } - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_2) { - FREAD(buf, 8); - if (gdb_ver >= GDB_VER_3) { - FREAD(buf, 2); - } - } + DBG(GDB_DBG_RTEe, 1) { + printf(MYNAME "-rte_il \"%s\" (%d of %d): %c%0.6f %c%0.6f\n", + nice(wpt->shortname), j + 1, links, + il_step->lat < 0 ? 'S' : 'N', il_step->lat, + il_step->lon < 0 ? 'W' : 'E', il_step->lon); + } +#endif + } + + waypt_init_bounds(&bounds); + + if (FREAD_C == 0) { /* interlink bounds */ + bounds.max_lat = FREAD_LATLON; + bounds.max_lon = FREAD_LATLON; + if (FREAD_C == 1) { + bounds.max_alt = FREAD_DBL; + } + bounds.min_lat = FREAD_LATLON; + bounds.min_lat = FREAD_LATLON; + if (FREAD_C == 1) { + bounds.min_alt = FREAD_DBL; + } + } + + if (links == 0) { + /* Without links we need all informations from wpt */ + waypoint* tmp = gdb_reader_find_waypt(wpt, 0); + if (tmp != NULL) { + waypt_free(wpt); + wpt = waypt_dupe(tmp); + } else { + if (waypt_bounds_valid(&bounds)) { + warning(MYNAME ": (has bounds)\n"); + } + + warning(MYNAME ": Data corruption detected!\n"); + fatal(MYNAME ": Sleeping route point without coordinates!\n"); + } + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_2) { + FREAD(buf, 8); + if (gdb_ver >= GDB_VER_3) { + FREAD(buf, 2); + } + } #if GDB_DEBUG - DBG(GDB_DBG_RTE, 1) - printf(MYNAME "-rte_pt \"%s\": coordinates = %c%0.6f, %c%0.6f\n", - nice(wpt->shortname), - wpt->latitude < 0 ? 'S' : 'N', wpt->latitude, - wpt->longitude < 0 ? 'W' : 'E', wpt->longitude); -#endif - wpt = gdb_add_route_waypt(rte, wpt, wpt_class); - if (wpt != NULL) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - GMSD_SET(wpt_class, wpt_class); - gmsd->ilinks = il_root; - il_root = NULL; - } - - while (il_root) { - garmin_ilink_t *il = il_root; - il_root = il_root->next; - xfree(il); - } - } /* ENDFOR: for (i = 0; i < points; i++) */ - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - rte->rte_url = FREAD_CSTR; - } - else { - rte->rte_url = gdb_fread_strlist(); - - color_idx = FREAD_i32; - rte->line_color.bbggrr = gt_color_value(color_idx); - FREAD(buf, 1); /* ?????????????????????????????????? */ - - rte->rte_desc = FREAD_CSTR; + DBG(GDB_DBG_RTE, 1) + printf(MYNAME "-rte_pt \"%s\": coordinates = %c%0.6f, %c%0.6f\n", + nice(wpt->shortname), + wpt->latitude < 0 ? 'S' : 'N', wpt->latitude, + wpt->longitude < 0 ? 'W' : 'E', wpt->longitude); +#endif + wpt = gdb_add_route_waypt(rte, wpt, wpt_class); + if (wpt != NULL) { + garmin_fs_t* gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data*) gmsd); + } + GMSD_SET(wpt_class, wpt_class); + gmsd->ilinks = il_root; + il_root = NULL; + } + + while (il_root) { + garmin_ilink_t* il = il_root; + il_root = il_root->next; + xfree(il); + } + } /* ENDFOR: for (i = 0; i < points; i++) */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + rte->rte_url = FREAD_CSTR; + } else { + rte->rte_url = gdb_fread_strlist(); + + color_idx = FREAD_i32; + rte->line_color.bbggrr = gt_color_value(color_idx); + FREAD(buf, 1); /* ?????????????????????????????????? */ + + rte->rte_desc = FREAD_CSTR; #if 0 - /* replace CRLF's with ", " */ - if (rte->rte_desc) { - char *c = rte->rte_desc; - while ((c = strstr(c, "\r\n"))) { - *c++ = ','; - *c++ = ' '; - } - } + /* replace CRLF's with ", " */ + if (rte->rte_desc) { + char* c = rte->rte_desc; + while ((c = strstr(c, "\r\n"))) { + *c++ = ','; + *c++ = ' '; + } + } #endif - } - return rte; + } + return rte; } /*-----------------------------------------------------------------------------*/ -static route_head * +static route_head* read_track(void) { - route_head *res; - int points, index; - char dummy; - int color_idx; + route_head* res; + int points, index; + char dummy; + int color_idx; - trk_ct++; + trk_ct++; - res = route_head_alloc(); - res->rte_name = FREAD_CSTR; + res = route_head_alloc(); + res->rte_name = FREAD_CSTR; // res->rte_num = trk_ct; - FREAD(&dummy, 1); /* display - 1 byte */ - color_idx = FREAD_i32; /* color - 1 dword */ - res->line_color.bbggrr = gt_color_value(color_idx); - - points = FREAD_i32; - - for (index = 0; index < points; index++) - { - waypoint *wpt = waypt_new(); - - trkpt_ct++; - - wpt->latitude = FREAD_LATLON; - wpt->longitude = FREAD_LATLON; - if (FREAD_C == 1) { - double alt = FREAD_DBL; - if (alt < 1.0e24) wpt->altitude = alt; - } - if (FREAD_C == 1) { - wpt->creation_time = FREAD_i32; - } - if (FREAD_C == 1) { - WAYPT_SET(wpt, depth, FREAD_DBL); - } - if (FREAD_C == 1) { - WAYPT_SET(wpt, temperature, FREAD_DBL); - } - - track_add_wpt(res, wpt); - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_3) { - res->rte_url = gdb_fread_strlist(); - } - else /* if (gdb_ver <= GDB_VER_2) */ { - res->rte_url = FREAD_CSTR; - } + FREAD(&dummy, 1); /* display - 1 byte */ + color_idx = FREAD_i32; /* color - 1 dword */ + res->line_color.bbggrr = gt_color_value(color_idx); + + points = FREAD_i32; + + for (index = 0; index < points; index++) { + waypoint* wpt = waypt_new(); + + trkpt_ct++; + + wpt->latitude = FREAD_LATLON; + wpt->longitude = FREAD_LATLON; + if (FREAD_C == 1) { + double alt = FREAD_DBL; + if (alt < 1.0e24) { + wpt->altitude = alt; + } + } + if (FREAD_C == 1) { + wpt->creation_time = FREAD_i32; + } + if (FREAD_C == 1) { + WAYPT_SET(wpt, depth, FREAD_DBL); + } + if (FREAD_C == 1) { + WAYPT_SET(wpt, temperature, FREAD_DBL); + } + + track_add_wpt(res, wpt); + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + res->rte_url = gdb_fread_strlist(); + } else { /* if (gdb_ver <= GDB_VER_2) */ + res->rte_url = FREAD_CSTR; + } #if GDB_DEBUG - DBG(GDB_DBG_TRK, res->rte_url) - printf(MYNAME "-trk \"%s\": url = %s\n", - res->rte_name, res->rte_url); + DBG(GDB_DBG_TRK, res->rte_url) + printf(MYNAME "-trk \"%s\": url = %s\n", + res->rte_name, res->rte_url); #endif - return res; + return res; } /*******************************************************************************/ static void -gdb_rd_init(const char *fname) +gdb_rd_init(const char* fname) { - fin = gbfopen_le(fname, "rb", MYNAME); - ftmp = gbfopen_le(NULL, "wb", MYNAME); - read_file_header(); - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_UTF8) - cet_convert_init(CET_CHARSET_UTF8, 1); - - QUEUE_INIT(&wayptq_in); - QUEUE_INIT(&wayptq_in_hidden); - - gdb_via = (gdb_opt_via && *gdb_opt_via) ? atoi(gdb_opt_via) : 0; - gdb_roadbook = (gdb_opt_roadbook && *gdb_opt_roadbook) ? atoi(gdb_opt_roadbook) : 0; - if (gdb_roadbook) /* higher priority */ gdb_via = 1; - - waypt_ct = 0; - waypth_ct = 0; - rtept_ct = 0; - trkpt_ct = 0; - rte_ct = 0; - trk_ct = 0; + fin = gbfopen_le(fname, "rb", MYNAME); + ftmp = gbfopen_le(NULL, "wb", MYNAME); + read_file_header(); + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_UTF8) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + QUEUE_INIT(&wayptq_in); + QUEUE_INIT(&wayptq_in_hidden); + + gdb_via = (gdb_opt_via && *gdb_opt_via) ? atoi(gdb_opt_via) : 0; + gdb_roadbook = (gdb_opt_roadbook && *gdb_opt_roadbook) ? atoi(gdb_opt_roadbook) : 0; + if (gdb_roadbook) { /* higher priority */ + gdb_via = 1; + } + + waypt_ct = 0; + waypth_ct = 0; + rtept_ct = 0; + trkpt_ct = 0; + rte_ct = 0; + trk_ct = 0; } static void gdb_rd_deinit(void) { - disp_summary(fin); - gdb_flush_waypt_queue(&wayptq_in); - gdb_flush_waypt_queue(&wayptq_in_hidden); - gbfclose(ftmp); - gbfclose(fin); + disp_summary(fin); + gdb_flush_waypt_queue(&wayptq_in); + gdb_flush_waypt_queue(&wayptq_in_hidden); + gbfclose(ftmp); + gbfclose(fin); } static void read_data(void) { - gbfile *fsave; - int incomplete = 0; /* number of incomplete reads */ - - for (;;) { - int len, delta; - char typ, dump; - gt_waypt_classes_e wpt_class; - waypoint *wpt; - route_head *trk, *rte; - - len = FREAD_i32; - if (FREAD(&typ, 1) < 1) { - fatal(MYNAME ": Attempt to read past EOF."); - } - if (typ == 'V') break; /* break the loop */ - - gbfrewind(ftmp); - gbfwrite(NULL, 0, 0, ftmp); /* truncate */ - gbfcopyfrom(ftmp, fin, len); - gbfrewind(ftmp); - - fsave = fin; /* swap standard 'fin' with cached input */ - fin = ftmp; - - dump = 1; - wpt_class = GDB_DEF_CLASS; - - switch(typ) { - case 'W': - wpt = read_waypoint(&wpt_class); - if ((gdb_via == 0) || (wpt_class == 0)) { - waypoint *dupe; - waypt_add(wpt); - dupe = waypt_dupe(wpt); - ENQUEUE_TAIL(&wayptq_in, &dupe->Q); - } - else - ENQUEUE_TAIL(&wayptq_in_hidden, &wpt->Q); - break; - case 'R': - rte = read_route(); - if (rte) route_add_head(rte); - break; - case 'T': - trk = read_track(); - if (trk) track_add_head(trk); - break; - default: - dump = 0; /* make a dump only for main types */ - break; - } - - fin = fsave; - delta = len - gbftell(ftmp); - is_fatal(delta > 1000000, "Internal consistency error. Delta too big"); - - // Avoid finite loop on bogus beta files from '06. - // THe 100000 is totally pulled from my hat. - // is_fatal((delta > 1000000) || (delta < 0), "Internal GDB error; invalid delta."); - - if (dump && delta) { - if (! incomplete++) { - warning(MYNAME ":==========================================\n"); - warning(MYNAME ":=== W A R N I N G ===\n"); - } - if (typ == 'W') - warning(MYNAME ":(%d%c-%02d): delta = %d (flag=%3d/%02x)-", - gdb_ver, typ, wpt_class, delta, waypt_flag, waypt_flag); - else - warning(MYNAME ":(%d%c): delta = %d -", gdb_ver, typ, delta); - if (delta > 0) { - int i; - char *buf = xmalloc(delta); - if (FREAD(buf, delta) < 1) - fatal(MYNAME ": Attempt to read past EOF.\n"); - for (i = 0; i < delta; i++) { - warning(" %02x", (unsigned char)buf[i]); - } - xfree(buf); - } - warning("\n"); - } - } - - - if (incomplete) { - warning(MYNAME ":------------------------------------------\n"); - warning(MYNAME ": \"%s\"\n", fin->name); - warning(MYNAME ":------------------------------------------\n"); - warning(MYNAME ": Please mail this information\n"); - warning(MYNAME " and, if you can, the used GDB file\n"); - warning(MYNAME ": to gpsbabel-misc@lists.sourceforge.net\n"); - warning(MYNAME ":==========================================\n"); - } + gbfile* fsave; + int incomplete = 0; /* number of incomplete reads */ + + for (;;) { + int len, delta; + char typ, dump; + gt_waypt_classes_e wpt_class; + waypoint* wpt; + route_head* trk, *rte; + + len = FREAD_i32; + if (FREAD(&typ, 1) < 1) { + fatal(MYNAME ": Attempt to read past EOF."); + } + if (typ == 'V') { + break; /* break the loop */ + } + + gbfrewind(ftmp); + gbfwrite(NULL, 0, 0, ftmp); /* truncate */ + gbfcopyfrom(ftmp, fin, len); + gbfrewind(ftmp); + + fsave = fin; /* swap standard 'fin' with cached input */ + fin = ftmp; + + dump = 1; + wpt_class = GDB_DEF_CLASS; + + switch (typ) { + case 'W': + wpt = read_waypoint(&wpt_class); + if ((gdb_via == 0) || (wpt_class == 0)) { + waypoint* dupe; + waypt_add(wpt); + dupe = waypt_dupe(wpt); + ENQUEUE_TAIL(&wayptq_in, &dupe->Q); + } else { + ENQUEUE_TAIL(&wayptq_in_hidden, &wpt->Q); + } + break; + case 'R': + rte = read_route(); + if (rte) { + route_add_head(rte); + } + break; + case 'T': + trk = read_track(); + if (trk) { + track_add_head(trk); + } + break; + default: + dump = 0; /* make a dump only for main types */ + break; + } + + fin = fsave; + delta = len - gbftell(ftmp); + is_fatal(delta > 1000000, "Internal consistency error. Delta too big"); + + // Avoid finite loop on bogus beta files from '06. + // THe 100000 is totally pulled from my hat. + // is_fatal((delta > 1000000) || (delta < 0), "Internal GDB error; invalid delta."); + + if (dump && delta) { + if (! incomplete++) { + warning(MYNAME ":==========================================\n"); + warning(MYNAME ":=== W A R N I N G ===\n"); + } + if (typ == 'W') + warning(MYNAME ":(%d%c-%02d): delta = %d (flag=%3d/%02x)-", + gdb_ver, typ, wpt_class, delta, waypt_flag, waypt_flag); + else { + warning(MYNAME ":(%d%c): delta = %d -", gdb_ver, typ, delta); + } + if (delta > 0) { + int i; + char* buf = (char*) xmalloc(delta); + if (FREAD(buf, delta) < 1) { + fatal(MYNAME ": Attempt to read past EOF.\n"); + } + for (i = 0; i < delta; i++) { + warning(" %02x", (unsigned char)buf[i]); + } + xfree(buf); + } + warning("\n"); + } + } + + + if (incomplete) { + warning(MYNAME ":------------------------------------------\n"); + warning(MYNAME ": \"%s\"\n", fin->name); + warning(MYNAME ":------------------------------------------\n"); + warning(MYNAME ": Please mail this information\n"); + warning(MYNAME " and, if you can, the used GDB file\n"); + warning(MYNAME ": to gpsbabel-misc@lists.sourceforge.net\n"); + warning(MYNAME ":==========================================\n"); + } } /*******************************************************************************/ @@ -1086,20 +1151,21 @@ read_data(void) * reset_short_handle: used for waypoint, route and track names */ static void -reset_short_handle(const char *defname) +reset_short_handle(const char* defname) { - if (short_h != NULL) - mkshort_del_handle(&short_h); - - short_h = mkshort_new_handle(); - - setshort_length(short_h, GDB_NAME_BUFFERLEN); - setshort_badchars(short_h, "\r\n\t"); - setshort_mustupper(short_h, 0); - setshort_mustuniq(short_h, 1); - setshort_whitespace_ok(short_h, 1); - setshort_repeating_whitespace_ok(short_h, 1); - setshort_defname(short_h, defname); + if (short_h != NULL) { + mkshort_del_handle(&short_h); + } + + short_h = mkshort_new_handle(); + + setshort_length(short_h, GDB_NAME_BUFFERLEN); + setshort_badchars(short_h, "\r\n\t"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + setshort_defname(short_h, defname); } /* ----------------------------------------------------------------------------*/ @@ -1107,612 +1173,671 @@ reset_short_handle(const char *defname) static void write_header(void) { - char buff[128], tbuff[32]; - char *c; - int len; - struct tm tm; - - FWRITE_CSTR("MsRcf"); - FWRITE_i32(2); - - strncpy(buff, "Dx", sizeof(buff)); - buff[1] = 'k' - 1 + gdb_ver; - FWRITE_CSTR(buff); - + char buff[128], tbuff[32]; + char* c; + int len, n = 0; + struct tm tm; + + FWRITE_CSTR("MsRcf"); + FWRITE_i32(2); + + strncpy(buff, "Dx", sizeof(buff)); + buff[1] = 'k' - 1 + gdb_ver; + FWRITE_CSTR(buff); + #if 0 - /* Take this if anything is wrong with our self generated watermark */ - strncpy(buff, "A].SQA*Dec 27 2004*17:40:51", sizeof(buff)); /* MapSource V6.5 */ + /* Take this if anything is wrong with our self generated watermark */ + strncpy(buff, "A].SQA*Dec 27 2004*17:40:51", sizeof(buff)); /* MapSource V6.5 */ #else - /* This is our "Watermark" to show this file was created by GPSbabel */ - - /* history: - - "A].GPSBabel_1.2.7-beta*Sep 13 2005*20:10:00" - gpsbabel V1.2.7 BETA - "A].GPSBabel_1.2.8-beta*Jan 18 2006*20:11:00" - gpsbabel 1.2.8-beta01182006_clyde - "A].GPSBabel_1.2.8-beta*Apr 18 2006*20:12:00" - gpsbabel 1.2.8-beta20060405 - "A].GPSBabel-1.3*Jul 02 2006*20:13:00" - gpsbabel 1.3.0 - "A].GPSBabel-1.3.1*Sep 03 2006*20:14:00" - gpsbabel 1.3.1 - "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 - - New since 11/01/2006: - version: version and release of gpsbabel (defined in configure.in) - timestamp: date and time of gdb.c (handled by CVS) - - "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 - "A].GPSBabel-beta20061125*Feb 06 2007*23:24:14" gpsbabel beta20061125 - "A].GPSBabel-1.3.3*Feb 20 2007*20:51:15" - gpsbabel 1.3.3 - - */ - - memset(&tm, 0, sizeof(tm)); - sscanf(gdb_release_date+7, "%d/%d/%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon -= 1; - strftime(tbuff, sizeof(tbuff), "%b %d %Y*%H:%M:%S", &tm); - snprintf(buff, sizeof(buff), "A].GPSBabel-%s*%s", gpsbabel_version, tbuff); + /* This is our "Watermark" to show this file was created by GPSbabel */ + + /* history: + + "A].GPSBabel_1.2.7-beta*Sep 13 2005*20:10:00" - gpsbabel V1.2.7 BETA + "A].GPSBabel_1.2.8-beta*Jan 18 2006*20:11:00" - gpsbabel 1.2.8-beta01182006_clyde + "A].GPSBabel_1.2.8-beta*Apr 18 2006*20:12:00" - gpsbabel 1.2.8-beta20060405 + "A].GPSBabel-1.3*Jul 02 2006*20:13:00" - gpsbabel 1.3.0 + "A].GPSBabel-1.3.1*Sep 03 2006*20:14:00" - gpsbabel 1.3.1 + "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 + + New since 11/01/2006: + version: version and release of gpsbabel (defined in configure.in) + timestamp: date and time of gdb.c (handled by CVS) + + "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 + "A].GPSBabel-beta20061125*Feb 06 2007*23:24:14" gpsbabel beta20061125 + "A].GPSBabel-1.3.3*Feb 20 2007*20:51:15" - gpsbabel 1.3.3 + + */ + + memset(&tm, 0, sizeof(tm)); + + n = sscanf(gdb_release_date+7, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + if (n != 6) { + // The $Date string in gdb_release_date[] above is bad. + fatal(MYNAME ": internal date format error on %s\n", gdb_release_date + 7); + } + + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + n = strftime(tbuff, sizeof(tbuff), "%b %d %Y*%H:%M:%S", &tm); + if (n == 0) { + // The build of the struct tm was bad. + fatal(MYNAME ": internal date generation error for %s\n", gdb_release_date + 7); + } + + snprintf(buff, sizeof(buff), "A].GPSBabel-%s*%s", gpsbabel_version, tbuff); #endif - len = strlen(buff); - buff[2] = 2; + len = strlen(buff); + buff[2] = 2; - c = buff; - while ((c = strchr(c, '*'))) *c++ = '\0'; + c = buff; + while ((c = strchr(c, '*'))) { + *c++ = '\0'; + } - FWRITE_i32(len); - FWRITE(buff, len + 1); - FWRITE_CSTR("MapSource"); /* MapSource magic */ + FWRITE_i32(len); + FWRITE(buff, len + 1); + FWRITE_CSTR("MapSource"); /* MapSource magic */ } /*-----------------------------------------------------------------------------*/ /* - * gdb_check_waypt: As implemented in waypt_add, but we have some leaks where + * gdb_check_waypt: As implemented in waypt_add, but we have some leaks where * waypoints are modified after waypt_add. Maybe we need a data check * after each input module. */ - + static void -gdb_check_waypt(waypoint *wpt) +gdb_check_waypt(waypoint* wpt) { - double lat_orig = wpt->latitude; - double lon_orig = wpt->longitude; - - if (wpt->latitude < -90) wpt->latitude += 180; - else if (wpt->latitude > +90) wpt->latitude -= 180; - if (wpt->longitude < -180) wpt->longitude += 360; - else if (wpt->longitude > +180) wpt->longitude -= 360; - - if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) - fatal ("Invalid latitude %f in waypoint %s.\n", - lat_orig, wpt->shortname ? wpt->shortname : ""); - if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) - fatal ("Invalid longitude %f in waypoint %s.\n", - lon_orig, wpt->shortname ? wpt->shortname : ""); + double lat_orig = wpt->latitude; + double lon_orig = wpt->longitude; + + if (wpt->latitude < -90) { + wpt->latitude += 180; + } else if (wpt->latitude > +90) { + wpt->latitude -= 180; + } + if (wpt->longitude < -180) { + wpt->longitude += 360; + } else if (wpt->longitude > +180) { + wpt->longitude -= 360; + } + + if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) + fatal("Invalid latitude %f in waypoint %s.\n", + lat_orig, wpt->shortname ? wpt->shortname : ""); + if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) + fatal("Invalid longitude %f in waypoint %s.\n", + lon_orig, wpt->shortname ? wpt->shortname : ""); } /*-----------------------------------------------------------------------------*/ static void write_waypoint( - const waypoint *wpt, const char *shortname, garmin_fs_t *gmsd, - const int icon, const int display) + const waypoint* wpt, const char* shortname, garmin_fs_t* gmsd, + const int icon, const int display) { - char zbuf[32], ffbuf[32]; - int wpt_class; - - waypt_ct++; /* increase informational number of written waypoints */ - - memset(zbuf, 0, sizeof(zbuf)); - memset(ffbuf, 0xFF, sizeof(ffbuf)); - - wpt_class = wpt->microseconds; /* trick */ - - FWRITE_CSTR(shortname); /* uniqe (!!!) shortname */ - FWRITE_i32(wpt_class); /* waypoint class */ - FWRITE_CSTR(GMSD_GET(cc, "")); /* country code */ - - if (wpt_class != 0) waypth_ct++; + char zbuf[32], ffbuf[32]; + int wpt_class; + + waypt_ct++; /* increase informational number of written waypoints */ + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xFF, sizeof(ffbuf)); + + wpt_class = wpt->microseconds; /* trick */ + + FWRITE_CSTR(shortname); /* uniqe (!!!) shortname */ + FWRITE_i32(wpt_class); /* waypoint class */ + FWRITE_CSTR(GMSD_GET(cc, "")); /* country code */ + + if (wpt_class != 0) { + waypth_ct++; + } #ifdef GMSD_EXPERIMENTAL - if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) { - FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); - } - else + if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) { + FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); + } else #endif - { - FWRITE(zbuf, 4); /* subclass part 1 */ - FWRITE(ffbuf, 12); /* subclass part 2 */ - FWRITE(zbuf, 2); /* subclass part 3 */ - FWRITE(ffbuf, 4); /* unknown */ - } - - FWRITE_LATLON(wpt->latitude); /* latitude */ - FWRITE_LATLON(wpt->longitude); /* longitude */ - FWRITE_DBL(wpt->altitude, unknown_alt); /* altitude */ - if (wpt->notes) - FWRITE_CSTR(wpt->notes); - else - FWRITE_CSTR(wpt->description); - FWRITE_DBL(WAYPT_GET(wpt, proximity, unknown_alt), unknown_alt); /* proximity */ - FWRITE_i32(display); /* display */ - FWRITE_i32(0); /* color */ - FWRITE_i32(icon); /* icon */ - FWRITE_CSTR(GMSD_GET(city, "")); /* city */ - FWRITE_CSTR(GMSD_GET(state, "")); /* state */ - FWRITE_CSTR(GMSD_GET(facility, "")); /* facility */ - FWRITE_C(0); /* unknown */ - FWRITE_DBL(WAYPT_GET(wpt, depth, unknown_alt), unknown_alt); /* depth */ - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - char *descr; - - FWRITE(zbuf, 3); - FWRITE(zbuf, 4); - descr = (wpt_class < gt_waypt_class_map_point) ? - wpt->url : wpt->description; - if ((descr != NULL) && (wpt_class >= gt_waypt_class_map_point) && \ - (strcmp(descr, wpt->shortname) == 0)) - descr = NULL; - FWRITE_CSTR(descr); - } - else /* if (gdb_ver > GDB_VER_3) */ { - int cnt; - url_link *url_next; - const char *str; - - if (wpt_class < gt_waypt_class_map_point) /* street address */ - str = GMSD_GET(addr, ""); - else - str = ""; - FWRITE_CSTR(str); - FWRITE(zbuf, 5); /* instruction dependend */ - - /* GBD doesn't have a native description field */ - /* here we misuse the instruction field */ - - str = wpt->description; - if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; - if (str && wpt->notes && (strcmp(str, wpt->notes) == 0)) str = NULL; - FWRITE_CSTR(str); /* instruction */ - - cnt = 0; - if (wpt->url) cnt++; - for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) - if (url_next->url) cnt++; - FWRITE_i32(cnt); - if (wpt->url) FWRITE_CSTR(wpt->url); - for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) - if (url_next->url) FWRITE_CSTR(url_next->url); - } - - FWRITE_i16(GMSD_GET(category, gdb_category)); - FWRITE_DBL(WAYPT_GET(wpt, temperature, 0), 0); - FWRITE_TIME(wpt->creation_time); - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_3) { - const char *str = GMSD_GET(phone_nr, ""); - if (*str) { - FWRITE_i32(1); - FWRITE_CSTR(str); - FWRITE_CSTR(""); - } - else { - FWRITE_i32(0); - } - FWRITE_CSTR(GMSD_GET(country, "")); - FWRITE_CSTR(GMSD_GET(postal_code, "")); - } + { + FWRITE(zbuf, 4); /* subclass part 1 */ + FWRITE(ffbuf, 12); /* subclass part 2 */ + FWRITE(zbuf, 2); /* subclass part 3 */ + FWRITE(ffbuf, 4); /* unknown */ + } + + FWRITE_LATLON(wpt->latitude); /* latitude */ + FWRITE_LATLON(wpt->longitude); /* longitude */ + FWRITE_DBL(wpt->altitude, unknown_alt); /* altitude */ + if (wpt->notes) { + FWRITE_CSTR(wpt->notes); + } else { + FWRITE_CSTR(wpt->description); + } + FWRITE_DBL(WAYPT_GET(wpt, proximity, unknown_alt), unknown_alt); /* proximity */ + FWRITE_i32(display); /* display */ + FWRITE_i32(0); /* color */ + FWRITE_i32(icon); /* icon */ + FWRITE_CSTR(GMSD_GET(city, "")); /* city */ + FWRITE_CSTR(GMSD_GET(state, "")); /* state */ + FWRITE_CSTR(GMSD_GET(facility, "")); /* facility */ + FWRITE_C(0); /* unknown */ + FWRITE_DBL(WAYPT_GET(wpt, depth, unknown_alt), unknown_alt); /* depth */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + char* descr; + + FWRITE(zbuf, 3); + FWRITE(zbuf, 4); + descr = (wpt_class < gt_waypt_class_map_point) ? + wpt->url : wpt->description; + if ((descr != NULL) && (wpt_class >= gt_waypt_class_map_point) && \ + (strcmp(descr, wpt->shortname) == 0)) { + descr = NULL; + } + FWRITE_CSTR(descr); + } else { /* if (gdb_ver > GDB_VER_3) */ + int cnt; + url_link* url_next; + const char* str; + + if (wpt_class < gt_waypt_class_map_point) { /* street address */ + str = GMSD_GET(addr, ""); + } else { + str = ""; + } + FWRITE_CSTR(str); + FWRITE(zbuf, 5); /* instruction dependend */ + + /* GBD doesn't have a native description field */ + /* here we misuse the instruction field */ + + str = wpt->description; + if (str && (strcmp(str, wpt->shortname) == 0)) { + str = NULL; + } + if (str && wpt->notes && (strcmp(str, wpt->notes) == 0)) { + str = NULL; + } + FWRITE_CSTR(str); /* instruction */ + + cnt = 0; + if (wpt->url) { + cnt++; + } + for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) + if (url_next->url) { + cnt++; + } + FWRITE_i32(cnt); + if (wpt->url) { + FWRITE_CSTR(wpt->url); + } + for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) + if (url_next->url) { + FWRITE_CSTR(url_next->url); + } + } + + FWRITE_i16(GMSD_GET(category, gdb_category)); + FWRITE_DBL(WAYPT_GET(wpt, temperature, 0), 0); + FWRITE_TIME(wpt->creation_time); + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + const char* str = GMSD_GET(phone_nr, ""); + if (*str) { + FWRITE_i32(1); + FWRITE_CSTR(str); + FWRITE_CSTR(""); + } else { + FWRITE_i32(0); + } + FWRITE_CSTR(GMSD_GET(country, "")); + FWRITE_CSTR(GMSD_GET(postal_code, "")); + } } static void -route_compute_bounds(const route_head *rte, bounds *bounds) +route_compute_bounds(const route_head* rte, bounds* bounds) { - queue *elem, *tmp; - waypt_init_bounds(bounds); - QUEUE_FOR_EACH((queue *)&rte->waypoint_list, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - gdb_check_waypt(wpt); - waypt_add_to_bounds(bounds, wpt); - } + queue* elem, *tmp; + waypt_init_bounds(bounds); + QUEUE_FOR_EACH((queue*)&rte->waypoint_list, elem, tmp) { + waypoint* wpt = (waypoint*)elem; + gdb_check_waypt(wpt); + waypt_add_to_bounds(bounds, wpt); + } } static void -route_write_bounds(bounds *bounds) +route_write_bounds(bounds* bounds) { - if (waypt_bounds_valid(bounds)) { - FWRITE_C(0); - FWRITE_LATLON(bounds->max_lat); - FWRITE_LATLON(bounds->max_lon); - FWRITE_DBL(bounds->max_alt, -(unknown_alt)); - FWRITE_LATLON(bounds->min_lat); - FWRITE_LATLON(bounds->min_lon); - FWRITE_DBL(bounds->min_alt, unknown_alt); - } - else FWRITE_C(1); + if (waypt_bounds_valid(bounds)) { + FWRITE_C(0); + FWRITE_LATLON(bounds->max_lat); + FWRITE_LATLON(bounds->max_lon); + FWRITE_DBL(bounds->max_alt, unknown_alt); + FWRITE_LATLON(bounds->min_lat); + FWRITE_LATLON(bounds->min_lon); + FWRITE_DBL(bounds->min_alt, -(unknown_alt)); + } else { + FWRITE_C(1); + } } static void -write_route(const route_head *rte, const char *rte_name) +write_route(const route_head* rte, const char* rte_name) { - bounds bounds; - int points, index; - queue *elem, *tmp; - char zbuf[32], ffbuf[32]; - - memset(zbuf, 0, sizeof(zbuf)); - memset(ffbuf, 0xFF, sizeof(ffbuf)); - - FWRITE_CSTR(rte_name); - FWRITE_C(0); /* display/autoname - 1 byte */ - - route_compute_bounds(rte, &bounds); - route_write_bounds(&bounds); - - points = ELEMENTS(rte); - FWRITE_i32(points); - - index = 0; - - QUEUE_FOR_EACH((queue *)&rte->waypoint_list, elem, tmp) { - - waypoint *wpt = (waypoint *)elem; - waypoint *next = (waypoint *)tmp; - waypoint *test; - garmin_fs_t *gmsd = NULL; - int wpt_class; - - index++; - rtept_ct++; /* increase informational number of written route points */ - - if (index == 1) gdb_check_waypt(wpt); - if (index < points) gdb_check_waypt(next); - - test = gdb_find_wayptq(&wayptq_out, wpt, 1); - if (test != NULL) wpt = test; - else { - fatal(MYNAME ": Sorry, that should never happen!!!\n"); - } - - gmsd = GMSD_FIND(wpt); - - /* extra_data may contain a modified shortname */ - FWRITE_CSTR((wpt->extra_data) ? (char *)wpt->extra_data : wpt->shortname); - - wpt_class = wpt->microseconds; /* trick */ - - FWRITE_i32(wpt_class); /* waypoint class */ - FWRITE_CSTR(GMSD_GET(cc, "")); /* country */ + bounds bounds; + int points, index; + queue* elem, *tmp; + char zbuf[32], ffbuf[32]; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xFF, sizeof(ffbuf)); + + FWRITE_CSTR(rte_name); + FWRITE_C(0); /* display/autoname - 1 byte */ + + route_compute_bounds(rte, &bounds); + route_write_bounds(&bounds); + + points = ELEMENTS(rte); + FWRITE_i32(points); + + index = 0; + + QUEUE_FOR_EACH((queue*)&rte->waypoint_list, elem, tmp) { + + waypoint* wpt = (waypoint*)elem; + waypoint* next = (waypoint*)tmp; + waypoint* test; + garmin_fs_t* gmsd = NULL; + int wpt_class; + + index++; + rtept_ct++; /* increase informational number of written route points */ + + if (index == 1) { + gdb_check_waypt(wpt); + } + if (index < points) { + gdb_check_waypt(next); + } + + test = gdb_find_wayptq(&wayptq_out, wpt, 1); + if (test != NULL) { + wpt = test; + } else { + fatal(MYNAME ": Sorry, that should never happen!!!\n"); + } + + gmsd = GMSD_FIND(wpt); + + /* extra_data may contain a modified shortname */ + FWRITE_CSTR((wpt->extra_data) ? (char*)wpt->extra_data : wpt->shortname); + + wpt_class = wpt->microseconds; /* trick */ + + FWRITE_i32(wpt_class); /* waypoint class */ + FWRITE_CSTR(GMSD_GET(cc, "")); /* country */ #ifdef GMSD_EXPERIMENTAL - if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) - FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); - else -#endif - { - FWRITE(zbuf, 4); /* subclass part 1 */ - FWRITE(ffbuf, 12); /* subclass part 2 */ - FWRITE(zbuf, 2); /* subclass part 3 */ - FWRITE(ffbuf, 4); /* unknown */ - } - - FWRITE_C(0); /* unknown value or string */ - FWRITE_C(3); /* unknown 18 bytes starting with 0x03 */ - FWRITE(zbuf, 3); - FWRITE(ffbuf, 4); - FWRITE(zbuf, 10); - - if (index == points) { - FWRITE_i32(0); /* no more steps */ - FWRITE_C(1); /* skip bounds */ - } - else /* if (index < points) */ { - FWRITE_i32(2); /* two interstep links */ - - FWRITE_LATLON(wpt->latitude); - FWRITE_LATLON(wpt->longitude); - FWRITE_DBL(wpt->altitude, unknown_alt); - FWRITE_LATLON(next->latitude); - FWRITE_LATLON(next->longitude); - FWRITE_DBL(next->altitude, unknown_alt); - - waypt_init_bounds(&bounds); - waypt_add_to_bounds(&bounds, wpt); - waypt_add_to_bounds(&bounds, next); - route_write_bounds(&bounds); - - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_2) { - FWRITE(ffbuf, 8); - if (gdb_ver >= GDB_VER_3) - FWRITE(zbuf, 2); - } - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - FWRITE_CSTR(rte->rte_url); - } - else /* if (gdb_ver >= GDB_VER_3) */ { - FWRITE_CSTR_LIST(rte->rte_url); - /* "Magenta" (14) is MapSource default */ - FWRITE_i32( (rte->line_color.bbggrr < 0) ? 14 : gt_color_index_by_rgb(rte->line_color.bbggrr) ); - FWRITE_C(0); - FWRITE_CSTR(rte->rte_desc); - } + if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) { + FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); + } else +#endif + { + FWRITE(zbuf, 4); /* subclass part 1 */ + FWRITE(ffbuf, 12); /* subclass part 2 */ + FWRITE(zbuf, 2); /* subclass part 3 */ + FWRITE(ffbuf, 4); /* unknown */ + } + + FWRITE_C(0); /* unknown value or string */ + FWRITE_C(3); /* unknown 18 bytes starting with 0x03 */ + FWRITE(zbuf, 3); + FWRITE(ffbuf, 4); + FWRITE(zbuf, 10); + + if (index == points) { + FWRITE_i32(0); /* no more steps */ + FWRITE_C(1); /* skip bounds */ + } else { /* if (index < points) */ + FWRITE_i32(2); /* two interstep links */ + + FWRITE_LATLON(wpt->latitude); + FWRITE_LATLON(wpt->longitude); + FWRITE_DBL(wpt->altitude, unknown_alt); + FWRITE_LATLON(next->latitude); + FWRITE_LATLON(next->longitude); + FWRITE_DBL(next->altitude, unknown_alt); + + waypt_init_bounds(&bounds); + waypt_add_to_bounds(&bounds, wpt); + waypt_add_to_bounds(&bounds, next); + route_write_bounds(&bounds); + + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_2) { + FWRITE(ffbuf, 8); + if (gdb_ver >= GDB_VER_3) { + FWRITE(zbuf, 2); + } + } + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + FWRITE_CSTR(rte->rte_url); + } else { /* if (gdb_ver >= GDB_VER_3) */ + FWRITE_CSTR_LIST(rte->rte_url); + /* "Magenta" (14) is MapSource default */ + FWRITE_i32((rte->line_color.bbggrr < 0) ? 14 : gt_color_index_by_rgb(rte->line_color.bbggrr)); + FWRITE_C(0); + FWRITE_CSTR(rte->rte_desc); + } } static void -write_track(const route_head *trk, const char *trk_name) +write_track(const route_head* trk, const char* trk_name) { - queue *elem, *tmp; - int points = ELEMENTS(trk); - - FWRITE_CSTR(trk_name); - FWRITE_C(0); - /* "Unknown" (0) is MapSource default */ - FWRITE_i32(gt_color_index_by_rgb(trk->line_color.bbggrr)); - - FWRITE_i32(points); /* total number of waypoints in waypoint list */ - - QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) - { - double d; - waypoint *wpt = (waypoint *)elem; - - trkpt_ct++; /* increase informational number of written route points */ - - FWRITE_LATLON(wpt->latitude); - FWRITE_LATLON(wpt->longitude); - FWRITE_DBL(wpt->altitude, unknown_alt); - FWRITE_TIME(wpt->creation_time); - d = WAYPT_GET(wpt, depth, unknown_alt); - FWRITE_DBL(d, unknown_alt); - d = WAYPT_GET(wpt, temperature, -99999); - FWRITE_DBL(d, -99999); - } - - /* finalize track */ - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - FWRITE_CSTR(trk->rte_url); - } - else /* if (gdb_ver >= GDB_VER_3 */ { - FWRITE_CSTR_LIST(trk->rte_url); - } + queue* elem, *tmp; + int points = ELEMENTS(trk); + + FWRITE_CSTR(trk_name); + FWRITE_C(0); + /* "Unknown" (0) is MapSource default */ + FWRITE_i32(gt_color_index_by_rgb(trk->line_color.bbggrr)); + + FWRITE_i32(points); /* total number of waypoints in waypoint list */ + + QUEUE_FOR_EACH((queue*)&trk->waypoint_list, elem, tmp) { + double d; + waypoint* wpt = (waypoint*)elem; + + trkpt_ct++; /* increase informational number of written route points */ + + FWRITE_LATLON(wpt->latitude); + FWRITE_LATLON(wpt->longitude); + FWRITE_DBL(wpt->altitude, unknown_alt); + FWRITE_TIME(wpt->creation_time); + d = WAYPT_GET(wpt, depth, unknown_alt); + FWRITE_DBL(d, unknown_alt); + d = WAYPT_GET(wpt, temperature, -99999); + FWRITE_DBL(d, -99999); + } + + /* finalize track */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + FWRITE_CSTR(trk->rte_url); + } else { /* if (gdb_ver >= GDB_VER_3 */ + FWRITE_CSTR_LIST(trk->rte_url); + } } /*-----------------------------------------------------------------------------*/ static void -finalize_item(gbfile *origin, const char identifier) +finalize_item(gbfile* origin, const char identifier) { - int len = gbftell(fout); - - fout = origin; - gbfseek(ftmp, 0, SEEK_SET); - - FWRITE_i32(len); - FWRITE_C(identifier); - gbfcopyfrom(fout, ftmp, len); - - gbfseek(ftmp, 0, SEEK_SET); /* Truncate memory stream */ - gbfwrite(NULL, 0, 0, ftmp); + int len = gbftell(fout); + + fout = origin; + gbfseek(ftmp, 0, SEEK_SET); + + FWRITE_i32(len); + FWRITE_C(identifier); + gbfcopyfrom(fout, ftmp, len); + + gbfseek(ftmp, 0, SEEK_SET); /* Truncate memory stream */ + gbfwrite(NULL, 0, 0, ftmp); } /*-----------------------------------------------------------------------------*/ static char -str_not_equal(const char *s1, const char *s2) +str_not_equal(const char* s1, const char* s2) { - if (s1) { - if (!s2) return 1; - if (strcmp(s1, s2) != 0) return 1; - else return 0; - } - else if (s2) return 1; - else return 0; + if (s1) { + if (!s2) { + return 1; + } + if (strcmp(s1, s2) != 0) { + return 1; + } else { + return 0; + } + } else if (s2) { + return 1; + } else { + return 0; + } } static void -write_waypoint_cb(const waypoint *refpt) +write_waypoint_cb(const waypoint* refpt) { - garmin_fs_t *gmsd; - waypoint *test; - gbfile *fsave; - - /* do this when backup always happens in main */ - - rtrim(((waypoint *)refpt)->shortname); - test = gdb_find_wayptq(&wayptq_out, refpt, 1); - - if ((test != NULL) && (route_flag == 0)) { - if ((str_not_equal(test->notes, refpt->notes)) || - (str_not_equal(test->url, refpt->url))) - test = NULL; - } - - if (test == NULL) { - int icon, display, wpt_class; - char *name; - waypoint *wpt = waypt_dupe(refpt); - - gdb_check_waypt(wpt); - ENQUEUE_TAIL(&wayptq_out, &wpt->Q); - - fsave = fout; - fout = ftmp; - - /* prepare the waypoint */ - gmsd = GMSD_FIND(wpt); - - wpt_class = GMSD_GET(wpt_class, -1); - if (wpt_class == -1) - wpt_class = (route_flag) ? GDB_DEF_HIDDEN_CLASS : GDB_DEF_CLASS; - wpt->microseconds = wpt_class; /* trick, we need this for the route(s) */ - - icon = GMSD_GET(icon, -1); - if (icon < 0) { - if (wpt->icon_descr) - icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); - else - icon = GDB_DEF_ICON; - } - - switch(GMSD_GET(display, -1)) { /* display */ - case -1: - if (wpt_class < 8) - display = gt_gdb_display_mode_symbol_and_name; - else - display = gt_gdb_display_mode_symbol; - break; - case gt_display_mode_symbol: - display = gt_gdb_display_mode_symbol; - break; - case gt_display_mode_symbol_and_comment: - display = gt_gdb_display_mode_symbol_and_comment; - break; - default: - display = gt_gdb_display_mode_symbol_and_name; - break; - } - - name = wpt->shortname; - - if (global_opts.synthesize_shortnames || (*name == '\0')) { - name = wpt->notes; - if (!name) name = wpt->description; - if (!name) name = wpt->shortname; - } - - name = mkshort(short_h, name); - wpt->extra_data = (void *)name; - write_waypoint(wpt, name, gmsd, icon, display); - - finalize_item(fsave, 'W'); - } + garmin_fs_t* gmsd; + waypoint* test; + gbfile* fsave; + + /* do this when backup always happens in main */ + + rtrim(((waypoint*)refpt)->shortname); + test = gdb_find_wayptq(&wayptq_out, refpt, 1); + + if ((test != NULL) && (route_flag == 0)) { + if ((str_not_equal(test->notes, refpt->notes)) || + (str_not_equal(test->url, refpt->url))) { + test = NULL; + } + } + + if (test == NULL) { + int icon, display, wpt_class; + char* name; + waypoint* wpt = waypt_dupe(refpt); + + gdb_check_waypt(wpt); + ENQUEUE_TAIL(&wayptq_out, &wpt->Q); + + fsave = fout; + fout = ftmp; + + /* prepare the waypoint */ + gmsd = GMSD_FIND(wpt); + + wpt_class = GMSD_GET(wpt_class, -1); + if (wpt_class == -1) { + wpt_class = (route_flag) ? GDB_DEF_HIDDEN_CLASS : GDB_DEF_CLASS; + } + wpt->microseconds = wpt_class; /* trick, we need this for the route(s) */ + + icon = GMSD_GET(icon, -1); + if (icon < 0) { + if (wpt->icon_descr) { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); + } else { + icon = GDB_DEF_ICON; + } + } + + switch (GMSD_GET(display, -1)) { /* display */ + case -1: + if (wpt_class < 8) { + display = gt_gdb_display_mode_symbol_and_name; + } else { + display = gt_gdb_display_mode_symbol; + } + break; + case gt_display_mode_symbol: + display = gt_gdb_display_mode_symbol; + break; + case gt_display_mode_symbol_and_comment: + display = gt_gdb_display_mode_symbol_and_comment; + break; + default: + display = gt_gdb_display_mode_symbol_and_name; + break; + } + + name = wpt->shortname; + + if (global_opts.synthesize_shortnames || (*name == '\0')) { + name = wpt->notes; + if (!name) { + name = wpt->description; + } + if (!name) { + name = wpt->shortname; + } + } + + name = mkshort(short_h, name); + wpt->extra_data = (void*)name; + write_waypoint(wpt, name, gmsd, icon, display); + + finalize_item(fsave, 'W'); + } } static void -write_route_cb(const route_head *rte) +write_route_cb(const route_head* rte) { - gbfile *fsave; - char *name; - char buf[32]; - - if (ELEMENTS(rte) <= 0) return; - - if (rte->rte_name == NULL) { - snprintf(buf, sizeof(buf), "Route%04d", rte->rte_num); - name = mkshort(short_h, buf); - } - else - name = mkshort(short_h, rte->rte_name); - - rte_ct++; /* increase informational number of written routes */ - - fsave = fout; - fout = ftmp; - write_route(rte, name); - finalize_item(fsave, 'R'); - - xfree(name); + gbfile* fsave; + char* name; + char buf[32]; + + if (ELEMENTS(rte) <= 0) { + return; + } + + if (rte->rte_name == NULL) { + snprintf(buf, sizeof(buf), "Route%04d", rte->rte_num); + name = mkshort(short_h, buf); + } else { + name = mkshort(short_h, rte->rte_name); + } + + rte_ct++; /* increase informational number of written routes */ + + fsave = fout; + fout = ftmp; + write_route(rte, name); + finalize_item(fsave, 'R'); + + xfree(name); } static void -write_track_cb(const route_head *trk) +write_track_cb(const route_head* trk) { - gbfile *fsave; - char *name; - char buf[32]; - - if (ELEMENTS(trk) <= 0) return; - - if (trk->rte_name == NULL) { - snprintf(buf, sizeof(buf), "Track%04d", trk->rte_num); - name = mkshort(short_h, buf); - } - else - name = mkshort(short_h, trk->rte_name); - - trk_ct++; /* increase informational number of written tracks */ - - fsave = fout; - fout = ftmp; - write_track(trk, name); - finalize_item(fsave, 'T'); - - xfree(name); + gbfile* fsave; + char* name; + char buf[32]; + + if (ELEMENTS(trk) <= 0) { + return; + } + + if (trk->rte_name == NULL) { + snprintf(buf, sizeof(buf), "Track%04d", trk->rte_num); + name = mkshort(short_h, buf); + } else { + name = mkshort(short_h, trk->rte_name); + } + + trk_ct++; /* increase informational number of written tracks */ + + fsave = fout; + fout = ftmp; + write_track(trk, name); + finalize_item(fsave, 'T'); + + xfree(name); } /*-----------------------------------------------------------------------------*/ static void -gdb_wr_init(const char *fname) +gdb_wr_init(const char* fname) { - fout = gbfopen_le(fname, "wb", MYNAME); - ftmp = gbfopen_le(NULL, "wb", MYNAME); - - gdb_category = (gdb_opt_category) ? atoi(gdb_opt_category) : 0; - gdb_ver = (gdb_opt_ver && *gdb_opt_ver) ? atoi(gdb_opt_ver) : 0; - - if (gdb_category) { - is_fatal((gdb_category < 1) || (gdb_category > 16), - MYNAME ": cat must be between 1 and 16!"); - gdb_category = 1 << (gdb_category - 1); - } - - if (gdb_opt_bitcategory) { - gdb_category = strtol(gdb_opt_bitcategory, NULL, 0); - } - - if (gdb_ver >= GDB_VER_UTF8) - cet_convert_init(CET_CHARSET_UTF8, 1); - - QUEUE_INIT(&wayptq_out); - short_h = NULL; - - waypt_ct = 0; - waypth_ct = 0; - rtept_ct = 0; - trkpt_ct = 0; - rte_ct = 0; - trk_ct = 0; + fout = gbfopen_le(fname, "wb", MYNAME); + ftmp = gbfopen_le(NULL, "wb", MYNAME); + + gdb_category = (gdb_opt_category) ? atoi(gdb_opt_category) : 0; + gdb_ver = (gdb_opt_ver && *gdb_opt_ver) ? atoi(gdb_opt_ver) : 0; + + if (gdb_category) { + is_fatal((gdb_category < 1) || (gdb_category > 16), + MYNAME ": cat must be between 1 and 16!"); + gdb_category = 1 << (gdb_category - 1); + } + + if (gdb_opt_bitcategory) { + gdb_category = strtol(gdb_opt_bitcategory, NULL, 0); + } + + if (gdb_ver >= GDB_VER_UTF8) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + QUEUE_INIT(&wayptq_out); + short_h = NULL; + + waypt_ct = 0; + waypth_ct = 0; + rtept_ct = 0; + trkpt_ct = 0; + rte_ct = 0; + trk_ct = 0; } static void gdb_wr_deinit(void) { - disp_summary(fout); - gdb_flush_waypt_queue(&wayptq_out); - mkshort_del_handle(&short_h); - gbfclose(fout); - gbfclose(ftmp); + disp_summary(fout); + gdb_flush_waypt_queue(&wayptq_out); + mkshort_del_handle(&short_h); + gbfclose(fout); + gbfclose(ftmp); } static void write_data(void) { - if (gdb_opt_ver) gdb_ver = atoi(gdb_opt_ver); - write_header(); - - reset_short_handle("WPT"); - route_flag = 0; - waypt_disp_all(write_waypoint_cb); - route_flag = 1; - route_disp_all(NULL, NULL, write_waypoint_cb); - - reset_short_handle("Route"); - route_disp_all(write_route_cb, NULL, NULL); - - reset_short_handle("Track"); - track_disp_all(write_track_cb, NULL, NULL); - - FWRITE_i32(2); /* finalize gdb with empty map segment */ - FWRITE_CSTR("V"); - FWRITE_C(1); + if (gdb_opt_ver) { + gdb_ver = atoi(gdb_opt_ver); + } + write_header(); + + reset_short_handle("WPT"); + route_flag = 0; + waypt_disp_all(write_waypoint_cb); + route_flag = 1; + route_disp_all(NULL, NULL, write_waypoint_cb); + + reset_short_handle("Route"); + route_disp_all(write_route_cb, NULL, NULL); + + reset_short_handle("Track"); + track_disp_all(write_track_cb, NULL, NULL); + + FWRITE_i32(2); /* finalize gdb with empty map segment */ + FWRITE_CSTR("V"); + FWRITE_C(1); } /*******************************************************************************/ @@ -1724,37 +1849,47 @@ write_data(void) #define GDB_OPT_ROADBOOK "roadbook" static arglist_t gdb_args[] = { - {GDB_OPT_CATEGORY, &gdb_opt_category, - "Default category on output (1..16)", - NULL, ARGTYPE_INT, "1", "16"}, - {GDB_OPT_BITCATEGORY, &gdb_opt_bitcategory, "Bitmap of categories", - NULL, ARGTYPE_INT, "1", "65535"}, - {GDB_OPT_VER, &gdb_opt_ver, - "Version of gdb file to generate (1..3)", - "2", ARGTYPE_INT, "1", "3"}, - {GDB_OPT_VIA, &gdb_opt_via, - "Drop route points that do not have an equivalent waypoint (hidden points)", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {GDB_OPT_ROADBOOK, &gdb_opt_roadbook, - "Include major turn points (with description) from calculated route", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - - ARG_TERMINATOR + { + GDB_OPT_CATEGORY, &gdb_opt_category, + "Default category on output (1..16)", + NULL, ARGTYPE_INT, "1", "16" + }, + { + GDB_OPT_BITCATEGORY, &gdb_opt_bitcategory, "Bitmap of categories", + NULL, ARGTYPE_INT, "1", "65535" + }, + { + GDB_OPT_VER, &gdb_opt_ver, + "Version of gdb file to generate (1..3)", + "2", ARGTYPE_INT, "1", "3" + }, + { + GDB_OPT_VIA, &gdb_opt_via, + "Drop route points that do not have an equivalent waypoint (hidden points)", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + GDB_OPT_ROADBOOK, &gdb_opt_roadbook, + "Include major turn points (with description) from calculated route", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + + ARG_TERMINATOR }; ff_vecs_t gdb_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - gdb_rd_init, - gdb_wr_init, - gdb_rd_deinit, - gdb_wr_deinit, - read_data, - write_data, - NULL, - gdb_args, - CET_CHARSET_MS_ANSI, 0 /* O.K.: changed to NON-FIXED */ - /* because of utf8 strings since GDB V3 */ + ff_type_file, + FF_CAP_RW_ALL, + gdb_rd_init, + gdb_wr_init, + gdb_rd_deinit, + gdb_wr_deinit, + read_data, + write_data, + NULL, + gdb_args, + CET_CHARSET_MS_ANSI, 0 /* O.K.: changed to NON-FIXED */ + /* because of utf8 strings since GDB V3 */ }; /*******************************************************************************/ diff --git a/gpsbabel/geo.c b/gpsbabel/geo.c index 55ea7955b..c897613a1 100644 --- a/gpsbabel/geo.c +++ b/gpsbabel/geo.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2002 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -19,18 +19,18 @@ #include "defs.h" #include "xmlgeneric.h" -static char *deficon = NULL; -static char *nuke_placer; +static char* deficon = NULL; +static char* nuke_placer; -static waypoint *wpt_tmp; +static waypoint* wpt_tmp; -static gbfile *ofd; +static gbfile* ofd; static arglist_t geo_args[] = { - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"nuke_placer", &nuke_placer, "Omit Placer name", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"nuke_placer", &nuke_placer, "Omit Placer name", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define MYNAME "geo" @@ -38,9 +38,9 @@ arglist_t geo_args[] = { #if ! HAVE_LIBEXPAT static void -geo_rd_init(const char *fname) +geo_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded GEO support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded GEO support because expat was not installed.\n"); } void @@ -52,178 +52,270 @@ geo_read(void) static xg_callback wpt_s, wpt_e; static xg_callback wpt_link_s, wpt_link; static xg_callback wpt_name, wpt_name_s, wpt_type, wpt_coord; +static xg_callback wpt_diff, wpt_terr, wpt_container; -static +static xg_tag_mapping loc_map[] = { - { wpt_s, cb_start, "/loc/waypoint" }, - { wpt_e, cb_end, "/loc/waypoint" }, - { wpt_name_s, cb_start, "/loc/waypoint/name" }, - { wpt_name, cb_cdata, "/loc/waypoint/name" }, - { wpt_type, cb_cdata, "/loc/waypoint/type" }, - { wpt_link_s, cb_start, "/loc/waypoint/link" }, - { wpt_link, cb_cdata, "/loc/waypoint/link" }, - { wpt_coord, cb_start, "/loc/waypoint/coord" }, - { NULL, 0, NULL } + { wpt_s, cb_start, "/loc/waypoint" }, + { wpt_e, cb_end, "/loc/waypoint" }, + { wpt_name_s, cb_start, "/loc/waypoint/name" }, + { wpt_name, cb_cdata, "/loc/waypoint/name" }, + { wpt_type, cb_cdata, "/loc/waypoint/type" }, + { wpt_link_s, cb_start, "/loc/waypoint/link" }, + { wpt_link, cb_cdata, "/loc/waypoint/link" }, + { wpt_coord, cb_start, "/loc/waypoint/coord" }, + { wpt_diff, cb_cdata, "/loc/waypoint/difficulty" }, + { wpt_terr, cb_cdata, "/loc/waypoint/terrain" }, + { wpt_container,cb_cdata, "/loc/waypoint/container" }, + { NULL, (xg_cb_type)0, NULL } }; -void wpt_s(const char *args, const char **unused) -{ - wpt_tmp = waypt_new(); - /* - * 'geo' doesn't really have an 'unknown' and doesn't have any - * concept of alt. Unfortunately, we have many reference files - * that have leaked the 'unknown_alt' value into them, so we paper - * over that here. - */ - wpt_tmp->altitude = 0; +void wpt_s(const char* args, const char** unused) +{ + wpt_tmp = waypt_new(); + /* + * 'geo' doesn't really have an 'unknown' and doesn't have any + * concept of alt. Unfortunately, we have many reference files + * that have leaked the 'unknown_alt' value into them, so we paper + * over that here. + */ + wpt_tmp->altitude = 0; } -void wpt_e(const char *args, const char **unused) +void wpt_e(const char* args, const char** unused) { - waypt_add(wpt_tmp); + waypt_add(wpt_tmp); } -void wpt_name_s(const char *args, const char **attrv) +void wpt_name_s(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "id")) { - wpt_tmp->shortname = xstrdup(avp[1]); - } - avp+=2; - } + const char** avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "id")) { + wpt_tmp->shortname = xstrdup(avp[1]); + } + avp+=2; + } } -void wpt_name(const char *args, const char **unused) +void wpt_name(const char* args, const char** unused) { - char *s; - if (!args) return; - - wpt_tmp->description = xstrappend(wpt_tmp->description,args); - s = xstrrstr(wpt_tmp->description, " by "); - if (s) { - waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(s + 4); + char* s; + if (!args) { + return; + } + + wpt_tmp->description = xstrappend(wpt_tmp->description,args); + s = xstrrstr(wpt_tmp->description, " by "); + if (s) { + waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(s + 4); + + if (nuke_placer) { + *s = '\0'; + } + } +} - if (nuke_placer) { - *s = '\0'; - } - } +void wpt_link_s(const char* args, const char** attrv) +{ + const char** avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "text")) { + wpt_tmp->url_link_text = xstrdup(avp[1]); + } + avp+=2; + } +} +void wpt_link(const char* args, const char** attrv) +{ + wpt_tmp->url = xstrdup(args); } -void wpt_link_s(const char *args, const char **attrv) +void wpt_type(const char* args, const char** unused) { - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "text")) { - wpt_tmp->url_link_text = xstrdup(avp[1]); - } - avp+=2; - } + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(args); } -void wpt_link(const char *args, const char **attrv) + +void wpt_coord(const char* args, const char** attrv) { - wpt_tmp->url = xstrdup(args); + const char** avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->longitude); + } + avp+=2; + } } -void wpt_type(const char *args, const char **unused) +void wpt_container(const char* args, const char** unused) { - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - wpt_tmp->icon_descr = xstrdup(args); + int v; + + if (!args) { + return; + } + switch (atoi(args)) { + case 1: + v = gc_unknown; + break; + case 2: + v = gc_micro; + break; + case 3: + v = gc_regular; + break; + case 4: + v = gc_large; + break; + case 5: + v = gc_virtual;; + break; + case 6: + v = gc_other; + break; + case 8: + v = gc_small; + break; + default: + v = gc_unknown; + break; + } + waypt_alloc_gc_data(wpt_tmp)->container = v; } -void wpt_coord(const char *args, const char **attrv) +void wpt_diff(const char* args, const char** unused) { - const char **avp = &attrv[0]; + if (!args) { + return; + } + waypt_alloc_gc_data(wpt_tmp)->diff = atof(args) * 10; +} - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->longitude); - } - avp+=2; - } +void wpt_terr(const char* args, const char** unused) +{ + if (!args) { + return; + } + waypt_alloc_gc_data(wpt_tmp)->terr = atof(args) * 10; } static void -geo_rd_init(const char *fname) +geo_rd_init(const char* fname) { - xml_init(fname, loc_map, NULL); + xml_init(fname, loc_map, NULL); } static void geo_read(void) { - xml_read(); + xml_read(); } #endif static void geo_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void -geo_wr_init(const char *fname) +geo_wr_init(const char* fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void geo_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static void -geo_waypt_pr(const waypoint *waypointp) +geo_waypt_pr(const waypoint* waypointp) { - char *tmp; - - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "", waypointp->shortname); - gbfprintf(ofd, "", waypointp->description); - gbfprintf(ofd, "\n"); - - gbfprintf(ofd, "", - waypointp->latitude, - waypointp->longitude); - gbfprintf(ofd, "\n"); - - if (waypointp->icon_descr) { - gbfprintf(ofd, "%s\n", deficon ? deficon : waypointp->icon_descr); - } - if (waypointp->url) { - tmp = xml_entitize(waypointp->url); - gbfprintf(ofd, "%s\n", - tmp); - xfree(tmp); - } - gbfprintf(ofd, "\n"); + char* tmp; + + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "", waypointp->shortname); + gbfprintf(ofd, "", waypointp->description); + gbfprintf(ofd, "\n"); + + gbfprintf(ofd, "", + waypointp->latitude, + waypointp->longitude); + gbfprintf(ofd, "\n"); + + if (waypointp->icon_descr) { + gbfprintf(ofd, "%s\n", deficon ? deficon : waypointp->icon_descr); + } + if (waypointp->url) { + tmp = xml_entitize(waypointp->url); + gbfprintf(ofd, "%s\n", + tmp); + xfree(tmp); + } + if (waypointp->gc_data && waypointp->gc_data->diff) { + int v; + + gbfprintf(ofd, "%.1lf\n", + waypointp->gc_data->diff / 10.0); + gbfprintf(ofd, "%.1lf\n", + waypointp->gc_data->terr / 10.0); + switch (waypointp->gc_data->container) { + case gc_unknown: + v = 1; + break; + case gc_micro: + v = 2; + break; + case gc_regular: + v = 3; + break; + case gc_large: + v = 4; + break; + case gc_virtual: + v = 5; + break; + case gc_other: + v = 6; + break; + case gc_small: + v = 8; + break; + default: + v = 1; + break; + } + gbfprintf(ofd, "%d\n", v); + } + gbfprintf(ofd, "\n"); } static void geo_write(void) { - gbfprintf(ofd, "\n"); - waypt_disp_all(geo_waypt_pr); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + waypt_disp_all(geo_waypt_pr); + gbfprintf(ofd, "\n"); } ff_vecs_t geo_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none }, - geo_rd_init, - geo_wr_init, - geo_rd_deinit, - geo_wr_deinit, - geo_read, - geo_write, - NULL, - geo_args, - CET_CHARSET_UTF8, 0 /* CET-REVIEW */ + ff_type_file, + { (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none, ff_cap_none }, + geo_rd_init, + geo_wr_init, + geo_rd_deinit, + geo_wr_deinit, + geo_read, + geo_write, + NULL, + geo_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/geoniche.c b/gpsbabel/geoniche.c index 65f84a9ea..4e9e0d059 100644 --- a/gpsbabel/geoniche.c +++ b/gpsbabel/geoniche.c @@ -36,22 +36,26 @@ #undef GEONICHE_DBG -static pdbfile *file_in, *file_out; -static const char *FilenameOut; +static pdbfile* file_in, *file_out; +static const char* FilenameOut; static int rec_ct; static int ct; static char Rec0Magic[] = "68000NV4Q2"; -static char *Arg_dbname = NULL; -static char *Arg_category = NULL; +static char* Arg_dbname = NULL; +static char* Arg_category = NULL; static arglist_t Args[] = { - {"dbname", &Arg_dbname, - "Database name (filename)", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"category", &Arg_category, - "Category name (Cache)", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "dbname", &Arg_dbname, + "Database name (filename)", NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "category", &Arg_category, + "Category name (Cache)", NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #define ARG_FREE(X) do { if (X) { xfree(X); X = NULL; } } while (0) @@ -63,717 +67,787 @@ static char GcSet[] = "0123456789ABCDEFGHJKMNPQRTVWXYZ"; static int GcOffset = 16 * 31 * 31 * 31 - 65536; static int -gid2id(char *gid) +gid2id(char* gid) { - char *p; - int i, val; - - if (strncmp(gid, "GC", 2) != 0) - return -1; - if (strlen(gid) != 6) - return -1; - gid += 2; - - if (strcmp(gid, "G000") < 0) - return strtol(gid, NULL, 16); - - for (val = i = 0; i < 4; ++i) - { - val *= 31; - p = strchr(GcSet, gid[i]); - if (!p) return -1; - val += p - GcSet; - } - return val - GcOffset; + char* p; + int i, val; + + if (strncmp(gid, "GC", 2) != 0) { + return -1; + } + if (strlen(gid) != 6) { + return -1; + } + gid += 2; + + if (strcmp(gid, "G000") < 0) { + return strtol(gid, NULL, 16); + } + + for (val = i = 0; i < 4; ++i) { + val *= 31; + p = strchr(GcSet, gid[i]); + if (!p) { + return -1; + } + val += p - GcSet; + } + return val - GcOffset; } static void id2gid(char gid[6+1], int id) { - gid[0] = 0; - if (id < 0) - return; - else if (id < 65536) - snprintf(gid, 6+1, "GC%04X", id); - else - { - int i; - - id += GcOffset; - gid[0] = 'G'; - gid[1] = 'C'; - for (i = 5; i >= 2; --i) { - gid[i] = GcSet[id%31]; - id /= 31; - } - gid[6] = 0; - if (id) - gid[0] = 0; - } + gid[0] = 0; + if (id < 0) { return; + } else if (id < 65536) { + snprintf(gid, 6+1, "GC%04X", id); + } else { + int i; + + id += GcOffset; + gid[0] = 'G'; + gid[1] = 'C'; + for (i = 5; i >= 2; --i) { + gid[i] = GcSet[id%31]; + id /= 31; + } + gid[6] = 0; + if (id) { + gid[0] = 0; + } + } + return; } static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - ARG_FREE(Arg_dbname); - ARG_FREE(Arg_category); + pdb_close(file_in); + ARG_FREE(Arg_dbname); + ARG_FREE(Arg_category); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - FilenameOut = fname; + file_out = pdb_create(fname, MYNAME); + FilenameOut = fname; } static void wr_deinit(void) { - pdb_close(file_out); - ARG_FREE(Arg_dbname); - ARG_FREE(Arg_category); + pdb_close(file_out); + ARG_FREE(Arg_dbname); + ARG_FREE(Arg_category); } -static char * -field(char **pp, int *lenp) +static char* +field(char** pp, int* lenp) { - int len = *lenp; - char *p = *pp; - char *dp, *dbuf; - int state = 0; - - if (len == 0 || *p == 0) - return NULL; - - dbuf = dp = xmalloc(len); - while (len) - { - char ch; - - ch = *p++; - --len; - if (ch == 0 || len == 0) - break; - switch (state) - { - case 0: - if (ch == '\\') - state = 1; - else if (ch == ',') - goto eof; - else - *dp++ = ch; - break; - default: - *dp++ = ch; - state = 0; - break; - } + int len = *lenp; + char* p = *pp; + char* dp, *dbuf; + int state = 0; + + if (len == 0 || *p == 0) { + return NULL; + } + + dbuf = dp = (char*) xmalloc(len); + while (len) { + char ch; + + ch = *p++; + --len; + if (ch == 0 || len == 0) { + break; + } + switch (state) { + case 0: + if (ch == '\\') { + state = 1; + } else if (ch == ',') { + goto eof; + } else { + *dp++ = ch; + } + break; + default: + *dp++ = ch; + state = 0; + break; } + } eof: - *dp++ = 0; - dbuf = xrealloc(dbuf, dp - dbuf); - /* fprintf(stderr, "<%.8s> dbuf=%x, len=%d\n", *pp, dbuf, len); */ - *pp = p; - *lenp = len; - return dbuf; + *dp++ = 0; + dbuf = (char*) xrealloc(dbuf, dp - dbuf); + /* fprintf(stderr, "<%.8s> dbuf=%x, len=%d\n", *pp, dbuf, len); */ + *pp = p; + *lenp = len; + return dbuf; } static void geoniche_read_asc(void) { - pdbrec_t *pdb_rec; - - /* Process record 0 */ - pdb_rec = file_in->rec_list; - if (strcmp((char *) pdb_rec->data, Rec0Magic)) - fatal(MYNAME ": Bad record 0, not a GeoNiche file.\n"); - pdb_rec = pdb_rec->next; - - /* Process the rest of the records */ - for (; pdb_rec; pdb_rec = pdb_rec->next) - { - waypoint *wpt; - char *vdata; - int vlen; - char *p; - - int id; - int route_id; - char *title; - char *category; - double lat, lon, alt; - char *datestr, *timestr; - int icon; - char *notes; - char gid[6+1]; - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - wpt = waypt_new(); - if (!wpt) - fatal(MYNAME ": Couldn't allocate waypoint.\n"); - vdata = (char *) pdb_rec->data; - vlen = pdb_rec->size; - - /* Field 1: Target */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 1 (target).\n"); - if (strcmp(p, "Route") == 0) - fatal(MYNAME ": Route record type is not implemented.\n"); - if (strcmp(p, "Target")) - fatal(MYNAME ": Unknown record type '%s'.\n", p); - xfree(p); - - /* Field 2: Import ID number */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 2 (ID).\n"); - id = atoi(p); - xfree(p); - - /* Field 3: Title */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 3 (Title).\n"); - title = p; - - /* Field 4: Route ID number */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 4 (Route ID).\n"); - route_id = atoi(p); - xfree(p); - - /* Field 5: Category */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 5 (Category).\n"); - category = p; - - /* Field 6: Latitude */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 6 (Latitude).\n"); - lat = atof(p); - xfree(p); - - /* Field 7: Longitude */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 7 (Longitude).\n"); - lon = atof(p); - xfree(p); - - /* Field 8: Altitude */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 8 (Altitude).\n"); - alt = atof(p); - xfree(p); - - /* Field 9: Creation date */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 9 (Creation date).\n"); - datestr = p; - - /* Field 10: Creation time */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 10 (Creation time).\n"); - timestr = p; - - /* Field 11: Visited date */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 11 (Visited date).\n"); - xfree(p); - - /* Field 12: Visited time */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 12 (Visited time).\n"); - xfree(p); - - /* Field 13: Icon color (R G B) */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 13 (Icon color).\n"); - xfree(p); - - /* Field 14: icon number */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 14 (Icon number).\n"); - icon = atoi(p); - xfree(p); - - /* Field 15: unused */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 15 (unused1).\n"); - xfree(p); - - /* Field 16: unused */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 16 (unused2).\n"); - xfree(p); - - /* Field 17: unused */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 17 (unused3).\n"); - xfree(p); - - /* Field 18: Notes */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 18 (Notes).\n"); - notes = p; - - sscanf(datestr, "%d/%d/%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - sscanf(timestr, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - if (tm.tm_year >= 1970) { - wpt->creation_time = mktime(&tm); - } - xfree(datestr); - xfree(timestr); - - id2gid(gid, id); - wpt->latitude = lat; - wpt->longitude = lon; - wpt->altitude = alt; - wpt->icon_descr = category; - wpt->wpt_flags.icon_descr_is_dynamic = 1; - - if (gid[0]) - { - wpt->shortname = xstrdup(gid); - wpt->description = title; - wpt->notes = notes; - } - else - { - wpt->shortname = xstrdup(title); - wpt->description = title; - wpt->notes = notes; - } - - waypt_add(wpt); - } + pdbrec_t* pdb_rec; + + /* Process record 0 */ + pdb_rec = file_in->rec_list; + if (strcmp((char*) pdb_rec->data, Rec0Magic)) { + fatal(MYNAME ": Bad record 0, not a GeoNiche file.\n"); + } + pdb_rec = pdb_rec->next; + + /* Process the rest of the records */ + for (; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint* wpt; + char* vdata; + int vlen; + char* p; + + int id; + int route_id; + char* title; + char* category; + double lat, lon, alt; + char* datestr, *timestr; + int icon; + char* notes; + char gid[6+1]; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + wpt = waypt_new(); + if (!wpt) { + fatal(MYNAME ": Couldn't allocate waypoint.\n"); + } + vdata = (char*) pdb_rec->data; + vlen = pdb_rec->size; + + /* Field 1: Target */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 1 (target).\n"); + } + if (strcmp(p, "Route") == 0) { + fatal(MYNAME ": Route record type is not implemented.\n"); + } + if (strcmp(p, "Target")) { + fatal(MYNAME ": Unknown record type '%s'.\n", p); + } + xfree(p); + + /* Field 2: Import ID number */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 2 (ID).\n"); + } + id = atoi(p); + xfree(p); + + /* Field 3: Title */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 3 (Title).\n"); + } + title = p; + + /* Field 4: Route ID number */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 4 (Route ID).\n"); + } + route_id = atoi(p); + xfree(p); + + /* Field 5: Category */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 5 (Category).\n"); + } + category = p; + + /* Field 6: Latitude */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 6 (Latitude).\n"); + } + lat = atof(p); + xfree(p); + + /* Field 7: Longitude */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 7 (Longitude).\n"); + } + lon = atof(p); + xfree(p); + + /* Field 8: Altitude */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 8 (Altitude).\n"); + } + alt = atof(p); + xfree(p); + + /* Field 9: Creation date */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 9 (Creation date).\n"); + } + datestr = p; + + /* Field 10: Creation time */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 10 (Creation time).\n"); + } + timestr = p; + + /* Field 11: Visited date */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 11 (Visited date).\n"); + } + xfree(p); + + /* Field 12: Visited time */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 12 (Visited time).\n"); + } + xfree(p); + + /* Field 13: Icon color (R G B) */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 13 (Icon color).\n"); + } + xfree(p); + + /* Field 14: icon number */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 14 (Icon number).\n"); + } + icon = atoi(p); + xfree(p); + + /* Field 15: unused */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 15 (unused1).\n"); + } + xfree(p); + + /* Field 16: unused */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 16 (unused2).\n"); + } + xfree(p); + + /* Field 17: unused */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 17 (unused3).\n"); + } + xfree(p); + + /* Field 18: Notes */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 18 (Notes).\n"); + } + notes = p; + + sscanf(datestr, "%d/%d/%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + sscanf(timestr, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + if (tm.tm_year >= 1970) { + wpt->creation_time = mktime(&tm); + } + xfree(datestr); + xfree(timestr); + + id2gid(gid, id); + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; + wpt->icon_descr = category; + wpt->wpt_flags.icon_descr_is_dynamic = 1; + + if (gid[0]) { + wpt->shortname = xstrdup(gid); + wpt->description = title; + wpt->notes = notes; + } else { + wpt->shortname = xstrdup(title); + wpt->description = title; + wpt->notes = notes; + } + + waypt_add(wpt); + } } -static const char *geoniche_icon_map[] = /* MPS */ +static const char* geoniche_icon_map[] = /* MPS */ { - /* 21 */ "Cross", - /* 22 */ "Cross (light)", - /* 23 */ "Cross (little)", - /* 24 */ "Cross (straight)", - /* 25 */ "Cross (light straight)", - /* 26 */ "Cross (little straight)", - /* 27 */ NULL, - /* 28 */ NULL, - /* 29 */ NULL, - /* 2A */ "Flag", - /* 2B */ "Car", /* 56 */ - /* 2C */ "Gas Station", /* 8 */ - /* 2D */ "Observation Point", - /* 2E */ "Scenic Area", /* 48 */ - /* 2F */ "City", - /* 30 */ "Mountains", - /* 31 */ "Park", /* 46 */ - /* 32 */ "Forest", /* 105 */ - /* 33 */ "Campground", /* 38 */ - /* 34 */ NULL, - /* 35 */ "Men", - /* 36 */ "Woman", - /* 37 */ "Hotel", /* 59 */ - /* 38 */ "Residence", /* 10 */ - /* 39 */ "Restaurant", /* 11 */ - /* 3A */ "Cafe", - /* 3B */ NULL, - /* 3C */ "Airport", /* 107 */ - /* 3D */ "Medical Facility", /* 43 */ - /* 3E */ "Ropeway", - /* 3F */ "Sailing Area", - /* 40 */ "Anchor", - /* 41 */ NULL, /* Half Anchor ??? */ - /* 42 */ "Fishing Area", /* 7 */ - /* 43 */ "Stop Sign", - /* 44 */ "Question Sign", - /* 45 */ NULL, - /* 46 */ NULL, - /* 47 */ "Euro Sign", - /* 48 */ "Bank", /* 6 */ - /* 49 */ NULL, - /* 4A */ "Left Arrow", - /* 4B */ "Right Arrow", - /* 4C */ "Traditional Cache", - /* 4D */ "Multi-Cache", /* 86 */ - /* 4E */ "Virtual Cache", /* 48 */ - /* 4F */ "Letterbox Cache", - /* 50 */ "Event Cache", /* 47 */ - /* 51 */ "Webcam Cache", /* 90 */ - /* 52 */ "Mystery or puzzle Cache", + /* 21 */ "Cross", + /* 22 */ "Cross (light)", + /* 23 */ "Cross (little)", + /* 24 */ "Cross (straight)", + /* 25 */ "Cross (light straight)", + /* 26 */ "Cross (little straight)", + /* 27 */ NULL, + /* 28 */ NULL, + /* 29 */ NULL, + /* 2A */ "Flag", + /* 2B */ "Car", /* 56 */ + /* 2C */ "Gas Station", /* 8 */ + /* 2D */ "Observation Point", + /* 2E */ "Scenic Area", /* 48 */ + /* 2F */ "City", + /* 30 */ "Mountains", + /* 31 */ "Park", /* 46 */ + /* 32 */ "Forest", /* 105 */ + /* 33 */ "Campground", /* 38 */ + /* 34 */ NULL, + /* 35 */ "Men", + /* 36 */ "Woman", + /* 37 */ "Hotel", /* 59 */ + /* 38 */ "Residence", /* 10 */ + /* 39 */ "Restaurant", /* 11 */ + /* 3A */ "Cafe", + /* 3B */ NULL, + /* 3C */ "Airport", /* 107 */ + /* 3D */ "Medical Facility", /* 43 */ + /* 3E */ "Ropeway", + /* 3F */ "Sailing Area", + /* 40 */ "Anchor", + /* 41 */ NULL, /* Half Anchor ??? */ + /* 42 */ "Fishing Area", /* 7 */ + /* 43 */ "Stop Sign", + /* 44 */ "Question Sign", + /* 45 */ NULL, + /* 46 */ NULL, + /* 47 */ "Euro Sign", + /* 48 */ "Bank", /* 6 */ + /* 49 */ NULL, + /* 4A */ "Left Arrow", + /* 4B */ "Right Arrow", + /* 4C */ "Traditional Cache", + /* 4D */ "Multi-Cache", /* 86 */ + /* 4E */ "Virtual Cache", /* 48 */ + /* 4F */ "Letterbox Cache", + /* 50 */ "Event Cache", /* 47 */ + /* 51 */ "Webcam Cache", /* 90 */ + /* 52 */ "Mystery or puzzle Cache", }; -static const char * +static const char* geoniche_icon_to_descr(const int no) { - const char *result = NULL; + const char* result = NULL; - if (no >= 0x21) - { - int i = no - 0x21; - if (i <= 49) - { - result = geoniche_icon_map[i]; - } + if (no >= 0x21) { + int i = no - 0x21; + if (i <= 49) { + result = geoniche_icon_map[i]; } - if (result != NULL) - { - result = xstrdup(result); - } - return result; + } + if (result != NULL) { + result = xstrdup(result); + } + return result; } static void geoniche_read_bin(void) { - pdbrec_t *pdb_rec; - - /* Process records */ - - for (pdb_rec = file_in->rec_list; pdb_rec != NULL; pdb_rec = pdb_rec->next) - { - char *vdata = (char *) pdb_rec->data; - struct tm created, visited; - int icon_nr, selected; - int latdeg, londeg; - double lat, lon, altitude; - waypoint *waypt; - - memset(&visited, 0, sizeof(visited)); - memset(&created, 0, sizeof(created)); - - latdeg = be_read16(vdata + 0); - lat = be_read32(vdata + 2); - londeg = be_read16(vdata + 6); - lon = be_read32(vdata + 8); - altitude = (float) be_read32(vdata + 12); - selected = vdata[16]; - created.tm_min = be_read16(vdata + 20); - created.tm_hour = be_read16(vdata + 22); - created.tm_mday = be_read16(vdata + 24); - created.tm_mon = be_read16(vdata + 26); - created.tm_year = be_read16(vdata + 28); - visited.tm_min = be_read16(vdata + 34); - visited.tm_hour = be_read16(vdata + 36); - visited.tm_mday = be_read16(vdata + 38); - visited.tm_mon = be_read16(vdata + 40); - visited.tm_year = be_read16(vdata + 42); + pdbrec_t* pdb_rec; + + /* Process records */ + + for (pdb_rec = file_in->rec_list; pdb_rec != NULL; pdb_rec = pdb_rec->next) { + char* vdata = (char*) pdb_rec->data; + struct tm created, visited; + int icon_nr, selected; + int latdeg, londeg; + double lat, lon, altitude; + waypoint* waypt; + + memset(&visited, 0, sizeof(visited)); + memset(&created, 0, sizeof(created)); + + latdeg = be_read16(vdata + 0); + lat = be_read32(vdata + 2); + londeg = be_read16(vdata + 6); + lon = be_read32(vdata + 8); + altitude = (float) be_read32(vdata + 12); + selected = vdata[16]; + created.tm_min = be_read16(vdata + 20); + created.tm_hour = be_read16(vdata + 22); + created.tm_mday = be_read16(vdata + 24); + created.tm_mon = be_read16(vdata + 26); + created.tm_year = be_read16(vdata + 28); + visited.tm_min = be_read16(vdata + 34); + visited.tm_hour = be_read16(vdata + 36); + visited.tm_mday = be_read16(vdata + 38); + visited.tm_mon = be_read16(vdata + 40); + visited.tm_year = be_read16(vdata + 42); #ifdef GEONICHE_DBG - printf(MYNAME "-date: %04d/%02d/%02d, %02d:%02d (%04d/%02d/%02d, %02d:%02d)\n", - created.tm_year, created.tm_mon, created.tm_mday, created.tm_hour, created.tm_min, - visited.tm_year, visited.tm_mon, visited.tm_mday, visited.tm_hour, visited.tm_min); + printf(MYNAME "-date: %04d/%02d/%02d, %02d:%02d (%04d/%02d/%02d, %02d:%02d)\n", + created.tm_year, created.tm_mon, created.tm_mday, created.tm_hour, created.tm_min, + visited.tm_year, visited.tm_mon, visited.tm_mday, visited.tm_hour, visited.tm_min); #endif - icon_nr = vdata[62]; - - latdeg = 89 - latdeg; - lat = lat * (double) 0.0000006; - if (latdeg >= 0) - lat = (double) 60.0 - lat; - else - latdeg++; - - lon = lon * (double) 0.0000006; - while (londeg >= 360) londeg-=360; - if (londeg > 180) - { - lon = (double) 60.0 - lon; - londeg = londeg - 359; - } - - created.tm_year-=1900; - created.tm_mon--; - - waypt = waypt_new(); - - waypt->shortname = xstrdup(vdata + 63); - waypt->altitude = altitude; - waypt->creation_time = mkgmtime(&created); - - GPS_Math_DegMin_To_Deg(latdeg, lat, &waypt->latitude); - GPS_Math_DegMin_To_Deg(londeg, lon, &waypt->longitude); - - waypt->icon_descr = geoniche_icon_to_descr(icon_nr); - if (waypt->icon_descr != NULL) - waypt->wpt_flags.icon_descr_is_dynamic = 1; - - waypt_add(waypt); + icon_nr = vdata[62]; + + latdeg = 89 - latdeg; + lat = lat * (double) 0.0000006; + if (latdeg >= 0) { + lat = (double) 60.0 - lat; + } else { + latdeg++; + } + + lon = lon * (double) 0.0000006; + while (londeg >= 360) { + londeg-=360; + } + if (londeg > 180) { + lon = (double) 60.0 - lon; + londeg = londeg - 359; + } + + created.tm_year-=1900; + created.tm_mon--; + + waypt = waypt_new(); + + waypt->shortname = xstrdup(vdata + 63); + waypt->altitude = altitude; + waypt->creation_time = mkgmtime(&created); + + GPS_Math_DegMin_To_Deg(latdeg, lat, &waypt->latitude); + GPS_Math_DegMin_To_Deg(londeg, lon, &waypt->longitude); + + waypt->icon_descr = geoniche_icon_to_descr(icon_nr); + if (waypt->icon_descr != NULL) { + waypt->wpt_flags.icon_descr_is_dynamic = 1; } + + waypt_add(waypt); + } } static void data_read(void) { - if (file_in->creator != MYCREATOR) - fatal(MYNAME ": Not a GeoNiche file.\n"); - - switch(file_in->type) - { - case MYTYPE_ASC: - geoniche_read_asc(); - break; - case MYTYPE_BIN: - geoniche_read_bin(); - break; - default: - fatal(MYNAME ": Unsupported GeoNiche file.\n"); - } + if (file_in->creator != MYCREATOR) { + fatal(MYNAME ": Not a GeoNiche file.\n"); + } + + switch (file_in->type) { + case MYTYPE_ASC: + geoniche_read_asc(); + break; + case MYTYPE_BIN: + geoniche_read_bin(); + break; + default: + fatal(MYNAME ": Unsupported GeoNiche file.\n"); + } } -static char * -enscape(char *s) +static char* +enscape(char* s) { - char *buf, *d; + char* buf, *d; - if (!s) - { - d = xmalloc(1); - *d = 0; - return d; + if (!s) { + d = (char*) xmalloc(1); + *d = 0; + return d; + } + buf = d = (char*) xmalloc(strlen(s) * 2 + 1); + for (; *s; ++s) { + + /* + * 3 May 06: need to escape single quotes for v1.40 release + */ + + if (*s == '\\' || *s == ',' || *s == '\'') { + *d++ = '\\'; + *d++ = *s; } - buf = d = xmalloc(strlen(s) * 2 + 1); - for (; *s; ++s) - { -/* - * 3 May 06: need to escape single quotes for v1.40 release - */ - - if (*s == '\\' || *s == ',' || *s == '\'') - { - *d++ = '\\'; - *d++ = *s; - } - -/* 3 May 06: stop stripping for better readability - * - * else if ((*s == '\r') || (*s == '\n')) - * *d++ = ' '; - */ - else - *d++ = *s; + /* 3 May 06: stop stripping for better readability + * + * else if ((*s == '\r') || (*s == '\n')) + * *d++ = ' '; + */ + else { + *d++ = *s; } + } - *d = 0; - return buf; + *d = 0; + return buf; } /* * Attempt to map an icon description into a GeoNiche icon number */ static int -wpt2icon(const waypoint *wpt) +wpt2icon(const waypoint* wpt) { - const char *desc = wpt->icon_descr; - - if (!desc) return 0; - else if (strstr(desc, "reg")) return 43; - else if (strstr(desc, "trad")) return 43; - else if (strstr(desc, "multi")) return 44; - else if (strstr(desc, "offset")) return 44; - else if (strstr(desc, "virt")) return 45; - else if (strstr(desc, "loca")) return 45; - else if (strstr(desc, "event")) return 46; - else if (strstr(desc, "lett")) return 47; - else if (strstr(desc, "hyb")) return 47; - else if (strstr(desc, "unk")) return 48; - else if (strstr(desc, "cam")) return 49; - - switch (wpt->gc_data->type) { - case gt_traditional: return 43; - case gt_multi: return 44; - case gt_locationless: return 45; - case gt_earth: return 45; - case gt_virtual: return 45; - case gt_letterbox: return 46; - case gt_event: return 47; - case gt_cito: return 47; - case gt_suprise: return 48; - case gt_webcam: return 49; - case gt_unknown: return 0; - case gt_benchmark: return 0; - case gt_ape: return 0; - case gt_mega: return 0; - case gt_wherigo: return 0; - } + const char* desc = wpt->icon_descr; + if (!desc) { + return 0; + } else if (strstr(desc, "reg")) { + return 43; + } else if (strstr(desc, "trad")) { + return 43; + } else if (strstr(desc, "multi")) { + return 44; + } else if (strstr(desc, "offset")) { + return 44; + } else if (strstr(desc, "virt")) { + return 45; + } else if (strstr(desc, "loca")) { + return 45; + } else if (strstr(desc, "event")) { + return 46; + } else if (strstr(desc, "lett")) { + return 47; + } else if (strstr(desc, "hyb")) { + return 47; + } else if (strstr(desc, "unk")) { + return 48; + } else if (strstr(desc, "cam")) { + return 49; + } + + switch (wpt->gc_data->type) { + case gt_traditional: + return 43; + case gt_multi: + return 44; + case gt_locationless: + return 45; + case gt_earth: + return 45; + case gt_virtual: + return 45; + case gt_letterbox: + return 46; + case gt_event: + return 47; + case gt_cito: + return 47; + case gt_suprise: + return 48; + case gt_webcam: + return 49; + case gt_unknown: + return 0; + case gt_benchmark: + return 0; + case gt_ape: + return 0; + case gt_mega: + return 0; + case gt_wherigo: return 0; + } + + return 0; } -static char * -geoniche_geostuff(const waypoint *wpt) +static char* +geoniche_geostuff(const waypoint* wpt) { - char *gs = NULL, *tmp1, *tmp2, *tmp3; - char tbuf[10240]; - - if (!wpt->gc_data->terr) { - return NULL; - } - - snprintf(tbuf, sizeof(tbuf), "\n%s by %s\n\n", gs_get_cachetype(wpt->gc_data->type), wpt->gc_data->placer); - gs = xstrappend(gs, tbuf); - -/* - * 3 May 06: Removed duplicated information - * - * snprintf(tbuf, sizeof(tbuf), "Waypoint: %s %s\n", wpt->shortname, wpt->description); - * gs = xstrappend(gs, tbuf); - */ - -/* - * 3 May 06: Added container type - */ - snprintf(tbuf, sizeof(tbuf), "Container: %s\nDifficulty: %3.1f\nTerrain: %3.1f\n\n", gs_get_container(wpt->gc_data->container), wpt->gc_data->diff/10.0, wpt->gc_data->terr/10.0); - gs = xstrappend(gs, tbuf); - - tmp1 = strip_html(&wpt->gc_data->desc_short); - tmp2 = strip_html(&wpt->gc_data->desc_long); - gs = xstrappend(gs, tmp1); - gs = xstrappend(gs, tmp2); - - tmp3 = rot13(wpt->gc_data->hint); - snprintf(tbuf, sizeof(tbuf), "\n\nHint: %s\n", tmp3); - gs = xstrappend(gs, tbuf); - - xfree(tmp1); - xfree(tmp2); - xfree(tmp3); - - tmp1 = enscape(gs); - xfree(gs); - - return tmp1; + char* gs = NULL, *tmp1, *tmp2, *tmp3; + char tbuf[10240]; + + if (!wpt->gc_data->terr) { + return NULL; + } + + snprintf(tbuf, sizeof(tbuf), "\n%s by %s\n\n", gs_get_cachetype(wpt->gc_data->type), wpt->gc_data->placer); + gs = xstrappend(gs, tbuf); + + /* + * 3 May 06: Removed duplicated information + * + * snprintf(tbuf, sizeof(tbuf), "Waypoint: %s %s\n", wpt->shortname, wpt->description); + * gs = xstrappend(gs, tbuf); + */ + + /* + * 3 May 06: Added container type + */ + snprintf(tbuf, sizeof(tbuf), "Container: %s\nDifficulty: %3.1f\nTerrain: %3.1f\n\n", gs_get_container(wpt->gc_data->container), wpt->gc_data->diff/10.0, wpt->gc_data->terr/10.0); + gs = xstrappend(gs, tbuf); + + tmp1 = strip_html(&wpt->gc_data->desc_short); + tmp2 = strip_html(&wpt->gc_data->desc_long); + gs = xstrappend(gs, tmp1); + gs = xstrappend(gs, tmp2); + + tmp3 = rot13(wpt->gc_data->hint); + snprintf(tbuf, sizeof(tbuf), "\n\nHint: %s\n", tmp3); + gs = xstrappend(gs, tbuf); + + xfree(tmp1); + xfree(tmp2); + xfree(tmp3); + + tmp1 = enscape(gs); + xfree(gs); + + return tmp1; } static void -geoniche_writewpt(const waypoint *wpt) +geoniche_writewpt(const waypoint* wpt) { - int vlen; - char *vdata; - char *title; - struct tm tm; - char datestr[10+1]; - char timestr[8+1]; - char *notes; - int id; - time_t tx; - char *gs; - - if (rec_ct == 0) { - pdb_write_rec(file_out, 0, 0, ct++, Rec0Magic, sizeof(Rec0Magic)); - } - - if ( wpt->description && wpt->description[0] ) - title = enscape(wpt->description); - else - title = enscape(wpt->shortname); - - id = gid2id(wpt->shortname); - if (id < 0) - id = rec_ct; - - tx = (wpt->creation_time != 0) ? wpt->creation_time : gpsbabel_time; - if (tx == 0) { /* maybe zero during testo (freezed time) */ - strcpy(datestr, "01/01/1904"); /* this seems to be the uninitialized date value for geoniche */ - strcpy(timestr, "00:00:00"); - } - else { - tm = *localtime(&tx); - strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); - strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); - } - - /* Notes field MUST have soemthing in it */ - if (!wpt->notes || wpt->notes[0] == 0) - notes = xstrdup(title); - else - notes = enscape(wpt->notes); - - gs = geoniche_geostuff(wpt); - if (gs) { - notes = xstrappend(notes, gs); - xfree (gs); - } - /* last chance to fill notes with something */ - if (*notes == '\0') notes = xstrappend(notes, "(notes)"); - - vlen = xasprintf(&vdata, - "Target,%d,%s,,%s,%f,%f,%f,%s,%s,,,,%d,,,,%s" - , id - , title - /* route ID */ - , Arg_category ? Arg_category : "Cache" - , wpt->latitude - , wpt->longitude - , wpt->altitude - , datestr - , timestr - /* visited date */ - /* visited time */ - /* icon color R G B */ - , wpt2icon(wpt) - /* unused1 */ - /* unused2 */ - /* unused3 */ - , notes - ); - - pdb_write_rec(file_out, 0, 0, ct++, vdata, vlen + 1); - - xfree(notes); - xfree(title); - xfree(vdata); - - rec_ct++; + int vlen; + char* vdata; + char* title; + struct tm tm; + char datestr[10+1]; + char timestr[8+1]; + char* notes; + int id; + time_t tx; + char* gs; + + if (rec_ct == 0) { + pdb_write_rec(file_out, 0, 0, ct++, Rec0Magic, sizeof(Rec0Magic)); + } + + if (wpt->description && wpt->description[0]) { + title = enscape(wpt->description); + } else { + title = enscape(wpt->shortname); + } + + id = gid2id(wpt->shortname); + if (id < 0) { + id = rec_ct; + } + + tx = (wpt->creation_time != 0) ? wpt->creation_time : gpsbabel_time; + if (tx == 0) { /* maybe zero during testo (freezed time) */ + strcpy(datestr, "01/01/1904"); /* this seems to be the uninitialized date value for geoniche */ + strcpy(timestr, "00:00:00"); + } else { + tm = *localtime(&tx); + strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); + strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); + } + + /* Notes field MUST have soemthing in it */ + if (!wpt->notes || wpt->notes[0] == 0) { + notes = xstrdup(title); + } else { + notes = enscape(wpt->notes); + } + + gs = geoniche_geostuff(wpt); + if (gs) { + notes = xstrappend(notes, gs); + xfree(gs); + } + /* last chance to fill notes with something */ + if (*notes == '\0') { + notes = xstrappend(notes, "(notes)"); + } + + vlen = xasprintf(&vdata, + "Target,%d,%s,,%s,%f,%f,%f,%s,%s,,,,%d,,,,%s" + , id + , title + /* route ID */ + , Arg_category ? Arg_category : "Cache" + , wpt->latitude + , wpt->longitude + , wpt->altitude + , datestr + , timestr + /* visited date */ + /* visited time */ + /* icon color R G B */ + , wpt2icon(wpt) + /* unused1 */ + /* unused2 */ + /* unused3 */ + , notes + ); + + pdb_write_rec(file_out, 0, 0, ct++, vdata, vlen + 1); + + xfree(notes); + xfree(title); + xfree(vdata); + + rec_ct++; } static void data_write(void) { - if (Arg_dbname) { - if (case_ignore_strcmp(Arg_dbname, "GeoNiche Targets") == 0) - fatal(MYNAME ": Reserved database name!\n"); - strncpy(file_out->name, Arg_dbname, PDB_DBNAMELEN); - } - else - strncpy(file_out->name, FilenameOut, PDB_DBNAMELEN); - file_out->name[PDB_DBNAMELEN-1] = 0; - - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + (49*365 + 17*366) * (60*60*24); - file_out->type = MYTYPE_ASC; - file_out->creator = MYCREATOR; - file_out->version = 0; - file_out->revision = 1; - - rec_ct = 0; - ct = 0; - waypt_disp_all(geoniche_writewpt); + if (Arg_dbname) { + if (case_ignore_strcmp(Arg_dbname, "GeoNiche Targets") == 0) { + fatal(MYNAME ": Reserved database name!\n"); + } + strncpy(file_out->name, Arg_dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, FilenameOut, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + (49*365 + 17*366) * (60*60*24); + file_out->type = MYTYPE_ASC; + file_out->creator = MYCREATOR; + file_out->version = 0; + file_out->revision = 1; + + rec_ct = 0; + ct = 0; + waypt_disp_all(geoniche_writewpt); } -ff_vecs_t geoniche_vecs = -{ - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - Args, - CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ +ff_vecs_t geoniche_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + Args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/ggv_log.c b/gpsbabel/ggv_log.c index ef31cba31..ece06c567 100644 --- a/gpsbabel/ggv_log.c +++ b/gpsbabel/ggv_log.c @@ -29,12 +29,12 @@ #define MYNAME "ggv_log" -static gbfile *fin, *fout; +static gbfile* fin, *fout; static int ggv_log_ver; static arglist_t ggv_log_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /******************************************************************************* @@ -42,235 +42,248 @@ arglist_t ggv_log_args[] = { *******************************************************************************/ static void -ggv_log_rd_init(const char *fname) +ggv_log_rd_init(const char* fname) { - static char magic[32]; - int len = 0; - - fin = gbfopen(fname, "rb", MYNAME); - - for (;;) { - int cin; - - cin = gbfgetc(fin); - if (cin < 0) break; - - magic[len++] = cin; - - if (cin == '\0') { - double ver = 0; - char *sver; - if (strncmp(magic, "DOMGVGPS Logfile V", 18) != 0) break; - - sver = &magic[18]; - sscanf(sver, "%lf:", &ver); - ggv_log_ver = ver * 10; - if ((ggv_log_ver == 10) || (ggv_log_ver == 25)) return; /* header accepted */ - - fatal(MYNAME ": Sorry, unsupported version (%s)!\n", sver); - } - else if (len == sizeof(magic)) - break; - } - fatal(MYNAME ": Invalid header. Probably no " MYNAME " file!\n"); + static char magic[32]; + int len = 0; + + fin = gbfopen(fname, "rb", MYNAME); + + for (;;) { + int cin; + + cin = gbfgetc(fin); + if (cin < 0) { + break; + } + + magic[len++] = cin; + + if (cin == '\0') { + double ver = 0; + char* sver; + if (strncmp(magic, "DOMGVGPS Logfile V", 18) != 0) { + break; + } + + sver = &magic[18]; + sscanf(sver, "%lf:", &ver); + ggv_log_ver = ver * 10; + if ((ggv_log_ver == 10) || (ggv_log_ver == 25)) { + return; /* header accepted */ + } + + fatal(MYNAME ": Sorry, unsupported version (%s)!\n", sver); + } else if (len == sizeof(magic)) { + break; + } + } + fatal(MYNAME ": Invalid header. Probably no " MYNAME " file!\n"); } -static void +static void ggv_log_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void ggv_log_read(void) { - signed char *buf; - int bufsz = 0, len; - route_head *trk = NULL; - - switch(ggv_log_ver) { - case 10: bufsz = 0x2A; break; - case 25: bufsz = 0x6F; break; - } - - buf = xmalloc(bufsz); - - while ((len = gbfread(buf, 1, bufsz, fin))) { - int deg, min; - double xlat, xlon; - float sec; - struct tm tm; - waypoint *wpt; - - if (len != bufsz) break; - - if (trk == NULL) { - trk = route_head_alloc(); - track_add_head(trk); - } - - memset(&tm, 0, sizeof(tm)); - - wpt = waypt_new(); - - deg = (gbint16) le_read16(&buf[0]); - min = le_read16(&buf[2]); - sec = le_read_float(&buf[4]); - xlat = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); - wpt->latitude = xlat; - - deg = (gbint16) le_read16(&buf[8]); - min = le_read16(&buf[10]); - sec = le_read_float(&buf[12]); - xlon = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); - wpt->longitude = xlon; - - WAYPT_SET(wpt, course, le_read16(&buf[16 + 0])); - - if (ggv_log_ver == 10) { - double secs; - - wpt->altitude = le_read16(&buf[16 + 2]); - WAYPT_SET(wpt, speed, le_read16(&buf[16 + 4])); - tm.tm_year = le_read16(&buf[16 + 8]); - tm.tm_mon = le_read16(&buf[16 + 10]); - tm.tm_mday = le_read16(&buf[16 + 12]); - tm.tm_hour = le_read16(&buf[16 + 14]); - tm.tm_min = le_read16(&buf[16 + 16]); - secs = le_read_double(&buf[16 + 18]); - tm.tm_sec = (int)secs; - wpt->microseconds = (secs - tm.tm_sec) * 1000000; - } - else { - wpt->altitude = le_read16(&buf[16 + 4]); - wpt->sat = (unsigned char)buf[16 + 14]; - - /* other probably valid double values at offset: - - 22: 0.0 - 20.0 - 43: 0.0 - 59.0 - 51: -1.0 - 61: -1.0 - 79: .. - 20.0 ? speed over ground ? (++) - 87: ? course ? - 95: 0.0 - 3.1 (++) - 103: -1 - - */ - } - - if (wpt->altitude == 0) - wpt->altitude = unknown_alt; - - if (tm.tm_year >= 1900) { - tm.tm_year -= 1900; - if (tm.tm_mon > 0) { - tm.tm_mon--; - wpt->creation_time = mkgmtime(&tm); - } - } - - track_add_wpt(trk, wpt); - } - xfree(buf); + signed char* buf; + int bufsz = 0, len; + route_head* trk = NULL; + + switch (ggv_log_ver) { + case 10: + bufsz = 0x2A; + break; + case 25: + bufsz = 0x6F; + break; + } + + buf = (signed char*) xmalloc(bufsz); + + while ((len = gbfread(buf, 1, bufsz, fin))) { + int deg, min; + double xlat, xlon; + float sec; + struct tm tm; + waypoint* wpt; + + if (len != bufsz) { + break; + } + + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + + memset(&tm, 0, sizeof(tm)); + + wpt = waypt_new(); + + deg = (gbint16) le_read16(&buf[0]); + min = le_read16(&buf[2]); + sec = le_read_float(&buf[4]); + xlat = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); + wpt->latitude = xlat; + + deg = (gbint16) le_read16(&buf[8]); + min = le_read16(&buf[10]); + sec = le_read_float(&buf[12]); + xlon = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); + wpt->longitude = xlon; + + WAYPT_SET(wpt, course, le_read16(&buf[16 + 0])); + + if (ggv_log_ver == 10) { + double secs; + + wpt->altitude = le_read16(&buf[16 + 2]); + WAYPT_SET(wpt, speed, le_read16(&buf[16 + 4])); + tm.tm_year = le_read16(&buf[16 + 8]); + tm.tm_mon = le_read16(&buf[16 + 10]); + tm.tm_mday = le_read16(&buf[16 + 12]); + tm.tm_hour = le_read16(&buf[16 + 14]); + tm.tm_min = le_read16(&buf[16 + 16]); + secs = le_read_double(&buf[16 + 18]); + tm.tm_sec = (int)secs; + wpt->microseconds = (secs - tm.tm_sec) * 1000000; + } else { + wpt->altitude = le_read16(&buf[16 + 4]); + wpt->sat = (unsigned char)buf[16 + 14]; + + /* other probably valid double values at offset: + + 22: 0.0 - 20.0 + 43: 0.0 - 59.0 + 51: -1.0 + 61: -1.0 + 79: .. - 20.0 ? speed over ground ? (++) + 87: ? course ? + 95: 0.0 - 3.1 (++) + 103: -1 + + */ + } + + if (wpt->altitude == 0) { + wpt->altitude = unknown_alt; + } + + if (tm.tm_year >= 1900) { + tm.tm_year -= 1900; + if (tm.tm_mon > 0) { + tm.tm_mon--; + wpt->creation_time = mkgmtime(&tm); + } + } + + track_add_wpt(trk, wpt); + } + xfree(buf); } static void -ggv_log_wr_init(const char *fname) +ggv_log_wr_init(const char* fname) { - fout = gbfopen(fname, "wb", MYNAME); - - gbfputcstr("DOMGVGPS Logfile V1.0:", fout); + fout = gbfopen(fname, "wb", MYNAME); + + gbfputcstr("DOMGVGPS Logfile V1.0:", fout); } static void ggv_log_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void -ggv_log_track_head_cb(const route_head *trk) +ggv_log_track_head_cb(const route_head* trk) { - queue *elem, *tmp; - waypoint *prev = NULL; - - QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { - double latmin, lonmin, latsec, lonsec; - int latint, lonint; - double course = 0, speed = 0; - struct tm tm; - waypoint *wpt = (waypoint *)elem; - double secs = 0; - - latint = wpt->latitude; - lonint = wpt->longitude; - latmin = 60.0 * (fabs(wpt->latitude) - latint); - lonmin = 60.0 * (fabs(wpt->longitude) - lonint); - latsec = 60.0 * (latmin - floor(latmin)); - lonsec = 60.0 * (lonmin - floor(lonmin)); - - if (wpt->creation_time > 0) { - tm = *gmtime(&wpt->creation_time); - tm.tm_mon += 1; - tm.tm_year += 1900; - } - else - memset(&tm, 0, sizeof(tm)); - - if (prev != NULL) { - course = heading_true_degrees( - prev->latitude, prev->longitude, - wpt->latitude, wpt->longitude); - speed = waypt_speed(prev, wpt); - } - if (wpt->creation_time > 0) - secs = (double)tm.tm_sec + ((double)wpt->microseconds / 1000000); - - gbfputint16((gbint16) latint, fout); - gbfputint16((gbint16) latmin, fout); - gbfputflt(latsec, fout); - gbfputint16((gbint16) lonint, fout); - gbfputint16((gbint16) lonmin, fout); - gbfputflt(lonsec, fout); - gbfputint16((gbint16) course, fout); - gbfputint16((gbint16) (wpt->altitude != unknown_alt) ? wpt->altitude : 0, fout); - gbfputint16((gbint16) speed, fout); - gbfputint16(0, fout); - gbfputint16(tm.tm_year, fout); - gbfputint16(tm.tm_mon, fout); - gbfputint16(tm.tm_mday, fout); - gbfputint16(tm.tm_hour, fout); - gbfputint16(tm.tm_min, fout); - gbfputdbl(secs, fout); - - prev = wpt; - } + queue* elem, *tmp; + waypoint* prev = NULL; + + QUEUE_FOR_EACH((queue*)&trk->waypoint_list, elem, tmp) { + double latmin, lonmin, latsec, lonsec; + int latint, lonint; + double course = 0, speed = 0; + struct tm tm; + waypoint* wpt = (waypoint*)elem; + double secs = 0; + + latint = wpt->latitude; + lonint = wpt->longitude; + latmin = 60.0 * (fabs(wpt->latitude) - latint); + lonmin = 60.0 * (fabs(wpt->longitude) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + + if (wpt->creation_time > 0) { + tm = *gmtime(&wpt->creation_time); + tm.tm_mon += 1; + tm.tm_year += 1900; + } else { + memset(&tm, 0, sizeof(tm)); + } + + if (prev != NULL) { + course = heading_true_degrees( + prev->latitude, prev->longitude, + wpt->latitude, wpt->longitude); + speed = waypt_speed(prev, wpt); + } + if (wpt->creation_time > 0) { + secs = (double)tm.tm_sec + ((double)wpt->microseconds / 1000000); + } + + gbfputint16((gbint16) latint, fout); + gbfputint16((gbint16) latmin, fout); + gbfputflt(latsec, fout); + gbfputint16((gbint16) lonint, fout); + gbfputint16((gbint16) lonmin, fout); + gbfputflt(lonsec, fout); + gbfputint16((gbint16) course, fout); + gbfputint16((gbint16)(wpt->altitude != unknown_alt) ? wpt->altitude : 0, fout); + gbfputint16((gbint16) speed, fout); + gbfputint16(0, fout); + gbfputint16(tm.tm_year, fout); + gbfputint16(tm.tm_mon, fout); + gbfputint16(tm.tm_mday, fout); + gbfputint16(tm.tm_hour, fout); + gbfputint16(tm.tm_min, fout); + gbfputdbl(secs, fout); + + prev = wpt; + } } static void ggv_log_write(void) { - track_disp_all(ggv_log_track_head_cb, NULL, NULL); + track_disp_all(ggv_log_track_head_cb, NULL, NULL); } /**************************************************************************/ ff_vecs_t ggv_log_vecs = { - ff_type_file, - { - ff_cap_none, /* waypoints */ - ff_cap_read | ff_cap_write, /* tracks */ - ff_cap_none /* routes */ - }, - ggv_log_rd_init, - ggv_log_wr_init, - ggv_log_rd_deinit, - ggv_log_wr_deinit, - ggv_log_read, - ggv_log_write, - NULL, - ggv_log_args, - CET_CHARSET_ASCII, 1 + ff_type_file, + { + ff_cap_none, /* waypoints */ + (ff_cap)(ff_cap_read | ff_cap_write), /* tracks */ + ff_cap_none /* routes */ + }, + ggv_log_rd_init, + ggv_log_wr_init, + ggv_log_rd_deinit, + ggv_log_wr_deinit, + ggv_log_read, + ggv_log_write, + NULL, + ggv_log_args, + CET_CHARSET_ASCII, 1 }; /**************************************************************************/ diff --git a/gpsbabel/ggv_ovl.c b/gpsbabel/ggv_ovl.c index fbd3057a1..43a293d70 100644 --- a/gpsbabel/ggv_ovl.c +++ b/gpsbabel/ggv_ovl.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include #include #include @@ -32,29 +32,29 @@ static arglist_t ggv_ovl_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; typedef enum { - OVL_SYMBOL_BITMAP = 1, - OVL_SYMBOL_TEXT, - OVL_SYMBOL_LINE, - OVL_SYMBOL_POLYGON, - OVL_SYMBOL_RECTANGLE, - OVL_SYMBOL_CIRCLE, - OVL_SYMBOL_TRIANGLE + OVL_SYMBOL_BITMAP = 1, + OVL_SYMBOL_TEXT, + OVL_SYMBOL_LINE, + OVL_SYMBOL_POLYGON, + OVL_SYMBOL_RECTANGLE, + OVL_SYMBOL_CIRCLE, + OVL_SYMBOL_TRIANGLE } OVL_SYMBOL_TYP; typedef enum { - OVL_COLOR_RED = 1, /* = 1 */ - OVL_COLOR_LIME, /* = 2 */ - OVL_COLOR_BLUE, /* = 3 */ - OVL_COLOR_YELLOW, /* = 4 */ - OVL_COLOR_BLACK, /* = 5 */ - OVL_COLOR_WHITE, /* = 6 */ - OVL_COLOR_7, /* = 7 (draws only a simple line) */ - OVL_COLOR_FUCHSIA, /* = 8 */ - OVL_COLOR_AQUA, /* = 9 */ + OVL_COLOR_RED = 1, /* = 1 */ + OVL_COLOR_LIME, /* = 2 */ + OVL_COLOR_BLUE, /* = 3 */ + OVL_COLOR_YELLOW, /* = 4 */ + OVL_COLOR_BLACK, /* = 5 */ + OVL_COLOR_WHITE, /* = 6 */ + OVL_COLOR_7, /* = 7 (draws only a simple line) */ + OVL_COLOR_FUCHSIA, /* = 8 */ + OVL_COLOR_AQUA, /* = 9 */ } OVL_COLOR_TYP; /* some hints: @@ -65,8 +65,8 @@ typedef enum { # "zoom": # "art": line-style */ -static inifile_t *inifile; -static gbfile *fout; +static inifile_t* inifile; +static gbfile* fout; static int symbol_ct; /* Number of symbols written */ static int group_ct; /* Group number during write */ @@ -79,362 +79,387 @@ static OVL_COLOR_TYP color; *******************************************************************************/ static void -ggv_ovl_rd_init(const char *fname) +ggv_ovl_rd_init(const char* fname) { - inifile = inifile_init(fname, MYNAME); - if (inifile->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); + inifile = inifile_init(fname, MYNAME); + if (inifile->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } - route_ct = 0; - track_ct = 0; + route_ct = 0; + track_ct = 0; } -static void +static void ggv_ovl_rd_deinit(void) { - inifile_done(inifile); + inifile_done(inifile); } static void ggv_ovl_read(void) { - int symbols; - int i; - - symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1); - - for (i = 1; i <= symbols; i++) { - int points; - OVL_SYMBOL_TYP type; - char symbol[32]; - - snprintf(symbol, sizeof(symbol), "Symbol %d", i); - - type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0); - points = inifile_readint_def(inifile, symbol, "Punkte", -1); - - switch(type) { - - char coord[32]; - waypoint *wpt; - char *cx; - int group; - - case OVL_SYMBOL_LINE: - case OVL_SYMBOL_POLYGON: - - if (!inifile_readint(inifile, symbol, "Group", &group)) group = -1; - - if (points > 0) { - int j; - route_head *rte, *trk; - - rte = trk = route_head_alloc(); - if (group > 1) { - route_add_head(rte); - route_ct++; - xasprintf(&rte->rte_name, "Route %d", route_ct); - } - else { - track_add_head(trk); - track_ct++; - xasprintf(&trk->rte_name, "Track %d", track_ct); - } - - for (j = 0; j < points; j++) { - - wpt = waypt_new(); - - snprintf(coord, sizeof(coord), "YKoord%d", j); - if ((cx = inifile_readstr(inifile, symbol, coord))) - wpt->latitude = atof(cx); - else - continue; - - snprintf(coord, sizeof(coord), "XKoord%d", j); - if ((cx = inifile_readstr(inifile, symbol, coord))) - wpt->longitude = atof(cx); - else - continue; - - if (group > 1) route_add_wpt(rte, wpt); - else track_add_wpt(trk, wpt); - } - } - break; - - case OVL_SYMBOL_CIRCLE: - case OVL_SYMBOL_TRIANGLE: - - wpt = waypt_new(); - wpt->shortname = xstrdup(symbol); - - if ((cx = inifile_readstr(inifile, symbol, "YKoord"))) - wpt->latitude = atof(cx); - else - continue; - if ((cx = inifile_readstr(inifile, symbol, "XKoord"))) - wpt->longitude = atof(cx); - else - continue; - - waypt_add(wpt); - break; - - case OVL_SYMBOL_BITMAP: - case OVL_SYMBOL_TEXT: - case OVL_SYMBOL_RECTANGLE: break; - } - } + int symbols; + int i; + + symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1); + + for (i = 1; i <= symbols; i++) { + int points; + OVL_SYMBOL_TYP type; + char symbol[32]; + + snprintf(symbol, sizeof(symbol), "Symbol %d", i); + + type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0); + points = inifile_readint_def(inifile, symbol, "Punkte", -1); + + switch (type) { + + char coord[32]; + waypoint* wpt; + char* cx; + int group; + + case OVL_SYMBOL_LINE: + case OVL_SYMBOL_POLYGON: + + if (!inifile_readint(inifile, symbol, "Group", &group)) { + group = -1; + } + + if (points > 0) { + int j; + route_head* rte, *trk; + + rte = trk = route_head_alloc(); + if (group > 1) { + route_add_head(rte); + route_ct++; + xasprintf(&rte->rte_name, "Route %d", route_ct); + } else { + track_add_head(trk); + track_ct++; + xasprintf(&trk->rte_name, "Track %d", track_ct); + } + + for (j = 0; j < points; j++) { + + wpt = waypt_new(); + + snprintf(coord, sizeof(coord), "YKoord%d", j); + if ((cx = inifile_readstr(inifile, symbol, coord))) { + wpt->latitude = atof(cx); + } else { + continue; + } + + snprintf(coord, sizeof(coord), "XKoord%d", j); + if ((cx = inifile_readstr(inifile, symbol, coord))) { + wpt->longitude = atof(cx); + } else { + continue; + } + + if (group > 1) { + route_add_wpt(rte, wpt); + } else { + track_add_wpt(trk, wpt); + } + } + } + break; + + case OVL_SYMBOL_CIRCLE: + case OVL_SYMBOL_TRIANGLE: + + wpt = waypt_new(); + wpt->shortname = xstrdup(symbol); + + if ((cx = inifile_readstr(inifile, symbol, "YKoord"))) { + wpt->latitude = atof(cx); + } else { + continue; + } + if ((cx = inifile_readstr(inifile, symbol, "XKoord"))) { + wpt->longitude = atof(cx); + } else { + continue; + } + + waypt_add(wpt); + break; + + case OVL_SYMBOL_BITMAP: + case OVL_SYMBOL_TEXT: + case OVL_SYMBOL_RECTANGLE: + break; + } + } } /**************************************************************************/ /* prototypes used in main functions */ -static void waypt_disp_cb(const waypoint *wpt); -static void track_disp_cb(const route_head *trk); -static void route_disp_cb(const route_head *rte); +static void waypt_disp_cb(const waypoint* wpt); +static void track_disp_cb(const route_head* trk); +static void route_disp_cb(const route_head* rte); static void write_bounds(void); -static void draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint *wpt); -static int get_direction(const waypoint *A, const waypoint *B); +static void draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint* wpt); +static int get_direction(const waypoint* A, const waypoint* B); // static void draw_symbol_text(const char *text, const waypoint *reference); /* -----------------------------------------------------------------------*/ static void -ggv_ovl_wr_init(const char *fname) +ggv_ovl_wr_init(const char* fname) { - fout = gbfopen(fname, "w", MYNAME); - - symbol_ct = 0; + fout = gbfopen(fname, "w", MYNAME); + + symbol_ct = 0; } static void ggv_ovl_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void ggv_ovl_write(void) { - group_ct = 1; /* tracks are not grouped */ - color = OVL_COLOR_FUCHSIA; - track_disp_all(track_disp_cb, NULL, NULL); - - group_ct++; - color = OVL_COLOR_AQUA; - route_disp_all(route_disp_cb, NULL, NULL); - - group_ct++; - color = OVL_COLOR_LIME; - waypt_disp_all(waypt_disp_cb); - - gbfprintf(fout, "[Overlay]\n"); - gbfprintf(fout, "Symbols=%d\n", symbol_ct); - gbfprintf(fout, "[MapLage]\n"); - gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n"); - gbfprintf(fout, "DimmFc=100\n"); - gbfprintf(fout, "ZoomFc=100\n"); - write_bounds(); - gbfprintf(fout, "RefOn=0\n"); /* no reference point */ + group_ct = 1; /* tracks are not grouped */ + color = OVL_COLOR_FUCHSIA; + track_disp_all(track_disp_cb, NULL, NULL); + + group_ct++; + color = OVL_COLOR_AQUA; + route_disp_all(route_disp_cb, NULL, NULL); + + group_ct++; + color = OVL_COLOR_LIME; + waypt_disp_all(waypt_disp_cb); + + gbfprintf(fout, "[Overlay]\n"); + gbfprintf(fout, "Symbols=%d\n", symbol_ct); + gbfprintf(fout, "[MapLage]\n"); + gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n"); + gbfprintf(fout, "DimmFc=100\n"); + gbfprintf(fout, "ZoomFc=100\n"); + write_bounds(); + gbfprintf(fout, "RefOn=0\n"); /* no reference point */ } /**************************************************************************/ static void -waypt_disp_cb(const waypoint *wpt) +waypt_disp_cb(const waypoint* wpt) { - draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt); - gbfprintf(fout, "Width=20\n"); - gbfprintf(fout, "Height=20\n"); - gbfprintf(fout, "Dir=100\n"); - gbfprintf(fout, "Zoom=1\n"); - gbfprintf(fout, "Size=102\n"); - gbfprintf(fout, "Area=2\n"); + draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt); + gbfprintf(fout, "Width=20\n"); + gbfprintf(fout, "Height=20\n"); + gbfprintf(fout, "Dir=100\n"); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=102\n"); + gbfprintf(fout, "Area=2\n"); // draw_symbol_text(wpt->shortname, wpt); } /* -----------------------------------------------------------------------*/ static void -track_disp_cb(const route_head *trk) +track_disp_cb(const route_head* trk) { - int i; - queue *elem, *tmp; - int waypt_ct = trk->rte_waypt_ct; - - if (waypt_ct <= 0) return; - - draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, NULL); - - gbfprintf(fout, "Zoom=1\n"); - gbfprintf(fout, "Size=105\n"); - gbfprintf(fout, "Punkte=%d\n", waypt_ct); - - i = 0; - - QUEUE_FOR_EACH(&(trk->waypoint_list), elem, tmp) { - - waypoint *wpt = (waypoint *) elem; - - gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude); - gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude); - - i++; - } + int i; + queue* elem, *tmp; + int waypt_ct = trk->rte_waypt_ct; + + if (waypt_ct <= 0) { + return; + } + + draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, NULL); + + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=105\n"); + gbfprintf(fout, "Punkte=%d\n", waypt_ct); + + i = 0; + + QUEUE_FOR_EACH(&(trk->waypoint_list), elem, tmp) { + + waypoint* wpt = (waypoint*) elem; + + gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude); + gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude); + + i++; + } } /* -----------------------------------------------------------------------*/ static void -route_disp_cb(const route_head *rte) +route_disp_cb(const route_head* rte) { - int i; - queue *elem, *tmp; - waypoint *prev; - int waypt_ct = rte->rte_waypt_ct; - - if (waypt_ct <= 0) return; - - track_disp_cb(rte); /* draw a line as tracks */ - - color = OVL_COLOR_RED; - - i = 0; - prev = NULL; - - QUEUE_FOR_EACH(&(rte->waypoint_list), elem, tmp) { - - waypoint *wpt = (waypoint *) elem; - - if (prev != NULL) { - draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, 9 /* color */, prev); - - gbfprintf(fout, "Width=12\n"); - gbfprintf(fout, "Height=8\n"); - gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt)); - gbfprintf(fout, "Zoom=1\n"); - gbfprintf(fout, "Size=101\n"); - gbfprintf(fout, "Area=2\n"); - } - - i++; - prev = wpt; - } + int i; + queue* elem, *tmp; + waypoint* prev; + int waypt_ct = rte->rte_waypt_ct; + + if (waypt_ct <= 0) { + return; + } + + track_disp_cb(rte); /* draw a line as tracks */ + + color = OVL_COLOR_RED; + + i = 0; + prev = NULL; + + QUEUE_FOR_EACH(&(rte->waypoint_list), elem, tmp) { + + waypoint* wpt = (waypoint*) elem; + + if (prev != NULL) { + draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, (OVL_COLOR_TYP)9 /* color */, prev); + + gbfprintf(fout, "Width=12\n"); + gbfprintf(fout, "Height=8\n"); + gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt)); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=101\n"); + gbfprintf(fout, "Area=2\n"); + } + + i++; + prev = wpt; + } } /* -----------------------------------------------------------------------*/ static void -waypt_bound_calc(const waypoint *waypointp) +waypt_bound_calc(const waypoint* waypointp) { - waypt_add_to_bounds(&all_bounds, waypointp); + waypt_add_to_bounds(&all_bounds, waypointp); } static void write_bounds(void) { - waypt_init_bounds(&all_bounds); + waypt_init_bounds(&all_bounds); - waypt_disp_all(waypt_bound_calc); - route_disp_all(NULL, NULL, waypt_bound_calc); - track_disp_all(NULL, NULL, waypt_bound_calc); + waypt_disp_all(waypt_bound_calc); + route_disp_all(NULL, NULL, waypt_bound_calc); + track_disp_all(NULL, NULL, waypt_bound_calc); - if (waypt_bounds_valid(&all_bounds)) { + if (waypt_bounds_valid(&all_bounds)) { - double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2); - double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2); + double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2); + double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2); - gbfprintf(fout, "CenterLat=%0.8f\n", cx); - gbfprintf(fout, "CenterLong=%0.8f\n", cy); - } - else { - gbfprintf(fout, "CenterLong=10.52374295\n"); - gbfprintf(fout, "CenterLat=52.26474445\n"); - } + gbfprintf(fout, "CenterLat=%0.8f\n", cx); + gbfprintf(fout, "CenterLong=%0.8f\n", cy); + } else { + gbfprintf(fout, "CenterLong=10.52374295\n"); + gbfprintf(fout, "CenterLat=52.26474445\n"); + } } static void -draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint *wpt) +draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint* wpt) { - symbol_ct++; - - gbfprintf(fout, "[Symbol %d]\n", symbol_ct); - gbfprintf(fout, "Typ=%d\n", typ); - gbfprintf(fout, "Group=%d\n", group_ct); - gbfprintf(fout, "Col=%d\n", color); - if (art >= 0) gbfprintf(fout, "Art=%d\n", art); - if (wpt) { - gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude); - gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude); - } + symbol_ct++; + + gbfprintf(fout, "[Symbol %d]\n", symbol_ct); + gbfprintf(fout, "Typ=%d\n", typ); + gbfprintf(fout, "Group=%d\n", group_ct); + gbfprintf(fout, "Col=%d\n", color); + if (art >= 0) { + gbfprintf(fout, "Art=%d\n", art); + } + if (wpt) { + gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude); + gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude); + } } /* the following code comes from first overlay module */ static int -get_direction(const waypoint *A, const waypoint *B) +get_direction(const waypoint* A, const waypoint* B) { - double lata, lona, latb, lonb; - double dist, dir; - int res; - - lata = RAD(A->latitude); - lona = RAD(A->longitude); - latb = RAD(B->latitude); - lonb = RAD(B->longitude); - - dist = gcdist(lata, lona, latb, lonb); - dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist))); - if (lonb < lona) dir = -dir; - res = (int) DEG(dir); - res = 360 - (res + 270); - if (res < 0) res += 360; - else if (res > 360) res -= 360.0; - - return res; + double lata, lona, latb, lonb; + double dist, dir; + int res; + + lata = RAD(A->latitude); + lona = RAD(A->longitude); + latb = RAD(B->latitude); + lonb = RAD(B->longitude); + + dist = gcdist(lata, lona, latb, lonb); + dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist))); + if (lonb < lona) { + dir = -dir; + } + res = (int) DEG(dir); + res = 360 - (res + 270); + if (res < 0) { + res += 360; + } else if (res > 360) { + res -= 360.0; + } + + return res; } #if 0 static void -draw_symbol_text(const char *text, const waypoint *reference) +draw_symbol_text(const char* text, const waypoint* reference) { - waypoint wpt; - - if ((reference == NULL) || (text == NULL)) return; - if (*text == '\0') return; - - wpt = *reference; - - wpt.latitude = wpt.latitude + 0.015; - wpt.longitude = wpt.longitude + 0.015; - - draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt); - - gbfprintf(fout, "Area=1\n"); - gbfprintf(fout, "Zoom=1\n"); - gbfprintf(fout, "Size=120\n"); - gbfprintf(fout, "Font=3\n"); - gbfprintf(fout, "Dir=100\n"); - gbfprintf(fout, "Text=%s\n", text); + waypoint wpt; + + if ((reference == NULL) || (text == NULL)) { + return; + } + if (*text == '\0') { + return; + } + + wpt = *reference; + + wpt.latitude = wpt.latitude + 0.015; + wpt.longitude = wpt.longitude + 0.015; + + draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt); + + gbfprintf(fout, "Area=1\n"); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=120\n"); + gbfprintf(fout, "Font=3\n"); + gbfprintf(fout, "Dir=100\n"); + gbfprintf(fout, "Text=%s\n", text); } #endif /**************************************************************************/ ff_vecs_t ggv_ovl_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - ggv_ovl_rd_init, - ggv_ovl_wr_init, - ggv_ovl_rd_deinit, - ggv_ovl_wr_deinit, - ggv_ovl_read, - ggv_ovl_write, - NULL, - ggv_ovl_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + FF_CAP_RW_ALL, + ggv_ovl_rd_init, + ggv_ovl_wr_init, + ggv_ovl_rd_deinit, + ggv_ovl_wr_deinit, + ggv_ovl_read, + ggv_ovl_write, + NULL, + ggv_ovl_args, + CET_CHARSET_MS_ANSI, 0 }; /**************************************************************************/ diff --git a/gpsbabel/globals.c b/gpsbabel/globals.c index 3891a45e7..f3580071a 100644 --- a/gpsbabel/globals.c +++ b/gpsbabel/globals.c @@ -1,6 +1,6 @@ /* Global data for GPSBabel. - + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify diff --git a/gpsbabel/glogbook.c b/gpsbabel/glogbook.c index 8a8d738c2..b42b6abeb 100644 --- a/gpsbabel/glogbook.c +++ b/gpsbabel/glogbook.c @@ -22,16 +22,16 @@ #include "defs.h" #include "xmlgeneric.h" -static gbfile *ofd; -static waypoint *wpt_tmp; -static route_head *trk_head; +static gbfile* ofd; +static waypoint* wpt_tmp; +static route_head* trk_head; #define MYNAME "glogbook" static arglist_t glogbook_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /* Tracks */ @@ -44,139 +44,139 @@ static xg_callback gl_trk_long; static xg_callback gl_trk_alt; static xg_tag_mapping gl_map[] = { - { gl_trk_s, cb_start, "/History/Run/Track" }, - { gl_trk_pnt_s,cb_start, "/History/Run/Track/Trackpoint/Position" }, - { gl_trk_pnt_e,cb_end, "/History/Run/Track/Trackpoint/Position" }, - { gl_trk_lat, cb_cdata, "/History/Run/Track/Trackpoint/Position/Latitude" }, - { gl_trk_long, cb_cdata, "/History/Run/Track/Trackpoint/Position/Longitude" }, - { gl_trk_alt, cb_cdata, "/History/Run/Track/Trackpoint/Position/Altitude" }, - { gl_trk_utc, cb_cdata, "/History/Run/Track/Trackpoint/Time" }, - { NULL, 0, NULL} + { gl_trk_s, cb_start, "/History/Run/Track" }, + { gl_trk_pnt_s,cb_start, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_pnt_e,cb_end, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_lat, cb_cdata, "/History/Run/Track/Trackpoint/Position/Latitude" }, + { gl_trk_long, cb_cdata, "/History/Run/Track/Trackpoint/Position/Longitude" }, + { gl_trk_alt, cb_cdata, "/History/Run/Track/Trackpoint/Position/Altitude" }, + { gl_trk_utc, cb_cdata, "/History/Run/Track/Trackpoint/Time" }, + { NULL, (xg_cb_type)0, NULL} }; static void -glogbook_rd_init(const char *fname) +glogbook_rd_init(const char* fname) { - xml_init(fname, gl_map, NULL); + xml_init(fname, gl_map, NULL); } static void glogbook_read(void) { - xml_read(); + xml_read(); } static void glogbook_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void -glogbook_wr_init(const char *fname) +glogbook_wr_init(const char* fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void glogbook_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static void -glogbook_waypt_pr(const waypoint *wpt) -{ - gbfprintf(ofd, " \n"); - gbfprintf(ofd, " \n"); - gbfprintf(ofd, " %.5f\n", wpt->latitude); - gbfprintf(ofd, " %.5f\n", wpt->longitude); - if (wpt->altitude != unknown_alt) { - gbfprintf(ofd, " %.3f\n", wpt->altitude); - } - gbfprintf(ofd, " \n"); - gbfprintf(ofd, " "); - xml_write_time(ofd, wpt->creation_time, wpt->microseconds, "Time"); - gbfprintf(ofd, " \n"); +glogbook_waypt_pr(const waypoint* wpt) +{ + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " %.5f\n", wpt->latitude); + gbfprintf(ofd, " %.5f\n", wpt->longitude); + if (wpt->altitude != unknown_alt) { + gbfprintf(ofd, " %.3f\n", wpt->altitude); + } + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " "); + xml_write_time(ofd, wpt->creation_time, wpt->microseconds, "Time"); + gbfprintf(ofd, " \n"); } static void -glogbook_hdr( const route_head *rte) +glogbook_hdr(const route_head* rte) { - gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void -glogbook_ftr(const route_head *rte) +glogbook_ftr(const route_head* rte) { - gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void glogbook_write(void) { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); - gbfprintf(ofd, " \n"); - track_disp_all(glogbook_hdr, glogbook_ftr, glogbook_waypt_pr); - gbfprintf(ofd, " \n"); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, " \n"); + track_disp_all(glogbook_hdr, glogbook_ftr, glogbook_waypt_pr); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, "\n"); } -void gl_trk_s(const char *args, const char **unused) +void gl_trk_s(const char* args, const char** unused) { - trk_head = route_head_alloc(); - track_add_head(trk_head); + trk_head = route_head_alloc(); + track_add_head(trk_head); } #if 0 -void gl_trk_ident(const char *args, const char **unused) +void gl_trk_ident(const char* args, const char** unused) { - trk_head->rte_name = xstrdup(args); + trk_head->rte_name = xstrdup(args); } #endif -void gl_trk_pnt_s(const char *args, const char **unused) +void gl_trk_pnt_s(const char* args, const char** unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } -void gl_trk_pnt_e(const char *args, const char **unused) +void gl_trk_pnt_e(const char* args, const char** unused) { - track_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); } -void gl_trk_utc(const char *args, const char **unused) +void gl_trk_utc(const char* args, const char** unused) { - wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); + wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); } -void gl_trk_lat(const char *args, const char **unused) +void gl_trk_lat(const char* args, const char** unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } -void gl_trk_long(const char *args, const char **unused) +void gl_trk_long(const char* args, const char** unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } -void gl_trk_alt(const char *args, const char **unused) +void gl_trk_alt(const char* args, const char** unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } ff_vecs_t glogbook_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none}, - glogbook_rd_init, - glogbook_wr_init, - glogbook_rd_deinit, - glogbook_wr_deinit, - glogbook_read, - glogbook_write, - NULL, - glogbook_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none}, + glogbook_rd_init, + glogbook_wr_init, + glogbook_rd_deinit, + glogbook_wr_deinit, + glogbook_read, + glogbook_write, + NULL, + glogbook_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/gnav_trl.c b/gpsbabel/gnav_trl.c index fdcaeccac..dc5216dee 100644 --- a/gpsbabel/gnav_trl.c +++ b/gpsbabel/gnav_trl.c @@ -27,132 +27,134 @@ static arglist_t gnav_trl_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; typedef struct gnav_trl_s { - gbuint32 time; - float lat; - float lon; - gbuint32 alt; + gbuint32 time; + float lat; + float lon; + gbuint32 alt; } gnav_trl_t; -static gbfile *fin, *fout; +static gbfile* fin, *fout; /******************************************************************************* * %%% global callbacks called by gpsbabel main process %%% * *******************************************************************************/ static void -gnav_trl_rd_init(const char *fname) +gnav_trl_rd_init(const char* fname) { - fin = gbfopen_le(fname, "rb", MYNAME); + fin = gbfopen_le(fname, "rb", MYNAME); } static void -gnav_trl_rw_init(const char *fname) +gnav_trl_rw_init(const char* fname) { - fout = gbfopen_le(fname, "wb", MYNAME); + fout = gbfopen_le(fname, "wb", MYNAME); } static void gnav_trl_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void gnav_trl_rw_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static double -read_altitude(void *ptr) +read_altitude(void* ptr) { - unsigned char *i = (unsigned char *) ptr; - char buf[sizeof(float)]; - le_write32(&buf, i[2] << 24 | i[1] << 16 | i[0] <<8 | i[3]); - return le_read_float(&buf); + unsigned char* i = (unsigned char*) ptr; + char buf[sizeof(float)]; + le_write32(&buf, i[2] << 24 | i[1] << 16 | i[0] <<8 | i[3]); + return le_read_float(&buf); } static void -write_altitude(void *ptr, const float alt) +write_altitude(void* ptr, const float alt) { - char buf[sizeof(float)]; - unsigned char *i = (unsigned char *) &buf; - le_write_float(&buf, alt); - le_write32(ptr, i[0] << 24 | i[3] << 16 | i[2] << 8 | i[1]); + char buf[sizeof(float)]; + unsigned char* i = (unsigned char*) &buf; + le_write_float(&buf, alt); + le_write32(ptr, i[0] << 24 | i[3] << 16 | i[2] << 8 | i[1]); } static void gnav_trl_read(void) { - route_head *trk = NULL; + route_head* trk = NULL; - while (! gbfeof(fin)) { - gnav_trl_t rec; - waypoint *wpt; + while (! gbfeof(fin)) { + gnav_trl_t rec; + waypoint* wpt; - if (gbfread(&rec, sizeof(rec), 1, fin) != 1) - fatal(MYNAME ": Unexpected EOF (end of file)!\n"); + if (gbfread(&rec, sizeof(rec), 1, fin) != 1) { + fatal(MYNAME ": Unexpected EOF (end of file)!\n"); + } - wpt = waypt_new(); + wpt = waypt_new(); - wpt->creation_time = le_read32(&rec.time); - wpt->latitude = le_read_float(&rec.lat); - wpt->longitude = le_read_float(&rec.lon); - wpt->altitude = read_altitude(&rec.alt); + wpt->creation_time = le_read32(&rec.time); + wpt->latitude = le_read_float(&rec.lat); + wpt->longitude = le_read_float(&rec.lon); + wpt->altitude = read_altitude(&rec.alt); - if (trk == NULL) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - } + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + } } static void -gnav_trl_write_trkpt(const waypoint *wpt) +gnav_trl_write_trkpt(const waypoint* wpt) { - gnav_trl_t rec; - - le_write32(&rec.time, wpt->creation_time); - le_write_float(&rec.lat, wpt->latitude); - le_write_float(&rec.lon, wpt->longitude); - if (wpt->altitude != unknown_alt) - write_altitude(&rec.alt, wpt->altitude); - else - write_altitude(&rec.alt, 0); - - gbfwrite(&rec, sizeof(rec), 1, fout); + gnav_trl_t rec; + + le_write32(&rec.time, wpt->creation_time); + le_write_float(&rec.lat, wpt->latitude); + le_write_float(&rec.lon, wpt->longitude); + if (wpt->altitude != unknown_alt) { + write_altitude(&rec.alt, wpt->altitude); + } else { + write_altitude(&rec.alt, 0); + } + + gbfwrite(&rec, sizeof(rec), 1, fout); } static void gnav_trl_write(void) { - track_disp_all(NULL, NULL, gnav_trl_write_trkpt); + track_disp_all(NULL, NULL, gnav_trl_write_trkpt); } /**************************************************************************/ ff_vecs_t gnav_trl_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - gnav_trl_rd_init, - gnav_trl_rw_init, - gnav_trl_rd_deinit, - gnav_trl_rw_deinit, - gnav_trl_read, - gnav_trl_write, - NULL, - gnav_trl_args, - CET_CHARSET_UTF8, 1 /* CET - do nothing ! */ + ff_type_file, + { + ff_cap_none /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + gnav_trl_rd_init, + gnav_trl_rw_init, + gnav_trl_rd_deinit, + gnav_trl_rw_deinit, + gnav_trl_read, + gnav_trl_write, + NULL, + gnav_trl_args, + CET_CHARSET_UTF8, 1 /* CET - do nothing ! */ }; diff --git a/gpsbabel/google.c b/gpsbabel/google.c index 889405696..e23991315 100644 --- a/gpsbabel/google.c +++ b/gpsbabel/google.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2002 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -19,11 +19,11 @@ #include "defs.h" #include "xmlgeneric.h" -static char *encoded_points = NULL; -static char *encoded_levels = NULL; -static char *script = NULL; -static route_head **routehead; -static int *routecount; +static char* encoded_points = NULL; +static char* encoded_levels = NULL; +static char* script = NULL; +static route_head** routehead; +static int* routecount; static short_handle desc_handle; static int serial = 0; @@ -33,9 +33,9 @@ static int serial = 0; #if ! HAVE_LIBEXPAT static void -google_rd_init(const char *fname) +google_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded Google Maps support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded Google Maps support because expat was not installed.\n"); } static void @@ -48,515 +48,479 @@ static xg_callback goog_points, goog_levels, goog_poly_e, goog_script; static xg_callback goog_segment_s, goog_segment, goog_td_s, goog_td_b; static xg_callback goog_td_e; -static +static xg_tag_mapping google_map[] = { - { goog_points, cb_cdata, "/page/directions/polyline/points" }, - { goog_levels, cb_cdata, "/page/directions/polyline/levels" }, - { goog_poly_e, cb_end, "/page/directions/polyline" }, - { goog_script, cb_cdata, "/html/head/script" }, - { goog_segment_s, cb_start, "/page/directions/segments/segment" }, - { goog_segment, cb_cdata, "/page/directions/segments/segment" }, - { goog_td_s, cb_start, "/div/table/tr/td" }, - { goog_td_s, cb_start, "/div/div/table/tr/td" }, - { goog_td_b, cb_cdata, "/div/table/tr/td/b" }, - { goog_td_b, cb_cdata, "/div/div/table/tr/td/b" }, - { goog_td_e, cb_end, "/div/table/tr/td" }, - { goog_td_e, cb_end, "/div/div/table/tr/td" }, - { NULL, 0, NULL } + { goog_points, cb_cdata, "/page/directions/polyline/points" }, + { goog_levels, cb_cdata, "/page/directions/polyline/levels" }, + { goog_poly_e, cb_end, "/page/directions/polyline" }, + { goog_script, cb_cdata, "/html/head/script" }, + { goog_segment_s, cb_start, "/page/directions/segments/segment" }, + { goog_segment, cb_cdata, "/page/directions/segments/segment" }, + { goog_td_s, cb_start, "/div/table/tr/td" }, + { goog_td_s, cb_start, "/div/div/table/tr/td" }, + { goog_td_b, cb_cdata, "/div/table/tr/td/b" }, + { goog_td_b, cb_cdata, "/div/div/table/tr/td/b" }, + { goog_td_e, cb_end, "/div/table/tr/td" }, + { goog_td_e, cb_end, "/div/div/table/tr/td" }, + { NULL, (xg_cb_type)0, NULL } }; -void goog_script( const char *args, const char **unused ) +void goog_script(const char* args, const char** unused) { - if (args) - { - if ( script ) - { - script = xstrappend( script, args ); - } - else - { - script = xstrdup( args ); - } - } -} - -void goog_points( const char *args, const char **unused ) + if (args) { + if (script) { + script = xstrappend(script, args); + } else { + script = xstrdup(args); + } + } +} + +void goog_points(const char* args, const char** unused) { - if (args) - { - if ( encoded_points ) - { - encoded_points = xstrappend( encoded_points, args ); - } - else - { - encoded_points = xstrdup(args); - } - } + if (args) { + if (encoded_points) { + encoded_points = xstrappend(encoded_points, args); + } else { + encoded_points = xstrdup(args); + } + } } -void goog_levels( const char *args, const char **unused ) +void goog_levels(const char* args, const char** unused) { - if (args) - { - if ( encoded_levels ) - { - encoded_levels = xstrappend( encoded_levels, args ); - } - else - { - encoded_levels = xstrdup(args); - } - } + if (args) { + if (encoded_levels) { + encoded_levels = xstrappend(encoded_levels, args); + } else { + encoded_levels = xstrdup(args); + } + } } static char goog_segname[7]; -static char *goog_realname = NULL; +static char* goog_realname = NULL; static int goog_segroute = 0; /* * The segments contain an index into the points array. We use that * index to find the waypoint and insert a better name for it. */ -void goog_segment_s( const char *args, const char **attrv ) +void goog_segment_s(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "pointIndex")) { - snprintf(goog_segname, sizeof(goog_segname), "\\%5.5x", atoi(avp[1])); - } - avp += 2; - } + const char** avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "pointIndex")) { + snprintf(goog_segname, sizeof(goog_segname), "\\%5.5x", atoi(avp[1])); + } + avp += 2; + } } -void goog_segment( const char *args, const char **unused ) +void goog_segment(const char* args, const char** unused) { - waypoint *wpt_tmp; - - wpt_tmp = route_find_waypt_by_name( routehead[goog_segroute], goog_segname); - if (wpt_tmp) { - xfree(wpt_tmp->shortname); - wpt_tmp->shortname = mkshort(desc_handle,args); - wpt_tmp->description = xstrdup(args); - } + waypoint* wpt_tmp; + + wpt_tmp = route_find_waypt_by_name(routehead[goog_segroute], goog_segname); + if (wpt_tmp) { + xfree(wpt_tmp->shortname); + wpt_tmp->shortname = mkshort(desc_handle,args); + wpt_tmp->description = xstrdup(args); + } } -void goog_td_s( const char *args, const char **attrv ) +void goog_td_s(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - int isdesc = 0; - int isseg = 0; - while (*avp) { - if ( 0 == strcmp(avp[0], "class" )) { - isdesc = !strcmp(avp[1], "desc" ); - isseg = !strcmp(avp[1], "dirsegtext" ); - } - else if ( isdesc && (0 == strcmp( avp[0], "id" ))) { - goog_segroute = 0; - snprintf( goog_segname, sizeof(goog_segname), - "\\%5.5x", - atoi(avp[1] + 6 )); - } - else if ( isseg && (0 == strcmp( avp[0], "id" ))) { - if ( strchr(strchr(avp[1],'_')+1,'_')) { - goog_segroute = atoi(strchr(avp[1],'_')+1); - } - else { - goog_segroute = 0; - } - snprintf( goog_segname, sizeof(goog_segname), - "\\%5.5x", - atoi(strrchr( avp[1],'_') + 1 )+routecount[goog_segroute]); - } - avp += 2; - } + const char** avp = &attrv[0]; + int isdesc = 0; + int isseg = 0; + while (*avp) { + if (0 == strcmp(avp[0], "class")) { + isdesc = !strcmp(avp[1], "desc"); + isseg = !strcmp(avp[1], "dirsegtext"); + } else if (isdesc && (0 == strcmp(avp[0], "id"))) { + goog_segroute = 0; + snprintf(goog_segname, sizeof(goog_segname), + "\\%5.5x", + atoi(avp[1] + 6)); + } else if (isseg && (0 == strcmp(avp[0], "id"))) { + if (strchr(strchr(avp[1],'_')+1,'_')) { + goog_segroute = atoi(strchr(avp[1],'_')+1); + } else { + goog_segroute = 0; + } + snprintf(goog_segname, sizeof(goog_segname), + "\\%5.5x", + atoi(strrchr(avp[1],'_') + 1)+routecount[goog_segroute]); + } + avp += 2; + } } - -void goog_td_b( const char *args, const char **attrv ) { - if ( goog_segname[0] == '\\' && !strchr( args, '\xa0')) { - if ( goog_realname ) { - xfree( goog_realname ); - goog_realname = NULL; - } - goog_realname = xmalloc( strlen(args)+1); - strcpy( goog_realname, args ); - } + +void goog_td_b(const char* args, const char** attrv) +{ + if (goog_segname[0] == '\\' && !strchr(args, '\xa0')) { + if (goog_realname) { + xfree(goog_realname); + goog_realname = NULL; + } + goog_realname = (char*) xmalloc(strlen(args)+1); + strcpy(goog_realname, args); + } } -void goog_td_e( const char *args, const char **attrv ) +void goog_td_e(const char* args, const char** attrv) { - if ( goog_segname[0] == '\\' && goog_realname ) { - goog_segment( goog_realname, attrv ); - } - goog_segname[0] = '\0'; - if ( goog_realname ) { - xfree( goog_realname ); - goog_realname = NULL; - } + if (goog_segname[0] == '\\' && goog_realname) { + goog_segment(goog_realname, attrv); + } + goog_segname[0] = '\0'; + if (goog_realname) { + xfree(goog_realname); + goog_realname = NULL; + } } -static long decode_goog64( char **str ) +static long decode_goog64(char** str) { - long result = 0; - unsigned char c = 0; - unsigned char shift = 0; - - if ( !(**str)) { - return 0; - } - - do - { - c = (unsigned char)(*(*str)++)-'?'; - result |= (c & 31)<latitude = lat / 100000.0; - wpt_tmp->longitude = lon / 100000.0; - wpt_tmp->route_priority=level; - wpt_tmp->shortname = (char *) xmalloc(7); - sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ ); - route_add_wpt(routehead[goog_segroute], wpt_tmp); - } - } - + long lat = 0; + long lon = 0; + long level = 0; + long level1 = -9999; + long level2 = -9999; + char* str = encoded_points; + char* lstr = encoded_levels; + + routehead[goog_segroute] = route_head_alloc(); + route_add_head(routehead[goog_segroute]); + routecount[goog_segroute] = serial; + + while (str && *str) { + lat += decode_goog64(&str); + lon += decode_goog64(&str); + + level = -1; + level2 = level1; + if (lstr && *lstr) { + level1 = -decode_goog64(&lstr); + } else { + level1 = -9999; + } + level = (level1latitude = lat / 100000.0; + wpt_tmp->longitude = lon / 100000.0; + wpt_tmp->route_priority=level; + wpt_tmp->shortname = (char*) xmalloc(7); + sprintf(wpt_tmp->shortname, "\\%5.5x", serial++); + route_add_wpt(routehead[goog_segroute], wpt_tmp); + } + } + } static void -google_rd_init(const char *fname) +google_rd_init(const char* fname) { - desc_handle = mkshort_new_handle(); - setshort_length(desc_handle, 12); + desc_handle = mkshort_new_handle(); + setshort_length(desc_handle, 12); - xml_init(fname, google_map, "ISO-8859-1" ); + xml_init(fname, google_map, "ISO-8859-1"); } static void google_read(void) { - routehead = (route_head **)xmalloc(sizeof(route_head *)); - routecount = (int *)xmalloc(sizeof(int)); - goog_segroute = 0; - xml_read(); - xfree( routehead ); - xfree( routecount ); - - if ( encoded_points ) - { - xfree( encoded_points ); - encoded_points = NULL; - } - if ( encoded_levels ) - { - xfree( encoded_levels ); - encoded_levels = NULL; - } - if ( script ) - { - char *xml = strchr( script, '\'' ); - char *dict = strstr( script, "({" ); - - char *end = NULL; - - if ( xml && (!dict || (xml < dict ))) { - routehead = (route_head **)xmalloc(sizeof(route_head *)); - routecount = (int *)xmalloc(sizeof(int)); - goog_segroute = 0; - xml++; - end = strchr( xml+1, '\'' ); - if ( end ) { - *end = '\0'; - xml_deinit(); - xml_init( NULL, google_map, NULL ); - xml_readstring( xml ); - if ( encoded_points ) - { - xfree( encoded_points ); - encoded_points = NULL; - } - if ( encoded_levels ) - { - xfree( encoded_levels ); - encoded_levels = NULL; - } - } - } - else if ( dict ) { - char qc = '\''; - int ofs = 9; - int panelofs = 8; - int count = 0; - char *tmp = NULL; - char *start = NULL; - - char *panel = strstr( dict, "panel: '" ); - encoded_points = strstr( dict, "points: '" ); - encoded_levels = strstr( dict, "levels: '" ); - if ( !encoded_points ) { - ofs = 10; - qc = '"'; - encoded_points = strstr( dict, "\"points\":\"" ); - encoded_levels = strstr( dict, "\"levels\":\"" ); - if ( !encoded_points ) { - encoded_points = strstr(dict, "points:\"" ); - encoded_levels = strstr(dict, "levels:\"" ); - ofs = 8; - } - } - - if ( !panel ) { - panel = strstr( dict, "panel:\""); - panelofs = 7; - } - tmp = panel; - while ( tmp ) { - if ( qc == '"' ) { - char *tmp1 = strstr( tmp, "\"points\":\"" ); - if ( !tmp1 ) { - tmp1 = strstr( tmp, "points:\"" ); - } - tmp = tmp1; - } - else { - tmp = strstr( tmp, "points: '" ); - } - count++; - if ( tmp ) { - tmp++; - } - } - routehead = (route_head **)xmalloc(sizeof(route_head *)*count); - routecount = (int *)xmalloc(sizeof(int)*count); - goog_segroute = 0; - - do { - - if ( encoded_points && encoded_levels ) { - encoded_points += ofs; - encoded_levels += ofs; - end = strchr( encoded_points, qc ); - if ( end ) { - *end = '\0'; - end = encoded_points; - while ( (end = strstr(end, "\\\\" ))) { - memmove( end, end+1, strlen(end)+1 ); - end++; - } - end = strchr( encoded_levels, qc ); - if ( end ) { - start = end; - *end = '\0'; - end = encoded_levels; - while ( (end = strstr(end, "\\\\" ))) { - memmove( end, end+1, strlen(end)+1 ); - end++; - } - goog_poly_e( NULL, NULL ); - - goog_segroute++; - start++; - { - encoded_points = strstr( start, "points: '" ); - encoded_levels = strstr( start, "levels: '" ); - } - if ( !encoded_points ) { - encoded_points = strstr( start, "\"points\":\"" ); - encoded_levels = strstr( start, "\"levels\":\"" ); - } - if ( !encoded_points ) { - encoded_points = strstr( start, "points:\"" ); - encoded_levels = strstr( start, "levels:\"" ); - } - } - } - } - } while ( start && encoded_points && encoded_levels ); - if ( panel ) { - panel += panelofs; - end = strstr( panel, "/table>
"); - } - if ( !end ) { - end = strstr( panel, "/div>
"); - } - } - if ( end ) { - char *to = panel; - char *from = panel; - while ( *from ) { - if ( !strncmp( from, "\\\"", 2 )) { - *to++ = '"'; - from += 2; - if ( *(to-2) != '=' ) { - *to++ = ' '; - } - } - else if ( !strncmp( from, "\\042", 4)) { - *to++ = '"'; - from += 4; - - if ( *(to-2) != '=' ) { - *to++ = ' '; - } - } - else if ( !strncmp( from, "\\u0026utm", 9)) { - strcpy( to, "&utm" ); - to += 8; - from += 9; - } - else if ( !strncmp( from, "\\u0026", 6 )) { - *to++='&'; - from += 6; - } - else if ( !strncmp( from, "\\u003c", 6 )) { - *to++='<'; - from += 6; - } - else if ( !strncmp( from, "\\u003e", 6 )) { - *to++='>'; - from += 6; - } - else if ( !strncmp( from, "\\x", 2)) { - unsigned int c; - sscanf(from+2, "%2x", &c); - *to++ = (char)c; - from += 4; - } - else if ( !strncmp( from, "\\'", 2)) { - *to++ = '\''; - from += 2; - } - else if ( !strncmp( from, " nowrap ", 8)) { - *to++ = ' '; - from += 8; - } - else if ( !strncmp( from, "tr style=\\\"display:none", 23 )) { - if ( strcmp( to-5, "/tr><" )) { - /* broken 6-26-07 missing that apparently doesn't bother browsers */ - strcpy(to, "/tr><" ); - to += 5; - } - *to++ = *from++; - } - else { - *to++ = *from++; - } - } - *to = '\0'; - -#if 0 - { - FILE *foo = fopen( "foo.xml", "w" ); - fprintf(foo, "\n", xhtml_entities ); - fwrite( panel, sizeof(char), strlen(panel), foo ); - fclose( foo ); - } + routehead = (route_head**)xmalloc(sizeof(route_head*)); + routecount = (int*)xmalloc(sizeof(int)); + goog_segroute = 0; + xml_read(); + xfree(routehead); + xfree(routecount); + + if (encoded_points) { + xfree(encoded_points); + encoded_points = NULL; + } + if (encoded_levels) { + xfree(encoded_levels); + encoded_levels = NULL; + } + if (script) { + char* xml = strchr(script, '\''); + char* dict = strstr(script, "({"); + + char* end = NULL; + + if (xml && (!dict || (xml < dict))) { + routehead = (route_head**)xmalloc(sizeof(route_head*)); + routecount = (int*)xmalloc(sizeof(int)); + goog_segroute = 0; + xml++; + end = strchr(xml+1, '\''); + if (end) { + *end = '\0'; + xml_deinit(); + xml_init(NULL, google_map, NULL); + xml_readstring(xml); + if (encoded_points) { + xfree(encoded_points); + encoded_points = NULL; + } + if (encoded_levels) { + xfree(encoded_levels); + encoded_levels = NULL; + } + } + } else if (dict) { + char qc = '\''; + int ofs = 9; + int panelofs = 8; + int count = 0; + char* tmp = NULL; + char* start = NULL; + + char* panel = strstr(dict, "panel: '"); + encoded_points = strstr(dict, "points: '"); + encoded_levels = strstr(dict, "levels: '"); + if (!encoded_points) { + ofs = 10; + qc = '"'; + encoded_points = strstr(dict, "\"points\":\""); + encoded_levels = strstr(dict, "\"levels\":\""); + if (!encoded_points) { + encoded_points = strstr(dict, "points:\""); + encoded_levels = strstr(dict, "levels:\""); + ofs = 8; + } + } + + if (!panel) { + panel = strstr(dict, "panel:\""); + panelofs = 7; + } + tmp = panel; + while (tmp) { + if (qc == '"') { + char* tmp1 = strstr(tmp, "\"points\":\""); + if (!tmp1) { + tmp1 = strstr(tmp, "points:\""); + } + tmp = tmp1; + } else { + tmp = strstr(tmp, "points: '"); + } + count++; + if (tmp) { + tmp++; + } + } + routehead = (route_head**)xmalloc(sizeof(route_head*)*count); + routecount = (int*)xmalloc(sizeof(int)*count); + goog_segroute = 0; + + do { + + if (encoded_points && encoded_levels) { + encoded_points += ofs; + encoded_levels += ofs; + end = strchr(encoded_points, qc); + if (end) { + *end = '\0'; + end = encoded_points; + while ((end = strstr(end, "\\\\"))) { + memmove(end, end+1, strlen(end)+1); + end++; + } + end = strchr(encoded_levels, qc); + if (end) { + start = end; + *end = '\0'; + end = encoded_levels; + while ((end = strstr(end, "\\\\"))) { + memmove(end, end+1, strlen(end)+1); + end++; + } + goog_poly_e(NULL, NULL); + + goog_segroute++; + start++; + { + encoded_points = strstr(start, "points: '"); + encoded_levels = strstr(start, "levels: '"); + } + if (!encoded_points) { + encoded_points = strstr(start, "\"points\":\""); + encoded_levels = strstr(start, "\"levels\":\""); + } + if (!encoded_points) { + encoded_points = strstr(start, "points:\""); + encoded_levels = strstr(start, "levels:\""); + } + } + } + } + } while (start && encoded_points && encoded_levels); + if (panel) { + panel += panelofs; + end = strstr(panel, "/table>
"); + } + if (!end) { + end = strstr(panel, "/div>
"); + } + } + if (end) { + char* to = panel; + char* from = panel; + while (*from) { + if (!strncmp(from, "\\\"", 2)) { + *to++ = '"'; + from += 2; + if (*(to-2) != '=') { + *to++ = ' '; + } + } else if (!strncmp(from, "\\042", 4)) { + *to++ = '"'; + from += 4; + + if (*(to-2) != '=') { + *to++ = ' '; + } + } else if (!strncmp(from, "\\u0026utm", 9)) { + strcpy(to, "&utm"); + to += 8; + from += 9; + } else if (!strncmp(from, "\\u0026", 6)) { + *to++='&'; + from += 6; + } else if (!strncmp(from, "\\u003c", 6)) { + *to++='<'; + from += 6; + } else if (!strncmp(from, "\\u003e", 6)) { + *to++='>'; + from += 6; + } else if (!strncmp(from, "\\x", 2)) { + unsigned int c; + sscanf(from+2, "%2x", &c); + *to++ = (char)c; + from += 4; + } else if (!strncmp(from, "\\'", 2)) { + *to++ = '\''; + from += 2; + } else if (!strncmp(from, " nowrap ", 8)) { + *to++ = ' '; + from += 8; + } else if (!strncmp(from, "tr style=\\\"display:none", 23)) { + if (strcmp(to-5, "/tr><")) { + /* broken 6-26-07 missing that apparently doesn't bother browsers */ + strcpy(to, "/tr><"); + to += 5; + } + *to++ = *from++; + } else { + *to++ = *from++; + } + } + *to = '\0'; + +#if 0 + { + FILE* foo = fopen("foo.xml", "w"); + fprintf(foo, "\n", xhtml_entities); + fwrite(panel, sizeof(char), strlen(panel), foo); + fclose(foo); + } #endif - xml_deinit(); - xml_init( NULL, google_map, NULL ); - xml_readprefixstring( "" ); - xml_readstring( panel ); - } - } - } - xfree( script ); - xfree( routehead ); - xfree( routecount ); - script = NULL; - } - - /* - * 'Tis better to leak than crash when we are merging and - * don't see an 'end' in the first file. This feels a bit - * like plastering over a deeper problem... - * - */ - if ( encoded_points ) { - encoded_points = NULL; - } - if ( encoded_levels ) { - encoded_levels = NULL; - } + xml_deinit(); + xml_init(NULL, google_map, NULL); + xml_readprefixstring(""); + xml_readstring(panel); + } + } + } + xfree(script); + xfree(routehead); + xfree(routecount); + script = NULL; + } + + /* + * 'Tis better to leak than crash when we are merging and + * don't see an 'end' in the first file. This feels a bit + * like plastering over a deeper problem... + * + */ + if (encoded_points) { + encoded_points = NULL; + } + if (encoded_levels) { + encoded_levels = NULL; + } } #endif static void google_rd_deinit(void) { - xml_deinit(); - mkshort_del_handle(&desc_handle); + xml_deinit(); + mkshort_del_handle(&desc_handle); } ff_vecs_t google_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read, ff_cap_none}, - google_rd_init, - NULL, - google_rd_deinit, - NULL, - google_read, - NULL, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none}, + google_rd_init, + NULL, + google_rd_deinit, + NULL, + google_read, + NULL, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* CET-REVIEW */ }; diff --git a/gpsbabel/gopal.c b/gpsbabel/gopal.c index 8b7ff716c..01fc35c8a 100644 --- a/gpsbabel/gopal.c +++ b/gpsbabel/gopal.c @@ -21,25 +21,25 @@ ===================================================================================== - This file allows gpsbabel to read and write the internal track log format used by - GoPal navigation systems. They produce a simple line-oriented format with one point per + This file allows gpsbabel to read and write the internal track log format used by + GoPal navigation systems. They produce a simple line-oriented format with one point per second. Unfortunately the the data does not contain a valid date, only some kind of timetick, together with each point (perhaps by mistake ??). So we have to parse the filename for a valid starting - date and add the timeoffset. Second problem (at least to me) was that irregularly stupid errors were - in the data, i.e. only one data point shows a totally wrong longitude or latitude. Everything else in + date and add the timeoffset. Second problem (at least to me) was that irregularly stupid errors were + in the data, i.e. only one data point shows a totally wrong longitude or latitude. Everything else in the dataset seems ok, so I needed a way to sort out these errors. My solution is to calculate the speed between successive points and drop points not between minspeed and maxspeed. This way I can sort out most - of this annoying bugs, a side effect is that if a minimum speed > 0 is set points with the same coodinates are also + of this annoying bugs, a side effect is that if a minimum speed > 0 is set points with the same coodinates are also dropped. Fileformat GoPal TICK; TIME UTC; LONG; LAT; HEIGHT; SPEED km/h; FIX; HDOP; SAT - 3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 + 3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 Filenames: trackYYYYMMDD_HHMMSS.trk A_YYYYMMDD_HHMMSS.trk with HHMMSS local time (not UTC) - + History 2008-07-18 initial release of Version 0.1 2008-07-26 bugfix: filenamehandling linux, format specification in write statement @@ -57,39 +57,38 @@ #include "grtcirc.h" #define MYNAME "gopal" -static gbfile *fin, *fout; +static gbfile* fin, *fout; static struct tm tm,filenamedate, trackdate; time_t tx; char tmp[64]; char routename[64]; -static char *optdate=NULL; -static char *optmaxspeed=NULL; -static char *optminspeed=NULL; -static char *optclean= NULL; +static char* optdate=NULL; +static char* optmaxspeed=NULL; +static char* optminspeed=NULL; +static char* optclean= NULL; static double minspeed,maxspeed; static struct tm opt_tm; /* converted "date" parameter */ static arglist_t gopal_args[] = { - {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - {"maxspeed", &optmaxspeed, "The maximum speed (km/h) traveling from waypoint to waypoint.", "200", ARGTYPE_INT, "1", "1000" }, - {"minspeed", &optminspeed, "The minimum speed (km/h) traveling from waypoint to waypoint. Set >0 to remove duplicate waypoints", "0", ARGTYPE_INT, "0", "999" }, - {"clean", &optclean, "Cleanup common errors in trackdata", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"maxspeed", &optmaxspeed, "The maximum speed (km/h) traveling from waypoint to waypoint.", "200", ARGTYPE_INT, "1", "1000" }, + {"minspeed", &optminspeed, "The minimum speed (km/h) traveling from waypoint to waypoint. Set >0 to remove duplicate waypoints", "0", ARGTYPE_INT, "0", "999" }, + {"clean", &optclean, "Cleanup common errors in trackdata", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define CHECK_BOOL(a) if (a && (*a == '0')) a = NULL -int gopal_check_line(char *line) +int gopal_check_line(char* line) { - char *c = line; - int i = 0; - while ((c = strchr(c, ','))) - { - c++; - i++; - } - return i; + char* c = line; + int i = 0; + while ((c = strchr(c, ','))) { + c++; + i++; + } + return i; } @@ -99,284 +98,296 @@ int gopal_check_line(char *line) *******************************************************************************/ static void -gopal_rd_init(const char *fname) -{char buff[32]; - char *ck; - char *filename; - CHECK_BOOL(optclean); - if (optminspeed) - { - minspeed=atof(optminspeed); - if (global_opts.debug_level > 1) fprintf(stderr,"options from command line : gopal minspeed = %s\n",optminspeed); - } - else - minspeed=0; - if (optmaxspeed) - { - maxspeed=atof(optmaxspeed); - if (global_opts.debug_level > 1) fprintf(stderr,"options from command line : gopal maxspeed = %s\n",optmaxspeed); - } - else - maxspeed=200; - if (global_opts.debug_level > 1) fprintf(stderr,"setting minspeed to %5.1lf km/h and maxspeed to %5.1lf km/h\n",minspeed,maxspeed); - - fin = gbfopen(fname, "r", MYNAME); - - memset(buff,0,sizeof(buff)); - if (optdate) - { - memset(&opt_tm, 0, sizeof(opt_tm)); - - ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); - if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) - fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); - else if (opt_tm.tm_year < 70) - fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); - tx = mkgmtime(&opt_tm); - - } - else - { - /* remove path */ - filename = get_filename(fname); - - if ((strncmp(filename,"track",5)==0)&&(strlen(filename)>13)) // we need at least 13 letters: trackYYYYMMDD... - { - strncpy(&buff[0],&filename[5],8); - } - else - if ((strncmp(filename,"A_",2)==0)&&(strlen(filename)>10))// here we expect at least 10 letters: A_YYYYMMDD... - { - strncpy(&buff[0],&filename[2],8); - } - // in buff we should now have something wich looks like a valid date starting with YYYYMMDD - ck = (char *)strptime(buff, "%Y%m%d", &filenamedate); - // if (((ck == NULL) || (*ck != '\0') )&&!(optdate)) - // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); - // /* else */ if (filenamedate.tm_year < 70) - // fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", buff); - // tx= mkgmtime(&filenamedate); - } +gopal_rd_init(const char* fname) +{ + char buff[32]; + char* ck; + char* filename; + CHECK_BOOL(optclean); + if (optminspeed) { + minspeed=atof(optminspeed); + if (global_opts.debug_level > 1) { + fprintf(stderr,"options from command line : gopal minspeed = %s\n",optminspeed); + } + } else { + minspeed=0; + } + if (optmaxspeed) { + maxspeed=atof(optmaxspeed); + if (global_opts.debug_level > 1) { + fprintf(stderr,"options from command line : gopal maxspeed = %s\n",optmaxspeed); + } + } else { + maxspeed=200; + } + if (global_opts.debug_level > 1) { + fprintf(stderr,"setting minspeed to %5.1lf km/h and maxspeed to %5.1lf km/h\n",minspeed,maxspeed); + } + + fin = gbfopen(fname, "r", MYNAME); + + memset(buff,0,sizeof(buff)); + if (optdate) { + memset(&opt_tm, 0, sizeof(opt_tm)); + + ck = (char*)strptime(optdate, "%Y%m%d", &opt_tm); + if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) { + fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); + } else if (opt_tm.tm_year < 70) { + fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); + } + tx = mkgmtime(&opt_tm); + + } else { + /* remove path */ + filename = get_filename(fname); + + if ((strncmp(filename,"track",5)==0)&&(strlen(filename)>13)) { // we need at least 13 letters: trackYYYYMMDD... + strncpy(&buff[0],&filename[5],8); + } else if ((strncmp(filename,"A_",2)==0)&&(strlen(filename)>10)) { // here we expect at least 10 letters: A_YYYYMMDD... + strncpy(&buff[0],&filename[2],8); + } + // in buff we should now have something wich looks like a valid date starting with YYYYMMDD + ck = (char*)strptime(buff, "%Y%m%d", &filenamedate); + // if (((ck == NULL) || (*ck != '\0') )&&!(optdate)) + // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); + // /* else */ if (filenamedate.tm_year < 70) + // fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", buff); + // tx= mkgmtime(&filenamedate); + } } -static void +static void gopal_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void gopal_read(void) { - char *buff; - char *str, *c; - int column; - long line; - double hmsd,speed; - int fix, hms; - route_head *route; - waypoint *wpt, *lastwpt=NULL; - double long_old,lat_old; - char tbuffer[64]; - struct tm tm2; - long_old=0;lat_old=0; - strftime(routename,sizeof(routename),"Tracklog %c",gmtime(&tx)); - - route = route_head_alloc(); - route->rte_name=xstrdup(routename); - route_add_head(route); - - line=0; - while ((buff = gbfgetstr(fin))) - { - int nfields; - unsigned long microsecs; - if ((line == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - str = buff = lrtrim(buff); - if (*buff == '\0') continue; - nfields = gopal_check_line(buff); - if ((nfields != 8) && (nfields != 11))continue; - // Old format. Hassle for date. - if ((nfields == 8) && (tx == 0)) { - // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); - } - wpt = waypt_new(); - - column = -1; - // the format of gopal is quite simple. Unfortunately the developers forgot the date as the first element... - //TICK; TIME; LONG; LAT; HEIGHT; SPEED; Fix; HDOP; SAT - //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 - c = csv_lineparse(str, ",", "", column++); - while (c != NULL) - { - switch(column) - { - case 0: /* "-" */ /* unknown fields for the moment */ - sscanf(c, "%lu", µsecs); - wpt->microseconds += microsecs % 1000000; - wpt->creation_time += microsecs / 1000000; - break; - case 1: /* Time UTC */ - sscanf(c,"%lf",&hmsd); - hms = (int) hmsd; - tm.tm_sec = hms % 100; - hms = hms / 100; - tm.tm_min = hms % 100; - hms = hms / 100; - tm.tm_hour = hms % 100; - tm.tm_year=trackdate.tm_year; - tm.tm_mon=trackdate.tm_mon; - tm.tm_mday=trackdate.tm_mday; - wpt->creation_time = tx+((((time_t)tm.tm_hour * 60) + tm.tm_min) * 60) + tm.tm_sec; - if (global_opts.debug_level > 1){ - strftime(tbuffer, sizeof(tbuffer), "%c", gmtime(&wpt->creation_time)); - printf("parsed timestamp: %s\n",tbuffer); - } - break; - - case 2: /* longitude */ - sscanf(c, "%lf", &wpt->longitude); - break; - - case 3: /* latitude */ - sscanf(c, "%lf", &wpt->latitude); - break; - case 4: /* altitude */ - sscanf(c, "%lf", &wpt->altitude); - break; - case 5: /* speed */ - //sscanf(c, "%lf", &wpt->speed); - wpt->speed=atof(c); - if (global_opts.debug_level > 1){ - printf("parsed speed: %8.5f\n",wpt->speed); - } - break; - case 6: /* type of fix */ - sscanf(c, "%d", &fix); - //my device shows only 0 or 2 - //should i guess from no of sats if 2d or 3d? - switch (fix) { - case 0: wpt->fix = fix_none;break; - case 2: wpt->fix = fix_2d;break; - //case 3: wpt->fix = fix_3d;break; - //case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ - //case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ - default: - wpt->fix = fix_unknown; - break; - } - break; - case 7: /* hdop */ - wpt->hdop = atof(c); - //sscanf(c, "%lf", &wpt->hdop); does not work ??? - //wpt->vdop=0;wpt->hdop=0; - break; - case 8: /* number of sats */ - sscanf(c, "%d", &wpt->sat); - break; - // Somewhere around mid/late 2009, these files started - // seeing 11 fields. - case 9: - memset(&tm2, 0, sizeof(tm2)); - if (!strptime(c, "%Y%m%d", &tm2)) { - fatal ("Bad date '%s'.\n", c); - } - wpt->creation_time += mkgmtime(&tm2); - break; - case 10: // Unknown. Ignored. - case 11: // Bearing. Ignored. - break; - } - c = csv_lineparse(NULL, ",", "", column++); - } - line++; - - if ((wpt->fix != fix_none)&&(lat_old==0)){ //first-time init - lat_old=wpt->latitude; - long_old=wpt->longitude; - //route_add_wpt(route, wpt); - lastwpt=wpt; - } - //calculate the speed to reach this waypoint from the last. This way I try to sort out invalid waypoints - speed=0; - if (lastwpt !=NULL) - { - speed=3.6*radtometers(gcdist(RAD(lastwpt->latitude), RAD(lastwpt->longitude), RAD(wpt->latitude), RAD(wpt->longitude))) / abs(wpt->creation_time - lastwpt->creation_time); - //printf("speed line %d %lf \n",line,speed); - } - /* Error handling: in the tracklog of my device sometimes "jump" waypoints ;-) */ - if ((optclean) && - (((wpt->longitude==0.0)|| (wpt->latitude==0.0)||(abs(wpt->latitude)>90)||(abs(wpt->longitude)>180))|| - ((speed>maxspeed)||(speed 1) fprintf(stderr,"Problem in or around line %5lu: \"%s\" %lf km/h\n",line,buff,speed); - } - else - { - if (global_opts.debug_level > 1) fprintf(stderr,"valid line %5lu: \"%s\" %lf km/h\n",line,buff,speed); - lastwpt=wpt; - long_old=wpt->longitude; - lat_old=wpt->latitude; - route_add_wpt(route,wpt); - waypt_add(waypt_dupe( wpt)); - } - } + char* buff; + char* str, *c; + int column; + long line; + double hmsd,speed; + int fix, hms; + route_head* route; + waypoint* wpt, *lastwpt=NULL; + double long_old,lat_old; + char tbuffer[64]; + struct tm tm2; + long_old=0; + lat_old=0; + strftime(routename,sizeof(routename),"Tracklog %c",gmtime(&tx)); + + route = route_head_alloc(); + route->rte_name=xstrdup(routename); + route_add_head(route); + + line=0; + while ((buff = gbfgetstr(fin))) { + int nfields; + unsigned long microsecs; + if ((line == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + str = buff = lrtrim(buff); + if (*buff == '\0') { + continue; + } + nfields = gopal_check_line(buff); + if ((nfields != 8) && (nfields != 11)) { + continue; + } + // Old format. Hassle for date. + if ((nfields == 8) && (tx == 0)) { + // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); + } + wpt = waypt_new(); + + column = -1; + // the format of gopal is quite simple. Unfortunately the developers forgot the date as the first element... + //TICK; TIME; LONG; LAT; HEIGHT; SPEED; Fix; HDOP; SAT + //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 + c = csv_lineparse(str, ",", "", column++); + while (c != NULL) { + switch (column) { + case 0: /* "-" */ /* unknown fields for the moment */ + sscanf(c, "%lu", µsecs); + wpt->microseconds += microsecs % 1000000; + wpt->creation_time += microsecs / 1000000; + break; + case 1: /* Time UTC */ + sscanf(c,"%lf",&hmsd); + hms = (int) hmsd; + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + tm.tm_year=trackdate.tm_year; + tm.tm_mon=trackdate.tm_mon; + tm.tm_mday=trackdate.tm_mday; + wpt->creation_time = tx+((((time_t)tm.tm_hour * 60) + tm.tm_min) * 60) + tm.tm_sec; + if (global_opts.debug_level > 1) { + strftime(tbuffer, sizeof(tbuffer), "%c", gmtime(&wpt->creation_time)); + printf("parsed timestamp: %s\n",tbuffer); + } + break; + + case 2: /* longitude */ + sscanf(c, "%lf", &wpt->longitude); + break; + + case 3: /* latitude */ + sscanf(c, "%lf", &wpt->latitude); + break; + case 4: /* altitude */ + sscanf(c, "%lf", &wpt->altitude); + break; + case 5: /* speed */ + //sscanf(c, "%lf", &wpt->speed); + wpt->speed=atof(c); + if (global_opts.debug_level > 1) { + printf("parsed speed: %8.5f\n",wpt->speed); + } + break; + case 6: /* type of fix */ + sscanf(c, "%d", &fix); + //my device shows only 0 or 2 + //should i guess from no of sats if 2d or 3d? + switch (fix) { + case 0: + wpt->fix = fix_none; + break; + case 2: + wpt->fix = fix_2d; + break; + //case 3: wpt->fix = fix_3d;break; + //case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ + //case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ + default: + wpt->fix = fix_unknown; + break; + } + break; + case 7: /* hdop */ + wpt->hdop = atof(c); + //sscanf(c, "%lf", &wpt->hdop); does not work ??? + //wpt->vdop=0;wpt->hdop=0; + break; + case 8: /* number of sats */ + sscanf(c, "%d", &wpt->sat); + break; + // Somewhere around mid/late 2009, these files started + // seeing 11 fields. + case 9: + memset(&tm2, 0, sizeof(tm2)); + if (!strptime(c, "%Y%m%d", &tm2)) { + fatal("Bad date '%s'.\n", c); + } + wpt->creation_time += mkgmtime(&tm2); + break; + case 10: // Unknown. Ignored. + case 11: // Bearing. Ignored. + break; + } + c = csv_lineparse(NULL, ",", "", column++); + } + line++; + + if ((wpt->fix != fix_none)&&(lat_old==0)) { //first-time init + lat_old=wpt->latitude; + long_old=wpt->longitude; + //route_add_wpt(route, wpt); + lastwpt=wpt; + } + //calculate the speed to reach this waypoint from the last. This way I try to sort out invalid waypoints + speed=0; + if (lastwpt !=NULL) { + speed=3.6*radtometers(gcdist(RAD(lastwpt->latitude), RAD(lastwpt->longitude), RAD(wpt->latitude), RAD(wpt->longitude))) / abs(wpt->creation_time - lastwpt->creation_time); + //printf("speed line %d %lf \n",line,speed); + } + /* Error handling: in the tracklog of my device sometimes "jump" waypoints ;-) */ + if ((optclean) && + (((wpt->longitude==0.0)|| (wpt->latitude==0.0)||(abs(wpt->latitude)>90)||(abs(wpt->longitude)>180))|| + ((speed>maxspeed)||(speed 1) { + fprintf(stderr,"Problem in or around line %5lu: \"%s\" %lf km/h\n",line,buff,speed); + } + } else { + if (global_opts.debug_level > 1) { + fprintf(stderr,"valid line %5lu: \"%s\" %lf km/h\n",line,buff,speed); + } + lastwpt=wpt; + long_old=wpt->longitude; + lat_old=wpt->latitude; + route_add_wpt(route,wpt); + waypt_add(waypt_dupe(wpt)); + } + } } -static void -gopal_route_hdr(const route_head *route) +static void +gopal_route_hdr(const route_head* route) { - + } -static void -gopal_route_tlr(const route_head *rte) +static void +gopal_route_tlr(const route_head* rte) { } static void -gopal_write_waypt(const waypoint *wpt) +gopal_write_waypt(const waypoint* wpt) { - char tbuffer[64]; - unsigned long timestamp; - int fix=fix_unknown; - //TICK; TIME; LONG; LAT; HEIGHT; SPEED; UN; HDOP; SAT - //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 - strftime(tbuffer, sizeof(tbuffer), "%H%M%S", gmtime(&wpt->creation_time)); - if (wpt->fix!=fix_unknown) { - switch (wpt->fix) - { - case fix_none: fix = 0; break; - case fix_2d: fix = 2; break; - default: fix = 0; break; - } - } - //MSVC handles time_t as int64, gcc and mac only int32, so convert it: - timestamp=(unsigned long)wpt->creation_time; - gbfprintf(fout, "%lu, %s, %lf, %lf, %5.1lf, %8.5lf, %d, %lf, %d\n",timestamp,tbuffer, wpt->longitude, wpt->latitude,wpt->altitude, - wpt->speed,fix,wpt->hdop,wpt->sat); + char tbuffer[64]; + unsigned long timestamp; + int fix=fix_unknown; + //TICK; TIME; LONG; LAT; HEIGHT; SPEED; UN; HDOP; SAT + //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 + strftime(tbuffer, sizeof(tbuffer), "%H%M%S", gmtime(&wpt->creation_time)); + if (wpt->fix!=fix_unknown) { + switch (wpt->fix) { + case fix_none: + fix = 0; + break; + case fix_2d: + fix = 2; + break; + default: + fix = 0; + break; + } + } + //MSVC handles time_t as int64, gcc and mac only int32, so convert it: + timestamp=(unsigned long)wpt->creation_time; + gbfprintf(fout, "%lu, %s, %lf, %lf, %5.1lf, %8.5lf, %d, %lf, %d\n",timestamp,tbuffer, wpt->longitude, wpt->latitude,wpt->altitude, + wpt->speed,fix,wpt->hdop,wpt->sat); } static void -gopal_wr_init(const char *fname) +gopal_wr_init(const char* fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } static void gopal_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void gopal_write(void) { - route_disp_all(gopal_route_hdr, gopal_route_tlr, gopal_write_waypt); + route_disp_all(gopal_route_hdr, gopal_route_tlr, gopal_write_waypt); } static void @@ -387,24 +398,24 @@ gopal_exit(void) /* optional */ /**************************************************************************/ // capabilities below means: we can only read and write waypoints -// +// ff_vecs_t gopal_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - gopal_rd_init, - gopal_wr_init, - gopal_rd_deinit, - gopal_wr_deinit, - gopal_read, - gopal_write, - gopal_exit, - gopal_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + gopal_rd_init, + gopal_wr_init, + gopal_rd_deinit, + gopal_wr_deinit, + gopal_read, + gopal_write, + gopal_exit, + gopal_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/gpilots.c b/gpsbabel/gpilots.c index fc567c471..55e04a189 100644 --- a/gpsbabel/gpilots.c +++ b/gpsbabel/gpilots.c @@ -34,410 +34,402 @@ /* * Structures grafted from http://www.cru.fr/perso/cc/GPilotS/ */ - -typedef struct -{ - long lat; /* latitude in semicircles */ - long lon; /* longitude in semicircles */ + +typedef struct { + long lat; /* latitude in semicircles */ + long lon; /* longitude in semicircles */ } Semicircle_Type; -typedef struct -{ - char ident[6]; /* identifier */ - unsigned char lat[4]; /* position */ - unsigned char lon[4]; /* position */ - unsigned char unused[4]; /* should be set to zero */ - char cmnt[40]; /* comment */ - unsigned char smbl; /* symbol id */ - unsigned char dspl; /* display option */ +typedef struct { + char ident[6]; /* identifier */ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char unused[4]; /* should be set to zero */ + char cmnt[40]; /* comment */ + unsigned char smbl; /* symbol id */ + unsigned char dspl; /* display option */ } D103_Wpt_Type; typedef union { - float f; - unsigned int i; + float f; + unsigned int i; } fi_t; -typedef struct /* size */ -{ - unsigned char wpt_class; /* class (see below) 1 */ - unsigned char color; /* color (see below) 1 */ - unsigned char dspl; /* display options (see below) 1 */ - unsigned char attr; /* attributes (see below) 1 */ - unsigned char smbl[2]; /* waypoint symbol 2 */ - unsigned char subclass[18]; /* subclass 18 */ - unsigned char lat[4]; /* position */ - unsigned char lon[4]; /* position */ - float alt; /* altitude in meters 4 */ - float dpth; /* depth in meters 4 */ - float dist; /* proximity distance in meters 4 */ - char state[2]; /* state 2 */ - char cc[2]; /* country code 2 */ - char varlenstrs[1]; /* start of variable length strings */ - /* G_char ident[]; variable length string 1-51 */ - /* G_char comment[]; waypoint user comment 1-51 */ - /* G_char facility[]; facility name 1-31 */ - /* G_char city[]; city name 1-25 */ - /* G_char addr[]; address number 1-51 */ - /* G_char cross_road[]; intersecting road label 1-51 */ +typedef struct { /* size */ + unsigned char wpt_class; /* class (see below) 1 */ + unsigned char color; /* color (see below) 1 */ + unsigned char dspl; /* display options (see below) 1 */ + unsigned char attr; /* attributes (see below) 1 */ + unsigned char smbl[2]; /* waypoint symbol 2 */ + unsigned char subclass[18]; /* subclass 18 */ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + float alt; /* altitude in meters 4 */ + float dpth; /* depth in meters 4 */ + float dist; /* proximity distance in meters 4 */ + char state[2]; /* state 2 */ + char cc[2]; /* country code 2 */ + char varlenstrs[1]; /* start of variable length strings */ + /* G_char ident[]; variable length string 1-51 */ + /* G_char comment[]; waypoint user comment 1-51 */ + /* G_char facility[]; facility name 1-31 */ + /* G_char city[]; city name 1-25 */ + /* G_char addr[]; address number 1-51 */ + /* G_char cross_road[]; intersecting road label 1-51 */ } D108_Wpt_Type; -typedef struct /* structure de waypoint "interne" */ -{ - unsigned char ident[51]; /* identifier (50 + '0') */ - Semicircle_Type posn; /* position (common to all Garmin types) */ - unsigned char cmnt[51]; /* comment (50 + '0') */ - float dst; /* proximity distance */ - float alt; /* altitude */ - int smbl; /* symbol id */ - unsigned char dspl; /* display option */ - unsigned char color; /* color */ +typedef struct { /* structure de waypoint "interne" */ + unsigned char ident[51]; /* identifier (50 + '0') */ + Semicircle_Type posn; /* position (common to all Garmin types) */ + unsigned char cmnt[51]; /* comment (50 + '0') */ + float dst; /* proximity distance */ + float alt; /* altitude */ + int smbl; /* symbol id */ + unsigned char dspl; /* display option */ + unsigned char color; /* color */ } Custom_Wpt_Type; -typedef struct /* internal track header */ -{ - char name[256]; /* nom du groupe de trackpoints */ - unsigned char dspl; /* display on the map ? */ - unsigned char color; /* color */ - unsigned char type; /* type of following track points */ - unsigned char unused; /* type of following track points */ - unsigned char number[2]; /* number of track points */ - unsigned char latmin[4]; /* latitude min */ - unsigned char latmax[4]; /* latitude max */ - unsigned char lonmin[4]; /* longitude min */ - unsigned char lonmax[4]; /* longitude max */ - unsigned char unused2[2]; /* type of following track points */ +typedef struct { /* internal track header */ + char name[256]; /* nom du groupe de trackpoints */ + unsigned char dspl; /* display on the map ? */ + unsigned char color; /* color */ + unsigned char type; /* type of following track points */ + unsigned char unused; /* type of following track points */ + unsigned char number[2]; /* number of track points */ + unsigned char latmin[4]; /* latitude min */ + unsigned char latmax[4]; /* latitude max */ + unsigned char lonmin[4]; /* longitude min */ + unsigned char lonmax[4]; /* longitude max */ + unsigned char unused2[2]; /* type of following track points */ } Custom_Trk_Hdr_Type; -typedef struct -{ - unsigned char lat[4]; /* position */ - unsigned char lon[4]; /* position */ - unsigned char time[4]; - unsigned char alt[4]; - unsigned char new_trk; - unsigned char unused; +typedef struct { + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char time[4]; + unsigned char alt[4]; + unsigned char new_trk; + unsigned char unused; } Custom_Trk_Point_Type; -typedef struct /* custom compact track point type */ -{ - unsigned char lat[4]; /* position */ - unsigned char lon[4]; /* position */ - unsigned char new_trk; - unsigned char unused; +typedef struct { /* custom compact track point type */ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char new_trk; + unsigned char unused; } Compact_Trk_Point_Type; /* size : 10 bytes */ -struct record -{ - struct { - unsigned char type; - unsigned short size; - unsigned int version; - } header; - union { - D103_Wpt_Type d103; - D108_Wpt_Type d108; - Custom_Wpt_Type CustWpt; - Custom_Trk_Hdr_Type CustTrkHdr; +struct record { + struct { + unsigned char type; + unsigned short size; + unsigned int version; + } header; + union { + D103_Wpt_Type d103; + D108_Wpt_Type d108; + Custom_Wpt_Type CustWpt; + Custom_Trk_Hdr_Type CustTrkHdr; #if LATER - Custom_Rte_Hdr_Type CustRteHdr; + Custom_Rte_Hdr_Type CustRteHdr; #endif - } wpt; + } wpt; }; -static pdbfile *file_in, *file_out; -static const char *out_fname; +static pdbfile* file_in, *file_out; +static const char* out_fname; static int ct = 0; -static char *dbname = NULL; +static char* dbname = NULL; static arglist_t my_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_in); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; } static void wr_deinit(void) { - pdb_close(file_out); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; - route_head *track_head = NULL; - - if (file_in->creator != MYCREATOR) { - fatal(MYNAME ": Not a %s file.\n", MYNAME); - } - - switch(file_in->type) { - case MYWPT: - /* blah */ - break; - case MYTRK: - /* blah */ - break; - default: - fatal(MYNAME ": Unknown file type 0x%x\n", (int) file_in->type); - } - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { - waypoint *wpt_tmp; - Custom_Trk_Point_Type *tp_cust; - Compact_Trk_Point_Type *tp_comp; - int lat; - int lon; - int sz; - fi_t fi; - int trk_num = 0; - int trk_seg_num = 1; - char trk_seg_num_buf[10]; - char *trk_name = ""; - - wpt_tmp = waypt_new(); - - rec = (struct record *) pdb_rec->data; - switch(rec->header.type) { - /* - * G103Type - */ - case 4: - wpt_tmp->shortname = xstrndupt(rec->wpt.d103.ident, sizeof(rec->wpt.d103.ident)); - wpt_tmp->description = xstrndupt(rec->wpt.d103.cmnt, sizeof(rec->wpt.d103.cmnt)); - /* This is odd. This is a Palm DB file, - * yet the data appears to be little endian, - * not appropriate the the actual Palm. - */ - lon = le_read32(&rec->wpt.d103.lon); - lat = le_read32(&rec->wpt.d103.lat); - wpt_tmp->longitude = lon / 2147483648.0 * 180.0; - wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - waypt_add(wpt_tmp); - break; - /* - * G108Type - */ - case 9: - wpt_tmp->shortname = xstrndupt(rec->wpt.d108.varlenstrs, 50); - wpt_tmp->description = xstrndupt(rec->wpt.d108.varlenstrs + strlen(wpt_tmp->shortname) + 1, 50); - /* This is odd. This is a Palm DB file, - * yet the data appears to be little endian, - * not appropriate the the actual Palm. - */ - lon = le_read32(&rec->wpt.d108.lon); - lat = le_read32(&rec->wpt.d108.lat); - wpt_tmp->longitude = lon / 2147483648.0 * 180.0; - wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - fi.i = le_read32(&rec->wpt.d108.alt); - wpt_tmp->altitude = fi.f; - fi.i = le_read32(&rec->wpt.d108.dpth); - WAYPT_SET(wpt_tmp, depth, fi.f); - fi.i = le_read32(&rec->wpt.d108.dist); - WAYPT_SET(wpt_tmp, proximity, fi.f); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 0; - wpt_tmp->icon_descr = gt_find_desc_from_icon_number((rec->wpt.d108.smbl[1] << 8) + rec->wpt.d108.smbl[0], PCX, NULL); - waypt_add(wpt_tmp); - break; - - /* - * CustomTrkHdr - */ - case 101: - trk_name = rec->wpt.CustTrkHdr.name; - sz = be_read16(&rec->wpt.CustTrkHdr.number); - - /* switch between custom track points and compact track points. - * (compact points have no altitude and time info. - */ - switch (rec->wpt.CustTrkHdr.type) { - case 102: - tp_cust = (Custom_Trk_Point_Type *) ((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); - while (sz--) { - if ((int)(tp_cust->new_trk) == 1 || trk_seg_num == 1) { - /* - * Start a new track segment - */ - track_head = route_head_alloc(); - if (trk_seg_num == 1) { - track_head->rte_name = xstrdup(trk_name); - } else { - /* name in the form TRACKNAME #n */ - snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); - track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); - sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); - } - trk_seg_num++; - track_head->rte_num = trk_num; - trk_num++; - track_add_head(track_head); - } - - wpt_tmp = waypt_new(); - - /* This is even more odd. - * Track data is stored as big endian while - * waypoint data is little endian!? - */ - lon = be_read32(&tp_cust->lon); - lat = be_read32(&tp_cust->lat); - wpt_tmp->longitude = lon / 2147483648.0 * 180.0; - wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - /* - * Convert Garmin/GPilotS time format to gpsbabel time format. - * Garmin/GPilotS count seconds from "UTC 12:00 AM December 31 1989". - * gpsbabel counts seconds from "UTC 12:00 AM January 1 1970". - */ - wpt_tmp->creation_time = be_read32(&tp_cust->time) + 631065600; - fi.i = be_read32(&tp_cust->alt); - wpt_tmp->altitude = fi.f; - track_add_wpt(track_head, wpt_tmp); - tp_cust++; - } - break; - case 104: - tp_comp = (Compact_Trk_Point_Type *) ((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); - while (sz--) { - if ((int)(tp_comp->new_trk) == 1 || trk_seg_num == 1) { - /* - * Start a new track segment - */ - track_head = route_head_alloc(); - if (trk_seg_num == 1) { - track_head->rte_name = xstrdup(trk_name); - } else { - /* name in the form TRACKNAME #n */ - snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); - track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); - sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); - } - trk_seg_num++; - track_head->rte_num = trk_num; - trk_num++; - track_add_head(track_head); - } - - wpt_tmp = waypt_new(); - lon = be_read32(&tp_comp->lon); - lat = be_read32(&tp_comp->lat); - wpt_tmp->longitude = lon / 2147483648.0 * 180.0; - wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - track_add_wpt(track_head, wpt_tmp); - tp_comp++; - } - break; - default: - fatal(MYNAME ": track point type %d not supported.\n", rec->wpt.CustTrkHdr.type); - } - break; - default: - fatal(MYNAME ": input record type %d not supported.\n", rec->header.type); - } - - } + struct record* rec; + pdbrec_t* pdb_rec; + route_head* track_head = NULL; + + if (file_in->creator != MYCREATOR) { + fatal(MYNAME ": Not a %s file.\n", MYNAME); + } + + switch (file_in->type) { + case MYWPT: + /* blah */ + break; + case MYTRK: + /* blah */ + break; + default: + fatal(MYNAME ": Unknown file type 0x%x\n", (int) file_in->type); + } + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { + waypoint* wpt_tmp; + Custom_Trk_Point_Type* tp_cust; + Compact_Trk_Point_Type* tp_comp; + int lat; + int lon; + int sz; + fi_t fi; + int trk_num = 0; + int trk_seg_num = 1; + char trk_seg_num_buf[10]; + char* trk_name = ""; + + wpt_tmp = waypt_new(); + + rec = (struct record*) pdb_rec->data; + switch (rec->header.type) { + /* + * G103Type + */ + case 4: + wpt_tmp->shortname = xstrndupt(rec->wpt.d103.ident, sizeof(rec->wpt.d103.ident)); + wpt_tmp->description = xstrndupt(rec->wpt.d103.cmnt, sizeof(rec->wpt.d103.cmnt)); + /* This is odd. This is a Palm DB file, + * yet the data appears to be little endian, + * not appropriate the the actual Palm. + */ + lon = le_read32(&rec->wpt.d103.lon); + lat = le_read32(&rec->wpt.d103.lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + waypt_add(wpt_tmp); + break; + /* + * G108Type + */ + case 9: + wpt_tmp->shortname = xstrndupt(rec->wpt.d108.varlenstrs, 50); + wpt_tmp->description = xstrndupt(rec->wpt.d108.varlenstrs + strlen(wpt_tmp->shortname) + 1, 50); + /* This is odd. This is a Palm DB file, + * yet the data appears to be little endian, + * not appropriate the the actual Palm. + */ + lon = le_read32(&rec->wpt.d108.lon); + lat = le_read32(&rec->wpt.d108.lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + fi.i = le_read32(&rec->wpt.d108.alt); + wpt_tmp->altitude = fi.f; + fi.i = le_read32(&rec->wpt.d108.dpth); + WAYPT_SET(wpt_tmp, depth, fi.f); + fi.i = le_read32(&rec->wpt.d108.dist); + WAYPT_SET(wpt_tmp, proximity, fi.f); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 0; + wpt_tmp->icon_descr = gt_find_desc_from_icon_number((rec->wpt.d108.smbl[1] << 8) + rec->wpt.d108.smbl[0], PCX, NULL); + waypt_add(wpt_tmp); + break; + + /* + * CustomTrkHdr + */ + case 101: + trk_name = rec->wpt.CustTrkHdr.name; + sz = be_read16(&rec->wpt.CustTrkHdr.number); + + /* switch between custom track points and compact track points. + * (compact points have no altitude and time info. + */ + switch (rec->wpt.CustTrkHdr.type) { + case 102: + tp_cust = (Custom_Trk_Point_Type*)((char*) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); + while (sz--) { + if ((int)(tp_cust->new_trk) == 1 || trk_seg_num == 1) { + /* + * Start a new track segment + */ + track_head = route_head_alloc(); + if (trk_seg_num == 1) { + track_head->rte_name = xstrdup(trk_name); + } else { + /* name in the form TRACKNAME #n */ + snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); + track_head->rte_name = (char*) xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); + sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); + } + trk_seg_num++; + track_head->rte_num = trk_num; + trk_num++; + track_add_head(track_head); + } + + wpt_tmp = waypt_new(); + + /* This is even more odd. + * Track data is stored as big endian while + * waypoint data is little endian!? + */ + lon = be_read32(&tp_cust->lon); + lat = be_read32(&tp_cust->lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + /* + * Convert Garmin/GPilotS time format to gpsbabel time format. + * Garmin/GPilotS count seconds from "UTC 12:00 AM December 31 1989". + * gpsbabel counts seconds from "UTC 12:00 AM January 1 1970". + */ + wpt_tmp->creation_time = be_read32(&tp_cust->time) + 631065600; + fi.i = be_read32(&tp_cust->alt); + wpt_tmp->altitude = fi.f; + track_add_wpt(track_head, wpt_tmp); + tp_cust++; + } + break; + case 104: + tp_comp = (Compact_Trk_Point_Type*)((char*) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); + while (sz--) { + if ((int)(tp_comp->new_trk) == 1 || trk_seg_num == 1) { + /* + * Start a new track segment + */ + track_head = route_head_alloc(); + if (trk_seg_num == 1) { + track_head->rte_name = xstrdup(trk_name); + } else { + /* name in the form TRACKNAME #n */ + snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); + track_head->rte_name = (char*) xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); + sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); + } + trk_seg_num++; + track_head->rte_num = trk_num; + trk_num++; + track_add_head(track_head); + } + + wpt_tmp = waypt_new(); + lon = be_read32(&tp_comp->lon); + lat = be_read32(&tp_comp->lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + track_add_wpt(track_head, wpt_tmp); + tp_comp++; + } + break; + default: + fatal(MYNAME ": track point type %d not supported.\n", rec->wpt.CustTrkHdr.type); + } + break; + default: + fatal(MYNAME ": input record type %d not supported.\n", rec->header.type); + } + + } } -struct hdr{ - char *wpt_name; - waypoint *wpt; +struct hdr { + char* wpt_name; + waypoint* wpt; }; static void -my_write_wpt(const waypoint *wpt) +my_write_wpt(const waypoint* wpt) { - struct record *rec; - char *vdata; - int lat, lon; - - rec = xcalloc(sizeof *rec, 1); - vdata = (char *)rec + sizeof (*rec); - - rec->header.type = 4; - rec->header.size = 5; - rec->header.version = 6; - - strncpy(rec->wpt.d103.ident, wpt->shortname, sizeof(rec->wpt.d103.ident)); - strncpy(rec->wpt.d103.cmnt, wpt->description, sizeof(rec->wpt.d103.cmnt)); - lat = wpt->latitude / 180.0 * 2147483648.0; - lon = wpt->longitude / 180.0 * 2147483648.0; - le_write32(&rec->wpt.d103.lat, lat); - le_write32(&rec->wpt.d103.lon, lon); - - pdb_write_rec(file_out, 0, ct, ct+1, rec, (char *)vdata - (char *)rec); - ct++; - xfree(rec); + struct record* rec; + char* vdata; + int lat, lon; + + rec = (struct record*) xcalloc(sizeof *rec, 1); + vdata = (char*)rec + sizeof(*rec); + + rec->header.type = 4; + rec->header.size = 5; + rec->header.version = 6; + + strncpy(rec->wpt.d103.ident, wpt->shortname, sizeof(rec->wpt.d103.ident)); + strncpy(rec->wpt.d103.cmnt, wpt->description, sizeof(rec->wpt.d103.cmnt)); + lat = wpt->latitude / 180.0 * 2147483648.0; + lon = wpt->longitude / 180.0 * 2147483648.0; + le_write32(&rec->wpt.d103.lat, lat); + le_write32(&rec->wpt.d103.lon, lon); + + pdb_write_rec(file_out, 0, ct, ct+1, rec, (char*)vdata - (char*)rec); + ct++; + xfree(rec); } static void data_write(void) { - if ( dbname ) { - strncpy( file_out->name, dbname, PDB_DBNAMELEN ); - } else { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - } - - /* - * Populate header. - */ - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - - file_out->type = MYWPT; - file_out->creator = MYCREATOR; - file_out->version = 1; - - waypt_disp_all(my_write_wpt); + if (dbname) { + strncpy(file_out->name, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + + /* + * Populate header. + */ + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + + file_out->type = MYWPT; + file_out->creator = MYCREATOR; + file_out->version = 1; + + waypt_disp_all(my_write_wpt); } ff_vecs_t gpilots_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_none}, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - my_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { (ff_cap)(ff_cap_read | ff_cap_write), (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none}, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + my_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/gpspilot.c b/gpsbabel/gpspilot.c index 31ebf8dcc..c3dad5d8d 100644 --- a/gpsbabel/gpspilot.c +++ b/gpsbabel/gpspilot.c @@ -32,209 +32,203 @@ #define MYCREATOR 0x47704c69 /* GpLi */ struct record { - pdb_32 longitude; /* Big endian, long * 3.6e6 */ - pdb_32 latitude; /* similarly */ - pdb_16 elevation; /* meters */ - pdb_16 magvar; /* magnetic variation in degrees, neg = west */ + pdb_32 longitude; /* Big endian, long * 3.6e6 */ + pdb_32 latitude; /* similarly */ + pdb_16 elevation; /* meters */ + pdb_16 magvar; /* magnetic variation in degrees, neg = west */ }; struct runways { - pdb_32 be_longitude; /* Big endian, long * 3.6e6 */ - pdb_32 be_latitude; /* similarly */ - pdb_32 en_longitude; /* Big endian, long * 3.6e6 */ - pdb_32 en_latitude; /* similarly */ + pdb_32 be_longitude; /* Big endian, long * 3.6e6 */ + pdb_32 be_latitude; /* similarly */ + pdb_32 en_longitude; /* Big endian, long * 3.6e6 */ + pdb_32 en_latitude; /* similarly */ }; -static pdbfile *file_in, *file_out; -static const char *out_fname; -static char *dbname = NULL; +static pdbfile* file_in, *file_out; +static const char* out_fname; +static char* dbname = NULL; static int ct; static arglist_t gpspilot_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_in); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; - - if ((file_in->creator != MYCREATOR)) { - fatal(MYNAME ": Not a gpspilot file.\n"); - } - - switch (file_in->type) - { - case MYTYPE_AIRPORT: - case MYTYPE_POINTS: - case MYTYPE_CITIES: - case MYTYPE_LNDMRKS: - case MYTYPE_NAVAIDS: - break; - default: - fatal(MYNAME ": Not a gpspilot file.\n"); - } - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { - waypoint *wpt_tmp; - char *vdata; - - wpt_tmp = waypt_new(); - - rec = (struct record *) pdb_rec->data; - wpt_tmp->longitude = be_read32(&rec->longitude) / 3.6e6; - wpt_tmp->latitude = be_read32(&rec->latitude) / 3.6e6; - wpt_tmp->altitude = - be_read16(&rec->elevation); - - vdata = (char *) pdb_rec->data + sizeof(*rec); - - /* - * skip runway records if an airport. - */ - if (pdb_rec->category == 0) - { - int numRunways; - numRunways = be_read16(vdata); - vdata += 2; - vdata += (sizeof(struct runways) * numRunways); - } - - /* - * This maping is a bit contrived. - * Name is up to 36. ID is up to 9. - * Since 'ID' maps more clearly to "shortname" (and this - * more likely to be resemble a wayoint name in another - * receiver) we use that for shortname and use 'name' as - * our description. - */ - wpt_tmp->description = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->shortname = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->notes = xstrdup(vdata); - - waypt_add(wpt_tmp); - - } + struct record* rec; + pdbrec_t* pdb_rec; + + if ((file_in->creator != MYCREATOR)) { + fatal(MYNAME ": Not a gpspilot file.\n"); + } + + switch (file_in->type) { + case MYTYPE_AIRPORT: + case MYTYPE_POINTS: + case MYTYPE_CITIES: + case MYTYPE_LNDMRKS: + case MYTYPE_NAVAIDS: + break; + default: + fatal(MYNAME ": Not a gpspilot file.\n"); + } + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint* wpt_tmp; + char* vdata; + + wpt_tmp = waypt_new(); + + rec = (struct record*) pdb_rec->data; + wpt_tmp->longitude = be_read32(&rec->longitude) / 3.6e6; + wpt_tmp->latitude = be_read32(&rec->latitude) / 3.6e6; + wpt_tmp->altitude = + be_read16(&rec->elevation); + + vdata = (char*) pdb_rec->data + sizeof(*rec); + + /* + * skip runway records if an airport. + */ + if (pdb_rec->category == 0) { + int numRunways; + numRunways = be_read16(vdata); + vdata += 2; + vdata += (sizeof(struct runways) * numRunways); + } + + /* + * This maping is a bit contrived. + * Name is up to 36. ID is up to 9. + * Since 'ID' maps more clearly to "shortname" (and this + * more likely to be resemble a wayoint name in another + * receiver) we use that for shortname and use 'name' as + * our description. + */ + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + waypt_add(wpt_tmp); + + } } static void -gpspilot_writewpt(const waypoint *wpt) +gpspilot_writewpt(const waypoint* wpt) { - struct record *rec; - char *vdata; - - rec = xcalloc(sizeof(*rec)+206,1); - - be_write32(&rec->longitude, si_round(wpt->longitude * 3.6e6)); - be_write32(&rec->latitude, si_round(wpt->latitude * 3.6e6)); - be_write16(&rec->elevation, si_round(wpt->altitude)); - be_write16(&rec->magvar, 0 ); - - vdata = (char *)rec + sizeof(*rec); - if ( wpt->description ) { - strncpy( vdata, wpt->description, 36 ); - vdata[35] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - if ( wpt->shortname ) { - strncpy( vdata, wpt->shortname, 9 ); - vdata[8] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - if ( wpt->notes ) { - strncpy( vdata, wpt->notes, 161 ); - vdata[160] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - pdb_write_rec(file_out, 0, 2, ct++, (void *)rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct record* rec; + char* vdata; + + rec = (struct record*) xcalloc(sizeof(*rec)+206,1); + + be_write32(&rec->longitude, si_round(wpt->longitude * 3.6e6)); + be_write32(&rec->latitude, si_round(wpt->latitude * 3.6e6)); + be_write16(&rec->elevation, si_round(wpt->altitude)); + be_write16(&rec->magvar, 0); + + vdata = (char*)rec + sizeof(*rec); + if (wpt->description) { + strncpy(vdata, wpt->description, 36); + vdata[35] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + if (wpt->shortname) { + strncpy(vdata, wpt->shortname, 9); + vdata[8] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + if (wpt->notes) { + strncpy(vdata, wpt->notes, 161); + vdata[160] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, (void*)rec, (char*)vdata - (char*)rec); + + xfree(rec); } static void data_write(void) { - if ( dbname ) { - strncpy(file_out->name, dbname, PDB_DBNAMELEN); - } - else { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - } - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE_POINTS; - file_out->creator = MYCREATOR; - file_out->version = 0; - - waypt_disp_all(gpspilot_writewpt); + if (dbname) { + strncpy(file_out->name, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE_POINTS; + file_out->creator = MYCREATOR; + file_out->version = 0; + + waypt_disp_all(gpspilot_writewpt); } ff_vecs_t gpspilot_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - gpspilot_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + gpspilot_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/gpssim.c b/gpsbabel/gpssim.c index 8a0d3e6b4..618463e7e 100644 --- a/gpsbabel/gpssim.c +++ b/gpsbabel/gpssim.c @@ -1,6 +1,6 @@ /* Write points to Franson Technology GpsGate simulator - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -18,61 +18,65 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #define MYNAME "gpssim" -static gbfile *fout; -static char *wayptspd; -static char *splitfiles_opt; +static gbfile* fout; +static char* wayptspd; +static char* splitfiles_opt; static int splitfiles; -static char *fnamestr; +static char* fnamestr; static int trk_count; static int doing_tracks; static arglist_t gpssim_args[] = { - { "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)", - NULL, ARGTYPE_FLOAT, ARG_NOMINMAX }, - { "split", &splitfiles_opt, "Split input into separate files", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "split", &splitfiles_opt, "Split input into separate files", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /* * The only thing kind of odd about this format is the "split" - * option. There's some trashing about with the 'splitfiles' toggle + * option. There's some trashing about with the 'splitfiles' toggle * to ensure that waypoints land in one file and each track and each * route land in files of their own. */ static void -gpssim_wr_init(const char *fname) +gpssim_wr_init(const char* fname) { - fnamestr = xstrdup(fname); - trk_count = 0; - splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0; - - /* If writing to stdout, never split files */ - if (0 == strcmp("-",splitfiles_opt)) { - splitfiles = 0; - } - - if (!splitfiles) { - fout = gbfopen(fname, "wb", MYNAME); - } + fnamestr = xstrdup(fname); + trk_count = 0; + splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0; + + /* If writing to stdout, never split files */ + if (0 == strcmp("-",splitfiles_opt)) { + splitfiles = 0; + } + + if (!splitfiles) { + fout = gbfopen(fname, "wb", MYNAME); + } } static void gpssim_wr_deinit(void) { - if (fout) { - gbfclose(fout); - fout = NULL; - } + if (fout) { + gbfclose(fout); + fout = NULL; + } - xfree(fnamestr); + xfree(fnamestr); } @@ -81,124 +85,124 @@ gpssim_wr_deinit(void) * in them explictly in case we're writing from a UNIX-like host. */ -static void -gpssim_write_sentence(const char *const s) +static void +gpssim_write_sentence(const char* const s) { - gbfprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s)); + gbfprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s)); } static void gpssim_write_spd(double knotsperhour) { - char obuf[1024]; + char obuf[1024]; - snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour); - gpssim_write_sentence(obuf); + snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour); + gpssim_write_sentence(obuf); } static void -gpssim_write_pt(const waypoint *wpt) +gpssim_write_pt(const waypoint* wpt) { - char obuf[1024]; - double lat, lon; - - if WAYPT_HAS(wpt, speed) { - gpssim_write_spd(MPS_TO_KNOTS(wpt->speed)); - } - - lat = degrees2ddmm(wpt->latitude); - lon = degrees2ddmm(wpt->longitude); - - snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f", - fabs(lat), lat < 0 ? 'S' : 'N', - fabs(lon), lon < 0 ? 'W' : 'E', - wpt->altitude == unknown_alt ? 0 : wpt->altitude - ); - - if ( wpt->creation_time ) { - char tbuf[20]; - int hms, ymd; - struct tm *tm; - - tm = gmtime(&wpt->creation_time); - hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; - ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; - snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms); - strcat(obuf, tbuf); - } - - gpssim_write_sentence(obuf); + char obuf[1024]; + double lat, lon; + + if WAYPT_HAS(wpt, speed) { + gpssim_write_spd(MPS_TO_KNOTS(wpt->speed)); + } + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + + snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f", + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + wpt->altitude == unknown_alt ? 0 : wpt->altitude + ); + + if (wpt->creation_time) { + char tbuf[20]; + int hms, ymd; + struct tm* tm; + + tm = gmtime(&wpt->creation_time); + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; + snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms); + strcat(obuf, tbuf); + } + + gpssim_write_sentence(obuf); } static void -gpssim_trk_hdr(const route_head *rh) +gpssim_trk_hdr(const route_head* rh) { - if (splitfiles) { - char c[1024]; - char *ofname = xstrdup(fnamestr); - - if (fout) { - fatal(MYNAME ": output file already open.\n"); - } - - snprintf(c, sizeof(c), "%s%04d.gpssim", - doing_tracks ? "-track" : "-route", - trk_count++); - ofname = xstrappend(ofname, c); - fout = gbfopen(ofname, "wb", MYNAME); - xfree(ofname); - } - track_recompute(rh, NULL); + if (splitfiles) { + char c[1024]; + char* ofname = xstrdup(fnamestr); + + if (fout) { + fatal(MYNAME ": output file already open.\n"); + } + + snprintf(c, sizeof(c), "%s%04d.gpssim", + doing_tracks ? "-track" : "-route", + trk_count++); + ofname = xstrappend(ofname, c); + fout = gbfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + track_recompute(rh, NULL); } static void -gpssim_trk_ftr(const route_head *rh) +gpssim_trk_ftr(const route_head* rh) { - if (splitfiles) { - gbfclose(fout); - fout = NULL; - } + if (splitfiles) { + gbfclose(fout); + fout = NULL; + } } static void gpssim_write(void) { - if (waypt_count()) { - if (splitfiles) { - char *ofname = xstrdup(fnamestr); - ofname = xstrappend(ofname, "-waypoints.gpssim"); - fout = gbfopen(ofname, "wb", MYNAME); - xfree(ofname); - } - if (wayptspd && wayptspd[0]) { - gpssim_write_spd(atof(wayptspd)); - } - waypt_disp_all(gpssim_write_pt); - if (splitfiles) { - gbfclose(fout); - fout = NULL; - } - } - - doing_tracks = 1; - track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); - - trk_count = 0; - doing_tracks = 0; - route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); + if (waypt_count()) { + if (splitfiles) { + char* ofname = xstrdup(fnamestr); + ofname = xstrappend(ofname, "-waypoints.gpssim"); + fout = gbfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + if (wayptspd && wayptspd[0]) { + gpssim_write_spd(atof(wayptspd)); + } + waypt_disp_all(gpssim_write_pt); + if (splitfiles) { + gbfclose(fout); + fout = NULL; + } + } + + doing_tracks = 1; + track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); + + trk_count = 0; + doing_tracks = 0; + route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); } ff_vecs_t gpssim_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_write, ff_cap_write }, - NULL, - gpssim_wr_init, - NULL, - gpssim_wr_deinit, - NULL, - gpssim_write, - NULL, - gpssim_args, - CET_CHARSET_ASCII, 0 + ff_type_file, + { ff_cap_write, ff_cap_write, ff_cap_write }, + NULL, + gpssim_wr_init, + NULL, + gpssim_wr_deinit, + NULL, + gpssim_write, + NULL, + gpssim_args, + CET_CHARSET_ASCII, 0 }; diff --git a/gpsbabel/gpsutil.c b/gpsbabel/gpsutil.c index 71e88dedc..0fae24e9b 100644 --- a/gpsbabel/gpsutil.c +++ b/gpsbabel/gpsutil.c @@ -21,155 +21,162 @@ #include "defs.h" #include "magellan.h" -static gbfile *file_in, *file_out; +static gbfile* file_in, *file_out; static short_handle mkshort_handle; #define MYNAME "GPSUTIL" static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = gbfopen(fname, "rb", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = gbfopen(fname, "w", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void data_read(void) { - char *ibuf; - char desc[31]; - double lat,lon; - char latdir, londir; - int ilat, ilon; - long alt; - char alttype; - char icon[3]; - waypoint *wpt_tmp; - int line = 0; - /* - * Make sure that all waypoints in single read have same - * timestamp. - */ - time_t now = current_time(); - icon[0] = 0; - - while ((ibuf = gbfgetstr(file_in))) { - int n, len; - char *sn; - - if ((line++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - /* A sharp in column zero or an blank line is a comment */ - ibuf = lrtrim(ibuf); - len = strlen(ibuf); - if ((len == 0) || (*ibuf == '#')) continue; - - if (len > 71) { - int offs = len - 71; - sn = xstrndup(ibuf, offs + 8); - ibuf += (offs + 9); - } - else { - sn = xstrndup(ibuf, 8); - ibuf += 9; - } - - n = sscanf(ibuf, "%lf%c %lf%c %ld%c %30[^,] %2s", - &lat, &latdir, &lon, &londir, - &alt, &alttype, desc, icon); - /* Require at least first threee fields, otherwise ignore */ - if (n < 2) { - xfree(sn); - continue; - } - rtrim(sn); - rtrim(desc); - rtrim(icon); - wpt_tmp = waypt_new(); - wpt_tmp->altitude = alt; - wpt_tmp->shortname = sn; - wpt_tmp->description = xstrdup(desc); - wpt_tmp->creation_time = now; - - if (latdir == 'S') lat = -lat; - if (londir == 'W') lon = -lon; - - lat /= 100.0; - lon /= 100.0; - ilon = (int)(lon); - wpt_tmp->longitude = ilon + (lon - ilon)*(100.0/60.0); - ilat = (int)(lat); - wpt_tmp->latitude = ilat + (lat - ilat) * (100.0/60.0); - wpt_tmp->icon_descr = mag_find_descr_from_token(icon); - waypt_add(wpt_tmp); - } + char* ibuf; + char desc[31]; + double lat,lon; + char latdir, londir; + int ilat, ilon; + long alt; + char alttype; + char icon[3]; + waypoint* wpt_tmp; + int line = 0; + /* + * Make sure that all waypoints in single read have same + * timestamp. + */ + time_t now = current_time(); + icon[0] = 0; + + while ((ibuf = gbfgetstr(file_in))) { + int n, len; + char* sn; + + if ((line++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + /* A sharp in column zero or an blank line is a comment */ + ibuf = lrtrim(ibuf); + len = strlen(ibuf); + if ((len == 0) || (*ibuf == '#')) { + continue; + } + + if (len > 71) { + int offs = len - 71; + sn = xstrndup(ibuf, offs + 8); + ibuf += (offs + 9); + } else { + sn = xstrndup(ibuf, 8); + ibuf += 9; + } + + n = sscanf(ibuf, "%lf%c %lf%c %ld%c %30[^,] %2s", + &lat, &latdir, &lon, &londir, + &alt, &alttype, desc, icon); + /* Require at least first threee fields, otherwise ignore */ + if (n < 2) { + xfree(sn); + continue; + } + rtrim(sn); + rtrim(desc); + rtrim(icon); + wpt_tmp = waypt_new(); + wpt_tmp->altitude = alt; + wpt_tmp->shortname = sn; + wpt_tmp->description = xstrdup(desc); + wpt_tmp->creation_time = now; + + if (latdir == 'S') { + lat = -lat; + } + if (londir == 'W') { + lon = -lon; + } + + lat /= 100.0; + lon /= 100.0; + ilon = (int)(lon); + wpt_tmp->longitude = ilon + (lon - ilon)*(100.0/60.0); + ilat = (int)(lat); + wpt_tmp->latitude = ilat + (lat - ilat) * (100.0/60.0); + wpt_tmp->icon_descr = mag_find_descr_from_token(icon); + waypt_add(wpt_tmp); + } } static void -gpsutil_disp(const waypoint *wpt) +gpsutil_disp(const waypoint* wpt) { - double lon,lat; - const char *icon_token; - char *tdesc = xstrdup(wpt->description); - - icon_token = mag_find_token_from_descr(wpt->icon_descr); - - lon = degrees2ddmm(wpt->longitude); - lat = degrees2ddmm(wpt->latitude); - - gbfprintf(file_out, "%-8.8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n", - global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, wpt) : - wpt->shortname, - fabs(lat), - lat < 0.0 ? 'S' : 'N', - fabs(lon), - lon < 0.0 ? 'W' : 'E', - ((wpt->altitude == unknown_alt) || - (wpt->altitude < 0.0)) ? 0 : wpt->altitude, - 'm', - wpt->description ? tdesc : "", - icon_token); - - xfree(tdesc); + double lon,lat; + const char* icon_token; + char* tdesc = xstrdup(wpt->description); + + icon_token = mag_find_token_from_descr(wpt->icon_descr); + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + gbfprintf(file_out, "%-8.8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n", + global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname, + fabs(lat), + lat < 0.0 ? 'S' : 'N', + fabs(lon), + lon < 0.0 ? 'W' : 'E', + ((wpt->altitude == unknown_alt) || + (wpt->altitude < 0.0)) ? 0 : wpt->altitude, + 'm', + wpt->description ? tdesc : "", + icon_token); + + xfree(tdesc); } static void data_write(void) { - waypt_disp_all(gpsutil_disp); + waypt_disp_all(gpsutil_disp); } ff_vecs_t gpsutil_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/gpx.c b/gpsbabel/gpx.c index be5e5479e..96f5963af 100644 --- a/gpsbabel/gpx.c +++ b/gpsbabel/gpx.c @@ -25,52 +25,52 @@ #include "cet_util.h" #include "garmin_fs.h" #if HAVE_LIBEXPAT - #include - static XML_Parser psr; +#include +static XML_Parser psr; #endif -static xml_tag *cur_tag; +static xml_tag* cur_tag; static vmem_t cdatastr; -static char *opt_logpoint = NULL; -static char *opt_humminbirdext = NULL; -static char *opt_garminext = NULL; +static char* opt_logpoint = NULL; +static char* opt_humminbirdext = NULL; +static char* opt_garminext = NULL; static int logpoint_ct = 0; -static const char *gpx_version; -static char *gpx_wversion; +static char* gpx_version = NULL; +static char* gpx_wversion; static int gpx_wversion_num; -static const char *gpx_creator; -static char *xsi_schema_loc = NULL; +static const char* gpx_creator; +static char* xsi_schema_loc = NULL; -static char *gpx_email = NULL; -static char *gpx_author = NULL; +static char* gpx_email = NULL; +static char* gpx_author = NULL; static vmem_t current_tag; -static waypoint *wpt_tmp; +static waypoint* wpt_tmp; static int cache_descr_is_html; -static gbfile *fd; -static const char *input_fname; -static gbfile *ofd; +static gbfile* fd; +static const char* input_fname; +static gbfile* ofd; static short_handle mkshort_handle; -static const char *link_url; -static char *link_text; +static const char* link_url; +static char* link_text; -static const char *input_string = NULL; +static const char* input_string = NULL; static int input_string_len = 0; static time_t file_time; -static char *snlen = NULL; -static char *suppresswhite = NULL; -static char *urlbase = NULL; -static route_head *trk_head; -static route_head *rte_head; -static const route_head *current_trk_head; // Output. +static char* snlen = NULL; +static char* suppresswhite = NULL; +static char* urlbase = NULL; +static route_head* trk_head; +static route_head* rte_head; +static const route_head* current_trk_head; // Output. /* used for bounds calculation on output */ static bounds all_bounds; static int next_trkpt_is_new_seg; -static format_specific_data **fs_ptr; +static format_specific_data** fs_ptr; #define MYNAME "GPX" #define MY_CBUF_SZ 4096 @@ -82,193 +82,196 @@ static format_specific_data **fs_ptr; #endif -/* +/* * Format used for floating point formats. Put in one place to make it - * easier to tweak when comparing output with other GPX programs that + * easier to tweak when comparing output with other GPX programs that * have more or less digits of output... */ /* #define FLT_FMT "%.9lf" */ /* ExpertGPS */ -#define FLT_FMT "%0.9lf" -#define FLT_FMT_T "%0.9lf" -#define FLT_FMT_R "%0.9lf" +#define FLT_FMT "%0.9lf" +#define FLT_FMT_T "%0.9lf" +#define FLT_FMT_R "%0.9lf" typedef enum { - tt_unknown = 0, - tt_gpx, - - tt_name, /* Optional file-level info */ - tt_desc, - tt_author, - tt_email, - tt_url, - tt_urlname, - tt_keywords, - - tt_wpt, - tt_wpt_cmt, - tt_wpt_desc, - tt_wpt_name, - tt_wpt_sym, - tt_wpt_url, - tt_wpt_ele, - tt_wpt_time, - tt_wpt_type, - tt_wpt_urlname, - tt_wpt_link, /* New in GPX 1.1 */ - tt_wpt_link_text, /* New in GPX 1.1 */ - tt_pdop, /* PDOPS are common for all three */ - tt_hdop, /* PDOPS are common for all three */ - tt_vdop, /* PDOPS are common for all three */ - tt_fix, - tt_sat, - tt_cache, - tt_cache_name, - tt_cache_container, - tt_cache_type, - tt_cache_difficulty, - tt_cache_terrain, - tt_cache_hint, - tt_cache_desc_short, - tt_cache_desc_long, - tt_cache_log_wpt, - tt_cache_log_type, - tt_cache_log_date, - tt_cache_placer, - - tt_wpt_extensions, - - tt_garmin_wpt_extensions, /* don't change this order */ - tt_garmin_wpt_proximity, - tt_garmin_wpt_temperature, - tt_garmin_wpt_depth, - tt_garmin_wpt_display_mode, - tt_garmin_wpt_categories, - tt_garmin_wpt_category, - tt_garmin_wpt_addr, - tt_garmin_wpt_city, - tt_garmin_wpt_state, - tt_garmin_wpt_country, - tt_garmin_wpt_postal_code, - tt_garmin_wpt_phone_nr, /* don't change this order */ - - tt_rte, - tt_rte_name, - tt_rte_desc, - tt_rte_cmt, - tt_rte_number, - tt_rte_rtept, - tt_rte_rtept_ele, - tt_rte_rtept_name, - tt_rte_rtept_desc, - tt_rte_rtept_sym, - tt_rte_rtept_time, - tt_rte_rtept_cmt, - tt_rte_rtept_url, - tt_rte_rtept_urlname, - tt_trk, - tt_trk_desc, - tt_trk_name, - tt_trk_trkseg, - tt_trk_number, - tt_trk_trkseg_trkpt, - tt_trk_trkseg_trkpt_cmt, - tt_trk_trkseg_trkpt_name, - tt_trk_trkseg_trkpt_sym, - tt_trk_trkseg_trkpt_url, - tt_trk_trkseg_trkpt_urlname, - tt_trk_trkseg_trkpt_desc, - tt_trk_trkseg_trkpt_ele, - tt_trk_trkseg_trkpt_time, - tt_trk_trkseg_trkpt_course, - tt_trk_trkseg_trkpt_speed, - tt_trk_trkseg_trkpt_heartrate, - tt_trk_trkseg_trkpt_cadence, - - tt_humminbird_wpt_depth, - tt_humminbird_wpt_status, - tt_humminbird_trk_trkseg_trkpt_depth, + tt_unknown = 0, + tt_gpx, + + tt_name, /* Optional file-level info */ + tt_desc, + tt_author, + tt_email, + tt_url, + tt_urlname, + tt_keywords, + + tt_wpt, + tt_wpt_cmt, + tt_wpt_desc, + tt_wpt_name, + tt_wpt_sym, + tt_wpt_url, + tt_wpt_ele, + tt_wpt_time, + tt_wpt_type, + tt_wpt_urlname, + tt_wpt_link, /* New in GPX 1.1 */ + tt_wpt_link_text, /* New in GPX 1.1 */ + tt_pdop, /* PDOPS are common for all three */ + tt_hdop, /* PDOPS are common for all three */ + tt_vdop, /* PDOPS are common for all three */ + tt_fix, + tt_sat, + tt_cache, + tt_cache_name, + tt_cache_container, + tt_cache_type, + tt_cache_difficulty, + tt_cache_terrain, + tt_cache_hint, + tt_cache_desc_short, + tt_cache_desc_long, + tt_cache_log_wpt, + tt_cache_log_type, + tt_cache_log_date, + tt_cache_placer, + tt_cache_favorite_points, + tt_cache_personal_note, + + tt_wpt_extensions, + + tt_garmin_wpt_extensions, /* don't change this order */ + tt_garmin_wpt_proximity, + tt_garmin_wpt_temperature, + tt_garmin_wpt_depth, + tt_garmin_wpt_display_mode, + tt_garmin_wpt_categories, + tt_garmin_wpt_category, + tt_garmin_wpt_addr, + tt_garmin_wpt_city, + tt_garmin_wpt_state, + tt_garmin_wpt_country, + tt_garmin_wpt_postal_code, + tt_garmin_wpt_phone_nr, /* don't change this order */ + + tt_rte, + tt_rte_name, + tt_rte_desc, + tt_rte_cmt, + tt_rte_number, + tt_rte_rtept, + tt_rte_rtept_ele, + tt_rte_rtept_name, + tt_rte_rtept_desc, + tt_rte_rtept_sym, + tt_rte_rtept_time, + tt_rte_rtept_cmt, + tt_rte_rtept_url, + tt_rte_rtept_urlname, + tt_trk, + tt_trk_desc, + tt_trk_name, + tt_trk_trkseg, + tt_trk_number, + tt_trk_trkseg_trkpt, + tt_trk_trkseg_trkpt_cmt, + tt_trk_trkseg_trkpt_name, + tt_trk_trkseg_trkpt_sym, + tt_trk_trkseg_trkpt_url, + tt_trk_trkseg_trkpt_urlname, + tt_trk_trkseg_trkpt_desc, + tt_trk_trkseg_trkpt_ele, + tt_trk_trkseg_trkpt_time, + tt_trk_trkseg_trkpt_course, + tt_trk_trkseg_trkpt_speed, + tt_trk_trkseg_trkpt_heartrate, + tt_trk_trkseg_trkpt_cadence, + + tt_humminbird_wpt_depth, + tt_humminbird_wpt_status, + tt_humminbird_trk_trkseg_trkpt_depth, } tag_type; typedef struct { - queue queue; - char *tagdata; + struct queue queue; + char* tagdata; } gpx_global_entry; /* * The file-level information. */ -static +static struct gpx_global { - gpx_global_entry name; - gpx_global_entry desc; - gpx_global_entry author; - gpx_global_entry email; - gpx_global_entry url; - gpx_global_entry urlname; - gpx_global_entry keywords; - /* time and bounds aren't here; they're recomputed. */ -} *gpx_global ; + gpx_global_entry name; + gpx_global_entry desc; + gpx_global_entry author; + gpx_global_entry email; + gpx_global_entry url; + gpx_global_entry urlname; + gpx_global_entry keywords; + /* time and bounds aren't here; they're recomputed. */ +}* gpx_global ; static void -gpx_add_to_global(gpx_global_entry *ge, char *cdata) +gpx_add_to_global(gpx_global_entry* ge, char* cdata) { - queue *elem, *tmp; - gpx_global_entry * gep; - - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gep = BASE_STRUCT(elem, gpx_global_entry, queue); - if (0 == strcmp(cdata, gep->tagdata)) - return; - } - - gep = xcalloc(sizeof(*gep), 1); - QUEUE_INIT(&gep->queue); - gep->tagdata = xstrdup(cdata); - ENQUEUE_TAIL(&ge->queue, &gep->queue); + queue* elem, *tmp; + gpx_global_entry* gep; + + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + if (0 == strcmp(cdata, gep->tagdata)) { + return; + } + } + + gep = (gpx_global_entry*) xcalloc(sizeof(*gep), 1); + QUEUE_INIT(&gep->queue); + gep->tagdata = xstrdup(cdata); + ENQUEUE_TAIL(&ge->queue, &gep->queue); } static void -gpx_rm_from_global(gpx_global_entry *ge) +gpx_rm_from_global(gpx_global_entry* ge) { - queue *elem, *tmp; + queue* elem, *tmp; - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gpx_global_entry *g = (gpx_global_entry *) dequeue(elem); - xfree(g->tagdata); - xfree(g); - } + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gpx_global_entry* g = (gpx_global_entry*) dequeue(elem); + xfree(g->tagdata); + xfree(g); + } } static void -gpx_write_gdata(gpx_global_entry *ge, const char *tag) +gpx_write_gdata(gpx_global_entry* ge, const char* tag) { - queue *elem, *tmp; - gpx_global_entry * gep; - - if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { - return; - } - - gbfprintf(ofd, "<%s>", tag); - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gep = BASE_STRUCT(elem, gpx_global_entry, queue); - gbfprintf(ofd, "%s", gep->tagdata); - /* Some tags we just output once. */ - if ((0 == strcmp(tag, "url")) || - (0 == strcmp(tag, "email"))) { - break; - } - gbfprintf(ofd, " "); - } - gbfprintf(ofd, "\n", tag); + queue* elem, *tmp; + gpx_global_entry* gep; + + if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { + return; + } + + gbfprintf(ofd, "<%s>", tag); + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + gbfprintf(ofd, "%s", gep->tagdata); + /* Some tags we just output once. */ + if ((0 == strcmp(tag, "url")) || + (0 == strcmp(tag, "email"))) { + break; + } + gbfprintf(ofd, " "); + } + gbfprintf(ofd, "\n", tag); } typedef struct tag_mapping { - tag_type tag_type; /* enum from above for this tag */ - int tag_passthrough; /* true if we don't generate this */ - const char *tag_name; /* xpath-ish tag name */ - unsigned long crc; /* Crc32 of tag_name */ + tag_type tag_type_; /* enum from above for this tag */ + int tag_passthrough; /* true if we don't generate this */ + const char* tag_name; /* xpath-ish tag name */ + unsigned long crc; /* Crc32 of tag_name */ } tag_mapping; /* @@ -278,29 +281,29 @@ typedef struct tag_mapping { */ tag_mapping tag_path_map[] = { - { tt_gpx, 0, "/gpx", 0UL }, - { tt_name, 0, "/gpx/name", 0UL }, - { tt_desc, 0, "/gpx/desc", 0UL }, - { tt_author, 0, "/gpx/author", 0UL }, - { tt_email, 0, "/gpx/email", 0UL }, - { tt_url, 0, "/gpx/url", 0UL }, - { tt_urlname, 0, "/gpx/urlname", 0UL }, - { tt_keywords, 0, "/gpx/keywords", 0UL }, - - { tt_wpt, 0, "/gpx/wpt", 0UL }, - { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, - { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, - { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, - { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, - { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, - { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, - { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, - { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ - { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ - { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, - { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, - - /* Double up the GPX 1.0 and GPX 1.1 styles */ + { tt_gpx, 0, "/gpx", 0UL }, + { tt_name, 0, "/gpx/name", 0UL }, + { tt_desc, 0, "/gpx/desc", 0UL }, + { tt_author, 0, "/gpx/author", 0UL }, + { tt_email, 0, "/gpx/email", 0UL }, + { tt_url, 0, "/gpx/url", 0UL }, + { tt_urlname, 0, "/gpx/urlname", 0UL }, + { tt_keywords, 0, "/gpx/keywords", 0UL }, + + { tt_wpt, 0, "/gpx/wpt", 0UL }, + { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, + { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, + { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, + { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, + { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, + { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, + { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, + { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ + { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ + { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, + { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, + + /* Double up the GPX 1.0 and GPX 1.1 styles */ #define GEOTAG(type,name) \ {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name, 0UL }, \ {type, 1, "/gpx/wpt/extensions/cache/" name, 0UL }, \ @@ -311,1248 +314,1267 @@ tag_mapping tag_path_map[] = { #define GARMIN_RTE_EXT "/gpx/rte/rtept/extensions/gpxxx:RoutePointExtension" // GEOTAG( tt_cache, "cache"), - { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, - - GEOTAG( tt_cache_name, "name"), - GEOTAG( tt_cache_container, "container"), - GEOTAG( tt_cache_type, "type"), - GEOTAG( tt_cache_difficulty, "difficulty"), - GEOTAG( tt_cache_terrain, "terrain"), - GEOTAG( tt_cache_hint, "encoded_hints"), - GEOTAG( tt_cache_hint, "hints"), /* opencaching.de */ - GEOTAG( tt_cache_desc_short, "short_description"), - GEOTAG( tt_cache_desc_long, "long_description"), - GEOTAG( tt_cache_placer, "owner"), - { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, - { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, - { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, - { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, - { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, - { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, - - { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, - - { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, - { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, - { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, - { tt_garmin_wpt_temperature, 0, GARMIN_TRK_EXT "/gpxtpx:atemp", 0UL }, - { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, - { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, - { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, - { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, - { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, - { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, - { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, - { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, - { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, - { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, - - // In Garmin space, but in core of waypoint. - { tt_trk_trkseg_trkpt_heartrate, 0, GARMIN_TRK_EXT "/gpxtpx:hr", 0UL }, - { tt_trk_trkseg_trkpt_cadence, 0, GARMIN_TRK_EXT "/gpxtpx:cad", 0UL }, - - { tt_humminbird_wpt_depth, 0, "/gpx/wpt/extensions/h:depth", 0UL }, // in centimeters. - { tt_humminbird_wpt_status, 0, "/gpx/wpt/extensions/h:status", 0UL }, - - { tt_rte, 0, "/gpx/rte", 0UL }, - { tt_rte_name, 0, "/gpx/rte/name", 0UL }, - { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, - { tt_rte_number, 0, "/gpx/rte/number", 0UL }, - { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, - { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, - { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, - { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, - { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, - { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, - { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, - { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, - { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, - - { tt_trk, 0, "/gpx/trk", 0UL }, - { tt_trk_name, 0, "/gpx/trk/name", 0UL }, - { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, - { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, - { tt_trk_number, 0, "/gpx/trk/number", 0UL }, - { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, - { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, - { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, - { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, - { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, - { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, - { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, - { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, - { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, - { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, - { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, - - { tt_humminbird_trk_trkseg_trkpt_depth, 0, "/gpx/trk/trkseg/trkpt/extensions/h:depth", 0UL }, // in centimeters. - - /* Common to tracks, routes, and waypts */ - { tt_fix, 0, "/gpx/wpt/fix", 0UL }, - { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, - { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, - { tt_sat, 0, "/gpx/wpt/sat", 0UL }, - { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, - { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, - { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, - { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, - { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, - { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, - { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, - { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, - { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, - { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, - { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, - {0, 0, NULL, 0UL} + { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, + + GEOTAG(tt_cache_name, "name"), + GEOTAG(tt_cache_container, "container"), + GEOTAG(tt_cache_type, "type"), + GEOTAG(tt_cache_difficulty, "difficulty"), + GEOTAG(tt_cache_terrain, "terrain"), + GEOTAG(tt_cache_hint, "encoded_hints"), + GEOTAG(tt_cache_hint, "hints"), /* opencaching.de */ + GEOTAG(tt_cache_desc_short, "short_description"), + GEOTAG(tt_cache_desc_long, "long_description"), + GEOTAG(tt_cache_placer, "owner"), + GEOTAG(tt_cache_favorite_points, "favorite_points"), + GEOTAG(tt_cache_personal_note, "personal_note"), + { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, + { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, + { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, + { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, + { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, + { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, + + { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, + + { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, + { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, + { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, + { tt_garmin_wpt_temperature, 0, GARMIN_TRK_EXT "/gpxtpx:atemp", 0UL }, + { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, + { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, + { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, + { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, + { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, + { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, + { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, + { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, + { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, + { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, + + // In Garmin space, but in core of waypoint. + { tt_trk_trkseg_trkpt_heartrate, 0, GARMIN_TRK_EXT "/gpxtpx:hr", 0UL }, + { tt_trk_trkseg_trkpt_cadence, 0, GARMIN_TRK_EXT "/gpxtpx:cad", 0UL }, + + { tt_humminbird_wpt_depth, 0, "/gpx/wpt/extensions/h:depth", 0UL }, // in centimeters. + { tt_humminbird_wpt_status, 0, "/gpx/wpt/extensions/h:status", 0UL }, + + { tt_rte, 0, "/gpx/rte", 0UL }, + { tt_rte_name, 0, "/gpx/rte/name", 0UL }, + { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, + { tt_rte_number, 0, "/gpx/rte/number", 0UL }, + { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, + { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, + { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, + { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, + { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, + { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, + { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, + { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, + { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, + + { tt_trk, 0, "/gpx/trk", 0UL }, + { tt_trk_name, 0, "/gpx/trk/name", 0UL }, + { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, + { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, + { tt_trk_number, 0, "/gpx/trk/number", 0UL }, + { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, + { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, + { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, + { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, + { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, + { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, + { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, + { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, + { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, + { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, + { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, + + { tt_humminbird_trk_trkseg_trkpt_depth, 0, "/gpx/trk/trkseg/trkpt/extensions/h:depth", 0UL }, // in centimeters. + + /* Common to tracks, routes, and waypts */ + { tt_fix, 0, "/gpx/wpt/fix", 0UL }, + { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, + { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, + { tt_sat, 0, "/gpx/wpt/sat", 0UL }, + { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, + { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, + { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, + { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + {(tag_type)0, 0, NULL, 0UL} }; static tag_type -get_tag(const char *t, int *passthrough) +get_tag(const char* t, int* passthrough) { - tag_mapping *tm; - unsigned long tcrc = get_crc32_s(t); - - for (tm = tag_path_map; tm->tag_type != 0; tm++) { - if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { - *passthrough = tm->tag_passthrough; - return tm->tag_type; - } - } - *passthrough = 1; - return tt_unknown; + tag_mapping* tm; + unsigned long tcrc = get_crc32_s(t); + + for (tm = tag_path_map; tm->tag_type_ != 0; tm++) { + if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { + *passthrough = tm->tag_passthrough; + return tm->tag_type_; + } + } + *passthrough = 1; + return tt_unknown; } static void prescan_tags(void) { - tag_mapping *tm; - for (tm = tag_path_map; tm->tag_type != 0; tm++) { - tm->crc = get_crc32_s(tm->tag_name); - } + tag_mapping* tm; + for (tm = tag_path_map; tm->tag_type_ != 0; tm++) { + tm->crc = get_crc32_s(tm->tag_name); + } } static void -tag_gpx(const char **attrv) +tag_gpx(const char** attrv) { - const char **avp; - for (avp = &attrv[0]; *avp; avp += 2) { - if (strcmp(avp[0], "version") == 0) { - gpx_version = avp[1]; - } - else if (strcmp(avp[0], "src") == 0) { - gpx_creator = avp[1]; - } - /* - * Our handling of schemaLocation really is weird. - * If we see we have a "normal" GPX 1.1 header, on read, - * flip our default on write to use that and don't append - * it to the rest... - */ - else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { - if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { - if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) { - xfree(xsi_schema_loc); - xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); - } - continue; - } - if (0 == strstr(xsi_schema_loc, avp[1])) { - xsi_schema_loc = xstrappend(xsi_schema_loc, " "); - xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); - } - } - } + const char** avp; + for (avp = &attrv[0]; *avp; avp += 2) { + if (strcmp(avp[0], "version") == 0) { + /* Set the default output version to the highest input + * version. + */ + if (! gpx_version) { + gpx_version = xstrdup(avp[1]); + } else if ((strtod(gpx_version, NULL) * 10) < (strtod(avp[1], NULL) * 10)) { + xfree(gpx_version); + gpx_version = xstrdup(avp[1]); + } + } else if (strcmp(avp[0], "src") == 0) { + gpx_creator = avp[1]; + } + /* + * Our handling of schemaLocation really is weird. + * If we see we have a "normal" GPX 1.1 header, on read, + * flip our default on write to use that and don't append + * it to the rest... + */ + else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { + if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { + if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) { + xfree(xsi_schema_loc); + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); + } + continue; + } + if (0 == strstr(xsi_schema_loc, avp[1])) { + xsi_schema_loc = xstrappend(xsi_schema_loc, " "); + xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); + } + } + } } static void -tag_wpt(const char **attrv) +tag_wpt(const char** attrv) { - const char **avp = &attrv[0]; - - wpt_tmp = waypt_new(); - - cur_tag = NULL; - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->longitude); - } - avp+=2; - } - fs_ptr = &wpt_tmp->fs; + const char** avp = &attrv[0]; + + wpt_tmp = waypt_new(); + + cur_tag = NULL; + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->longitude); + } + avp+=2; + } + fs_ptr = &wpt_tmp->fs; } static void -tag_cache_desc(const char ** attrv) +tag_cache_desc(const char** attrv) { - const char **avp; - - cache_descr_is_html = 0; - for (avp = &attrv[0]; *avp; avp+=2) { - if (strcmp(avp[0], "html") == 0) { - if (strcmp(avp[1], "True") == 0) { - cache_descr_is_html = 1; - } - } - } + const char** avp; + + cache_descr_is_html = 0; + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "html") == 0) { + if (strcmp(avp[1], "True") == 0) { + cache_descr_is_html = 1; + } + } + } } static void -tag_gs_cache(const char **attrv) +tag_gs_cache(const char** attrv) { - const char **avp; - geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); - - for (avp = &attrv[0]; *avp; avp+=2) { - if (strcmp(avp[0], "id") == 0) { - gc_data->id = atoi(avp[1]); - } else if (strcmp(avp[0], "available") == 0) { - if (case_ignore_strcmp(avp[1], "True") == 0) { - gc_data->is_available = status_true; - } - else if (case_ignore_strcmp(avp[1], "False") == 0) { - gc_data->is_available = status_false; - } - } else if (strcmp(avp[0], "archived") == 0) { - if (case_ignore_strcmp(avp[1], "True") == 0) { - gc_data->is_archived = status_true; - } - else if (case_ignore_strcmp(avp[1], "False") == 0) { - gc_data->is_archived = status_false; - } - } - } + const char** avp; + geocache_data* gc_data = waypt_alloc_gc_data(wpt_tmp); + + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "id") == 0) { + gc_data->id = atoi(avp[1]); + } else if (strcmp(avp[0], "available") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + gc_data->is_available = status_true; + } else if (case_ignore_strcmp(avp[1], "False") == 0) { + gc_data->is_available = status_false; + } + } else if (strcmp(avp[0], "archived") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + gc_data->is_archived = status_true; + } else if (case_ignore_strcmp(avp[1], "False") == 0) { + gc_data->is_archived = status_false; + } + } + } } static void -start_something_else(const char *el, const char **attrv) +start_something_else(const char* el, const char** attrv) { - const char **avp = attrv; - char **avcp = NULL; - int attr_count = 0; - xml_tag *new_tag; - fs_xml *fs_gpx; - - if ( !fs_ptr ) { - return; - } - - new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); - new_tag->tagname = xstrdup(el); - - /* count attributes */ - while (*avp) { - attr_count++; - avp++; - } - - /* copy attributes */ - avp = attrv; - new_tag->attributes = (char **)xcalloc(sizeof(char *),attr_count+1); - avcp = new_tag->attributes; - while (*avp) { - *avcp = xstrdup(*avp); - avcp++; - avp++; - } - *avcp = NULL; - - if ( cur_tag ) { - if ( cur_tag->child ) { - cur_tag = cur_tag->child; - while ( cur_tag->sibling ) { - cur_tag = cur_tag->sibling; - } - cur_tag->sibling = new_tag; - new_tag->parent = cur_tag->parent; - } - else { - cur_tag->child = new_tag; - new_tag->parent = cur_tag; - } - } - else { - fs_gpx = (fs_xml *)fs_chain_find( *fs_ptr, FS_GPX ); - - if ( fs_gpx && fs_gpx->tag ) { - cur_tag = fs_gpx->tag; - while ( cur_tag->sibling ) { - cur_tag = cur_tag->sibling; - } - cur_tag->sibling = new_tag; - new_tag->parent = NULL; - } - else { - fs_gpx = fs_xml_alloc(FS_GPX); - fs_gpx->tag = new_tag; - fs_chain_add( fs_ptr, (format_specific_data *)fs_gpx ); - new_tag->parent = NULL; - } - } - cur_tag = new_tag; + const char** avp = attrv; + char** avcp = NULL; + int attr_count = 0; + xml_tag* new_tag; + fs_xml* fs_gpx; + + if (!fs_ptr) { + return; + } + + new_tag = (xml_tag*)xcalloc(sizeof(xml_tag),1); + new_tag->tagname = xstrdup(el); + + /* count attributes */ + while (*avp) { + attr_count++; + avp++; + } + + /* copy attributes */ + avp = attrv; + new_tag->attributes = (char**)xcalloc(sizeof(char*),attr_count+1); + avcp = new_tag->attributes; + while (*avp) { + *avcp = xstrdup(*avp); + avcp++; + avp++; + } + *avcp = NULL; + + if (cur_tag) { + if (cur_tag->child) { + cur_tag = cur_tag->child; + while (cur_tag->sibling) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = cur_tag->parent; + } else { + cur_tag->child = new_tag; + new_tag->parent = cur_tag; + } + } else { + fs_gpx = (fs_xml*)fs_chain_find(*fs_ptr, FS_GPX); + + if (fs_gpx && fs_gpx->tag) { + cur_tag = fs_gpx->tag; + while (cur_tag->sibling) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = NULL; + } else { + fs_gpx = fs_xml_alloc(FS_GPX); + fs_gpx->tag = new_tag; + fs_chain_add(fs_ptr, (format_specific_data*)fs_gpx); + new_tag->parent = NULL; + } + } + cur_tag = new_tag; } static void end_something_else() { - if ( cur_tag ) { - cur_tag = cur_tag->parent; - } + if (cur_tag) { + cur_tag = cur_tag->parent; + } } static void -tag_log_wpt(const char **attrv) +tag_log_wpt(const char** attrv) { - waypoint * lwp_tmp; - const char **avp = &attrv[0]; - - /* create a new waypoint */ - lwp_tmp = waypt_new(); - - /* extract the lat/lon attributes */ - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &lwp_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &lwp_tmp->longitude); - } - avp+=2; - } - /* Make a new shortname. Since this is a groundspeak extension, - we assume that GCBLAH is the current shortname format and that - wpt_tmp refers to the currently parsed waypoint. Unfortunatley, - we need to keep track of log_wpt counts so we don't collide with - dupe shortnames. - */ - - if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { - /* copy of the shortname */ - lwp_tmp->shortname = xcalloc(7, 1); - sprintf(lwp_tmp->shortname, "%-4.4s%02d", - &wpt_tmp->shortname[2], logpoint_ct++); - - waypt_add(lwp_tmp); - } + waypoint* lwp_tmp; + const char** avp = &attrv[0]; + + /* create a new waypoint */ + lwp_tmp = waypt_new(); + + /* extract the lat/lon attributes */ + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->longitude); + } + avp+=2; + } + /* Make a new shortname. Since this is a groundspeak extension, + we assume that GCBLAH is the current shortname format and that + wpt_tmp refers to the currently parsed waypoint. Unfortunatley, + we need to keep track of log_wpt counts so we don't collide with + dupe shortnames. + */ + + if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { + /* copy of the shortname */ + lwp_tmp->shortname = (char*) xcalloc(7, 1); + sprintf(lwp_tmp->shortname, "%-4.4s%02d", + &wpt_tmp->shortname[2], logpoint_ct++); + + waypt_add(lwp_tmp); + } } static void -gpx_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) +gpx_start(void* data, const XML_Char* xml_el, const XML_Char** xml_attr) { - char *e; - char *ep; - int passthrough; - int tag; - const char *el = xml_convert_to_char_string(xml_el); - const char **attr = xml_convert_attrs_to_char_string(xml_attr); - - vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); - e = current_tag.mem; - ep = e + strlen(e); - *ep++ = '/'; - strcpy(ep, el); - - - /* - * Reset end-of-string without actually emptying/reallocing cdatastr. - */ - *(char *) cdatastr.mem = 0; - - tag = get_tag(current_tag.mem, &passthrough); - switch (tag) { - case tt_gpx: - tag_gpx(attr); - break; - case tt_wpt: - tag_wpt(attr); - break; - case tt_wpt_link: - if (0 == strcmp(attr[0], "href")) { - link_url = attr[1]; - } - break; - case tt_wpt_link_text: - link_text = cdatastr.mem; - break; - case tt_rte: - rte_head = route_head_alloc(); - route_add_head(rte_head); - fs_ptr = &rte_head->fs; - break; - case tt_rte_rtept: - tag_wpt(attr); - break; - case tt_trk: - trk_head = route_head_alloc(); - track_add_head(trk_head); - fs_ptr = &trk_head->fs; - break; - case tt_trk_trkseg_trkpt: - tag_wpt(attr); - if (next_trkpt_is_new_seg) { - wpt_tmp->wpt_flags.new_trkseg = 1; - next_trkpt_is_new_seg = 0; - } - break; - case tt_unknown: - start_something_else(el, attr); - return; - case tt_cache: - tag_gs_cache(attr); - break; - case tt_cache_log_wpt: - if (opt_logpoint) - tag_log_wpt(attr); - break; - case tt_cache_desc_long: - case tt_cache_desc_short: - tag_cache_desc(attr); - break; - case tt_cache_placer: - if (*attr && (0 == strcmp(attr[0], "id"))) { - waypt_alloc_gc_data(wpt_tmp)->placer_id = atoi(attr[1]); - } - default: - break; - } - if (passthrough) { - start_something_else(el, attr); - } - xml_free_converted_string(el); - xml_free_converted_attrs(attr); + char* e; + char* ep; + int passthrough; + int tag; + const char* el = xml_convert_to_char_string(xml_el); + const char** attr = xml_convert_attrs_to_char_string(xml_attr); + + vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); + e = current_tag.mem; + ep = e + strlen(e); + *ep++ = '/'; + strcpy(ep, el); + + + /* + * Reset end-of-string without actually emptying/reallocing cdatastr. + */ + *(char*) cdatastr.mem = 0; + + tag = get_tag(current_tag.mem, &passthrough); + switch (tag) { + case tt_gpx: + tag_gpx(attr); + break; + case tt_wpt: + tag_wpt(attr); + break; + case tt_wpt_link: + if (attr[0] && attr[1] && 0 == strcmp(attr[0], "href")) { + link_url = attr[1]; + } + break; + case tt_wpt_link_text: + link_text = cdatastr.mem; + break; + case tt_rte: + rte_head = route_head_alloc(); + route_add_head(rte_head); + fs_ptr = &rte_head->fs; + break; + case tt_rte_rtept: + tag_wpt(attr); + break; + case tt_trk: + trk_head = route_head_alloc(); + track_add_head(trk_head); + fs_ptr = &trk_head->fs; + break; + case tt_trk_trkseg_trkpt: + tag_wpt(attr); + if (next_trkpt_is_new_seg) { + wpt_tmp->wpt_flags.new_trkseg = 1; + next_trkpt_is_new_seg = 0; + } + break; + case tt_unknown: + start_something_else(el, attr); + return; + case tt_cache: + tag_gs_cache(attr); + break; + case tt_cache_log_wpt: + if (opt_logpoint) { + tag_log_wpt(attr); + } + break; + case tt_cache_desc_long: + case tt_cache_desc_short: + tag_cache_desc(attr); + break; + case tt_cache_placer: + if (*attr && (0 == strcmp(attr[0], "id"))) { + waypt_alloc_gc_data(wpt_tmp)->placer_id = atoi(attr[1]); + } + default: + break; + } + if (passthrough) { + start_something_else(el, attr); + } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); } struct -gs_type_mapping{ - geocache_type type; - const char *name; + gs_type_mapping { + geocache_type type; + const char* name; } gs_type_map[] = { - { gt_traditional, "Traditional Cache" }, - { gt_traditional, "Traditional" }, /* opencaching.de */ - { gt_multi, "Multi-cache" }, - { gt_multi, "Multi" }, /* opencaching.de */ - { gt_virtual, "Virtual Cache" }, - { gt_virtual, "Virtual" }, /* opencaching.de */ - { gt_event, "Event Cache" }, - { gt_event, "Event" }, /* opencaching.de */ - { gt_webcam, "Webcam Cache" }, - { gt_webcam, "Webcam" }, /* opencaching.de */ - { gt_suprise, "Unknown Cache" }, - { gt_earth, "Earthcache" }, - { gt_earth, "Earth" }, /* opencaching.de */ - { gt_cito, "Cache In Trash Out Event" }, - { gt_letterbox, "Letterbox Hybrid" }, - { gt_locationless, "Locationless (Reverse) Cache" }, - { gt_ape, "Project APE Cache" }, - { gt_mega, "Mega-Event Cache" }, - { gt_wherigo, "Wherigo Cache" }, - - { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ + { gt_traditional, "Traditional Cache" }, + { gt_traditional, "Traditional" }, /* opencaching.de */ + { gt_multi, "Multi-cache" }, + { gt_multi, "Multi" }, /* opencaching.de */ + { gt_virtual, "Virtual Cache" }, + { gt_virtual, "Virtual" }, /* opencaching.de */ + { gt_event, "Event Cache" }, + { gt_event, "Event" }, /* opencaching.de */ + { gt_webcam, "Webcam Cache" }, + { gt_webcam, "Webcam" }, /* opencaching.de */ + { gt_suprise, "Unknown Cache" }, + { gt_earth, "Earthcache" }, + { gt_earth, "Earth" }, /* opencaching.de */ + { gt_cito, "Cache In Trash Out Event" }, + { gt_letterbox, "Letterbox Hybrid" }, + { gt_locationless, "Locationless (Reverse) Cache" }, + { gt_ape, "Project APE Cache" }, + { gt_mega, "Mega-Event Cache" }, + { gt_wherigo, "Wherigo Cache" }, + + { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ }; struct -gs_container_mapping{ - geocache_container type; - const char *name; + gs_container_mapping { + geocache_container type; + const char* name; } gs_container_map[] = { - { gc_other, "Unknown" }, - { gc_other, "Other" }, /* Synonym on read. */ - { gc_micro, "Micro" }, - { gc_regular, "Regular" }, - { gc_large, "Large" }, - { gc_small, "Small" }, - { gc_virtual, "Virtual" } + { gc_other, "Unknown" }, + { gc_other, "Other" }, /* Synonym on read. */ + { gc_micro, "Micro" }, + { gc_regular, "Regular" }, + { gc_large, "Large" }, + { gc_small, "Small" }, + { gc_virtual, "Virtual" } }; geocache_type -gs_mktype(const char *t) +gs_mktype(const char* t) { - int i; - int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { - return gs_type_map[i].type; - } - } - return gt_unknown; + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { + return gs_type_map[i].type; + } + } + return gt_unknown; } -const char * +const char* gs_get_cachetype(geocache_type t) { - int i; - int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); - - for (i = 0; i < sz; i++) { - if (t == gs_type_map[i].type) { - return gs_type_map[i].name; - } - } - return "Unknown"; + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_type_map[i].type) { + return gs_type_map[i].name; + } + } + return "Unknown"; } geocache_container -gs_mkcont(const char *t) +gs_mkcont(const char* t) { - int i; - int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { - return gs_container_map[i].type; - } - } - return gc_unknown; + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { + return gs_container_map[i].type; + } + } + return gc_unknown; } -const char * +const char* gs_get_container(geocache_container t) { - int i; - int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); - - for (i = 0; i < sz; i++) { - if (t == gs_container_map[i].type) { - return gs_container_map[i].name; - } - } - return "Unknown"; + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_container_map[i].type) { + return gs_container_map[i].name; + } + } + return "Unknown"; } -time_t -xml_parse_time( const char *cdatastr, int *microsecs ) +time_t +xml_parse_time(const char* cdatastr, int* microsecs) { - int off_hr = 0; - int off_min = 0; - int off_sign = 1; - char *offsetstr = NULL; - char *pointstr = NULL; - struct tm tm; - time_t rv = 0; - char *timestr = xstrdup( cdatastr ); - - memset(&tm, 0, sizeof(tm)); - - offsetstr = strchr( timestr, 'Z' ); - if ( offsetstr ) { - /* zulu time; offsets stay at defaults */ - *offsetstr = '\0'; - } else { - offsetstr = strchr( timestr, '+' ); - if ( offsetstr ) { - /* positive offset; parse it */ - *offsetstr = '\0'; - sscanf( offsetstr+1, "%d:%d", &off_hr, &off_min ); - } else { - offsetstr = strchr( timestr, 'T' ); - if ( offsetstr ) { - offsetstr = strchr( offsetstr, '-' ); - if ( offsetstr ) { - /* negative offset; parse it */ - *offsetstr = '\0'; - sscanf( offsetstr+1, "%d:%d", - &off_hr, &off_min ); - off_sign = -1; - } - } - } - } - - pointstr = strchr( timestr, '.' ); - if ( pointstr ) { - if (microsecs) { - double fsec; - sscanf(pointstr, "%le", &fsec); - /* Round to avoid FP jitter */ - *microsecs = .5 + (fsec * 1000000.0) ; - } - *pointstr = '\0'; - } - - sscanf(timestr, "%d-%d-%dT%d:%d:%d", - &tm.tm_year, - &tm.tm_mon, - &tm.tm_mday, - &tm.tm_hour, - &tm.tm_min, - &tm.tm_sec); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; - - rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; - - xfree(timestr); - - return rv; + int off_hr = 0; + int off_min = 0; + int off_sign = 1; + char* offsetstr = NULL; + char* pointstr = NULL; + struct tm tm; + time_t rv = 0; + char* timestr = xstrdup(cdatastr); + + memset(&tm, 0, sizeof(tm)); + + offsetstr = strchr(timestr, 'Z'); + if (offsetstr) { + /* zulu time; offsets stay at defaults */ + *offsetstr = '\0'; + } else { + offsetstr = strchr(timestr, '+'); + if (offsetstr) { + /* positive offset; parse it */ + *offsetstr = '\0'; + sscanf(offsetstr+1, "%d:%d", &off_hr, &off_min); + } else { + offsetstr = strchr(timestr, 'T'); + if (offsetstr) { + offsetstr = strchr(offsetstr, '-'); + if (offsetstr) { + /* negative offset; parse it */ + *offsetstr = '\0'; + sscanf(offsetstr+1, "%d:%d", + &off_hr, &off_min); + off_sign = -1; + } + } + } + } + + pointstr = strchr(timestr, '.'); + if (pointstr) { + if (microsecs) { + double fsec; + sscanf(pointstr, "%le", &fsec); + /* Round to avoid FP jitter */ + *microsecs = .5 + (fsec * 1000000.0) ; + } + *pointstr = '\0'; + } + + sscanf(timestr, "%d-%d-%dT%d:%d:%d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday, + &tm.tm_hour, + &tm.tm_min, + &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + + rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; + + xfree(timestr); + + return rv; } static void -gpx_end(void *data, const XML_Char *xml_el) +gpx_end(void* data, const XML_Char* xml_el) { - const char *el = xml_convert_to_char_string(xml_el); - char *s = strrchr(current_tag.mem, '/'); - float x; - char *cdatastrp = cdatastr.mem; - int passthrough; - static time_t gc_log_date; - tag_type tag; - - if (strcmp(s + 1, el)) { - fprintf(stderr, "Mismatched tag %s\n", el); - } - - tag = get_tag(current_tag.mem, &passthrough); - switch(tag) { - /* - * First, the tags that are file-global. - */ - case tt_name: - gpx_add_to_global(&gpx_global->name, cdatastrp); - break; - case tt_desc: - gpx_add_to_global(&gpx_global->desc, cdatastrp); - break; - case tt_author: - gpx_add_to_global(&gpx_global->author, cdatastrp); - break; - case tt_email: - gpx_add_to_global(&gpx_global->email, cdatastrp); - if (gpx_email == NULL) { - gpx_email = xstrdup(cdatastrp); - } - break; - case tt_url: - gpx_add_to_global(&gpx_global->url, cdatastrp); - break; - case tt_urlname: - gpx_add_to_global(&gpx_global->urlname, cdatastrp); - break; - case tt_keywords: - gpx_add_to_global(&gpx_global->keywords, cdatastrp); - break; - - /* - * Waypoint-specific tags. - */ - case tt_wpt: - waypt_add(wpt_tmp); - logpoint_ct = 0; - cur_tag = NULL; - wpt_tmp = NULL; - break; - case tt_cache_name: - if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); - wpt_tmp->notes = xstrdup(cdatastrp); - break; - case tt_cache_container: - waypt_alloc_gc_data(wpt_tmp)->container = gs_mkcont(cdatastrp); - break; - case tt_cache_type: - waypt_alloc_gc_data(wpt_tmp)->type = gs_mktype(cdatastrp); - break; - case tt_cache_difficulty: - sscanf(cdatastrp, "%f", &x); - waypt_alloc_gc_data(wpt_tmp)->diff = x * 10; - break; - case tt_cache_hint: - rtrim(cdatastrp); - if (cdatastrp[0]) { - waypt_alloc_gc_data(wpt_tmp)->hint = xstrdup(cdatastrp); - } - break; - case tt_cache_desc_long: - rtrim(cdatastrp); - if (cdatastrp[0]) { - geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); - gc_data->desc_long.is_html = cache_descr_is_html; - gc_data->desc_long.utfstring = xstrdup(cdatastrp); - } - break; - case tt_cache_desc_short: - rtrim(cdatastrp); - if (cdatastrp[0]) { - geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); - gc_data->desc_short.is_html = cache_descr_is_html; - gc_data->desc_short.utfstring = xstrdup(cdatastrp); - } - break; - case tt_cache_terrain: - sscanf(cdatastrp, "%f", &x); - waypt_alloc_gc_data(wpt_tmp)->terr = x * 10; - break; - case tt_cache_placer: - waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(cdatastrp); - break; - case tt_cache_log_date: - gc_log_date = xml_parse_time( cdatastrp, NULL ); - break; - /* - * "Found it" logs follow the date according to the schema, - * if this is the first "found it" for this waypt, just use the - * last date we saw in this log. - */ - case tt_cache_log_type: - if ((0 == strcmp(cdatastrp, "Found it")) && - (0 == wpt_tmp->gc_data->last_found)) { - waypt_alloc_gc_data(wpt_tmp)->last_found = gc_log_date; - } - gc_log_date = 0; - break; - - /* - * Garmin-waypoint-specific tags. - */ - case tt_garmin_wpt_proximity: - case tt_garmin_wpt_temperature: - case tt_garmin_wpt_depth: - case tt_garmin_wpt_display_mode: - case tt_garmin_wpt_category: - case tt_garmin_wpt_addr: - case tt_garmin_wpt_city: - case tt_garmin_wpt_state: - case tt_garmin_wpt_country: - case tt_garmin_wpt_postal_code: - case tt_garmin_wpt_phone_nr: - garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); - break; - - /* - * Humminbird-waypoint-specific tags. - */ - case tt_humminbird_wpt_depth: - case tt_humminbird_trk_trkseg_trkpt_depth: - WAYPT_SET(wpt_tmp, depth, atof(cdatastrp) / 100.0) - break; - /* - * Route-specific tags. - */ - case tt_rte_name: - rte_head->rte_name = xstrdup(cdatastrp); - break; - case tt_rte: - break; - case tt_rte_rtept: - route_add_wpt(rte_head, wpt_tmp); - wpt_tmp = NULL; - break; - case tt_rte_desc: - rte_head->rte_desc = xstrdup(cdatastrp); - break; - case tt_rte_number: - rte_head->rte_num = atoi(cdatastrp); - break; - /* - * Track-specific tags. - */ - case tt_trk_name: - trk_head->rte_name = xstrdup(cdatastrp); - break; - case tt_trk: - break; - case tt_trk_trkseg: - next_trkpt_is_new_seg = 1; - break; - case tt_trk_trkseg_trkpt: - track_add_wpt(trk_head, wpt_tmp); - wpt_tmp = NULL; - break; - case tt_trk_desc: - trk_head->rte_desc = xstrdup(cdatastrp); - break; - case tt_trk_number: - trk_head->rte_num = atoi(cdatastrp); - break; - case tt_trk_trkseg_trkpt_course: - WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); - break; - case tt_trk_trkseg_trkpt_speed: - WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); - break; - case tt_trk_trkseg_trkpt_heartrate: - wpt_tmp->heartrate = atof(cdatastrp); - break; - case tt_trk_trkseg_trkpt_cadence: - wpt_tmp->cadence = atof(cdatastrp); - break; - - /* - * Items that are actually in multiple categories. - */ - case tt_wpt_ele: - case tt_rte_rtept_ele: - case tt_trk_trkseg_trkpt_ele: - sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); - break; - case tt_wpt_name: - case tt_rte_rtept_name: - case tt_trk_trkseg_trkpt_name: - wpt_tmp->shortname = xstrdup(cdatastrp); - break; - case tt_wpt_sym: - case tt_rte_rtept_sym: - case tt_trk_trkseg_trkpt_sym: - wpt_tmp->icon_descr = xstrdup(cdatastrp); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - break; - case tt_wpt_time: - case tt_trk_trkseg_trkpt_time: - case tt_rte_rtept_time: - wpt_tmp->creation_time = xml_parse_time( cdatastrp, &wpt_tmp->microseconds ); - break; - case tt_wpt_cmt: - case tt_rte_rtept_cmt: - case tt_trk_trkseg_trkpt_cmt: - wpt_tmp->description = xstrdup(cdatastrp); - break; - case tt_wpt_desc: - case tt_trk_trkseg_trkpt_desc: - case tt_rte_rtept_desc: - if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); - wpt_tmp->notes = xstrdup(cdatastrp); - break; - case tt_pdop: - wpt_tmp->pdop = atof(cdatastrp); - break; - case tt_hdop: - wpt_tmp->hdop = atof(cdatastrp); - break; - case tt_vdop: - wpt_tmp->vdop = atof(cdatastrp); - break; - case tt_sat: - wpt_tmp->sat = atof(cdatastrp); - break; - case tt_fix: - wpt_tmp->fix = atoi(cdatastrp)-1; - if ( wpt_tmp->fix < fix_2d) { - if (!case_ignore_strcmp(cdatastrp, "none")) - wpt_tmp->fix = fix_none; - else if (!case_ignore_strcmp(cdatastrp, "dgps")) - wpt_tmp->fix = fix_dgps; - else if (!case_ignore_strcmp(cdatastrp, "pps")) - wpt_tmp->fix = fix_pps; - else - wpt_tmp->fix = fix_unknown; - } - break; - case tt_wpt_url: - case tt_trk_trkseg_trkpt_url: - case tt_rte_rtept_url: - wpt_tmp->url = xstrdup(cdatastrp); - break; - case tt_wpt_urlname: - case tt_trk_trkseg_trkpt_urlname: - case tt_rte_rtept_urlname: - wpt_tmp->url_link_text = xstrdup(cdatastrp); - break; - case tt_wpt_link: -//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: -//TODO: implement GPX 1.1 case tt_rte_rtept_link: - { - char *lt = link_text; - if (lt) { - lt = xstrdup(lrtrim(link_text)); - } - - waypt_add_url(wpt_tmp, xstrdup(link_url), lt); - link_text = NULL; - } - break; - case tt_unknown: - end_something_else(); - *s = 0; - return; - default: - break; - } - - if (passthrough) { - end_something_else(); - } - - *s = 0; - xml_free_converted_string(el); + const char* el = xml_convert_to_char_string(xml_el); + char* s = strrchr(current_tag.mem, '/'); + float x; + char* cdatastrp = cdatastr.mem; + int passthrough; + static time_t gc_log_date; + tag_type tag; + + if (strcmp(s + 1, el)) { + fprintf(stderr, "Mismatched tag %s\n", el); + } + + tag = get_tag(current_tag.mem, &passthrough); + switch (tag) { + /* + * First, the tags that are file-global. + */ + case tt_name: + gpx_add_to_global(&gpx_global->name, cdatastrp); + break; + case tt_desc: + gpx_add_to_global(&gpx_global->desc, cdatastrp); + break; + case tt_author: + gpx_add_to_global(&gpx_global->author, cdatastrp); + break; + case tt_email: + gpx_add_to_global(&gpx_global->email, cdatastrp); + if (gpx_email == NULL) { + gpx_email = xstrdup(cdatastrp); + } + break; + case tt_url: + gpx_add_to_global(&gpx_global->url, cdatastrp); + break; + case tt_urlname: + gpx_add_to_global(&gpx_global->urlname, cdatastrp); + break; + case tt_keywords: + gpx_add_to_global(&gpx_global->keywords, cdatastrp); + break; + + /* + * Waypoint-specific tags. + */ + case tt_wpt: + waypt_add(wpt_tmp); + logpoint_ct = 0; + cur_tag = NULL; + wpt_tmp = NULL; + break; + case tt_cache_name: + if (wpt_tmp->notes != NULL) { + xfree(wpt_tmp->notes); + } + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_cache_container: + waypt_alloc_gc_data(wpt_tmp)->container = gs_mkcont(cdatastrp); + break; + case tt_cache_type: + waypt_alloc_gc_data(wpt_tmp)->type = gs_mktype(cdatastrp); + break; + case tt_cache_difficulty: + sscanf(cdatastrp, "%f", &x); + waypt_alloc_gc_data(wpt_tmp)->diff = x * 10; + break; + case tt_cache_hint: + rtrim(cdatastrp); + if (cdatastrp[0]) { + waypt_alloc_gc_data(wpt_tmp)->hint = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_long: + rtrim(cdatastrp); + if (cdatastrp[0]) { + geocache_data* gc_data = waypt_alloc_gc_data(wpt_tmp); + gc_data->desc_long.is_html = cache_descr_is_html; + gc_data->desc_long.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_short: + rtrim(cdatastrp); + if (cdatastrp[0]) { + geocache_data* gc_data = waypt_alloc_gc_data(wpt_tmp); + gc_data->desc_short.is_html = cache_descr_is_html; + gc_data->desc_short.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_terrain: + sscanf(cdatastrp, "%f", &x); + waypt_alloc_gc_data(wpt_tmp)->terr = x * 10; + break; + case tt_cache_placer: + waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(cdatastrp); + break; + case tt_cache_log_date: + gc_log_date = xml_parse_time(cdatastrp, NULL); + break; + /* + * "Found it" logs follow the date according to the schema, + * if this is the first "found it" for this waypt, just use the + * last date we saw in this log. + */ + case tt_cache_log_type: + if ((0 == strcmp(cdatastrp, "Found it")) && + (0 == wpt_tmp->gc_data->last_found)) { + waypt_alloc_gc_data(wpt_tmp)->last_found = gc_log_date; + } + gc_log_date = 0; + break; + case tt_cache_favorite_points: + waypt_alloc_gc_data(wpt_tmp)->favorite_points = atoi(cdatastrp); + break; + case tt_cache_personal_note: + waypt_alloc_gc_data(wpt_tmp)->personal_note = xstrdup(cdatastrp); + break; + + /* + * Garmin-waypoint-specific tags. + */ + case tt_garmin_wpt_proximity: + case tt_garmin_wpt_temperature: + case tt_garmin_wpt_depth: + case tt_garmin_wpt_display_mode: + case tt_garmin_wpt_category: + case tt_garmin_wpt_addr: + case tt_garmin_wpt_city: + case tt_garmin_wpt_state: + case tt_garmin_wpt_country: + case tt_garmin_wpt_postal_code: + case tt_garmin_wpt_phone_nr: + garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); + break; + + /* + * Humminbird-waypoint-specific tags. + */ + case tt_humminbird_wpt_depth: + case tt_humminbird_trk_trkseg_trkpt_depth: + WAYPT_SET(wpt_tmp, depth, atof(cdatastrp) / 100.0) + break; + /* + * Route-specific tags. + */ + case tt_rte_name: + rte_head->rte_name = xstrdup(cdatastrp); + break; + case tt_rte: + break; + case tt_rte_rtept: + route_add_wpt(rte_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_rte_desc: + rte_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_rte_number: + rte_head->rte_num = atoi(cdatastrp); + break; + /* + * Track-specific tags. + */ + case tt_trk_name: + trk_head->rte_name = xstrdup(cdatastrp); + break; + case tt_trk: + break; + case tt_trk_trkseg: + next_trkpt_is_new_seg = 1; + break; + case tt_trk_trkseg_trkpt: + track_add_wpt(trk_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_trk_desc: + trk_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_trk_number: + trk_head->rte_num = atoi(cdatastrp); + break; + case tt_trk_trkseg_trkpt_course: + WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); + break; + case tt_trk_trkseg_trkpt_speed: + WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); + break; + case tt_trk_trkseg_trkpt_heartrate: + wpt_tmp->heartrate = atof(cdatastrp); + break; + case tt_trk_trkseg_trkpt_cadence: + wpt_tmp->cadence = atof(cdatastrp); + break; + + /* + * Items that are actually in multiple categories. + */ + case tt_wpt_ele: + case tt_rte_rtept_ele: + case tt_trk_trkseg_trkpt_ele: + sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); + break; + case tt_wpt_name: + case tt_rte_rtept_name: + case tt_trk_trkseg_trkpt_name: + wpt_tmp->shortname = xstrdup(cdatastrp); + break; + case tt_wpt_sym: + case tt_rte_rtept_sym: + case tt_trk_trkseg_trkpt_sym: + wpt_tmp->icon_descr = xstrdup(cdatastrp); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case tt_wpt_time: + case tt_trk_trkseg_trkpt_time: + case tt_rte_rtept_time: + wpt_tmp->creation_time = xml_parse_time(cdatastrp, &wpt_tmp->microseconds); + break; + case tt_wpt_cmt: + case tt_rte_rtept_cmt: + case tt_trk_trkseg_trkpt_cmt: + wpt_tmp->description = xstrdup(cdatastrp); + break; + case tt_wpt_desc: + case tt_trk_trkseg_trkpt_desc: + case tt_rte_rtept_desc: + if (wpt_tmp->notes != NULL) { + xfree(wpt_tmp->notes); + } + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_pdop: + wpt_tmp->pdop = atof(cdatastrp); + break; + case tt_hdop: + wpt_tmp->hdop = atof(cdatastrp); + break; + case tt_vdop: + wpt_tmp->vdop = atof(cdatastrp); + break; + case tt_sat: + wpt_tmp->sat = atof(cdatastrp); + break; + case tt_fix: + wpt_tmp->fix = (fix_type)(atoi(cdatastrp)-1); + if (wpt_tmp->fix < fix_2d) { + if (!case_ignore_strcmp(cdatastrp, "none")) { + wpt_tmp->fix = fix_none; + } else if (!case_ignore_strcmp(cdatastrp, "dgps")) { + wpt_tmp->fix = fix_dgps; + } else if (!case_ignore_strcmp(cdatastrp, "pps")) { + wpt_tmp->fix = fix_pps; + } else { + wpt_tmp->fix = fix_unknown; + } + } + break; + case tt_wpt_url: + case tt_trk_trkseg_trkpt_url: + case tt_rte_rtept_url: + wpt_tmp->url = xstrdup(cdatastrp); + break; + case tt_wpt_urlname: + case tt_trk_trkseg_trkpt_urlname: + case tt_rte_rtept_urlname: + wpt_tmp->url_link_text = xstrdup(cdatastrp); + break; + case tt_wpt_link: +//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: +//TODO: implement GPX 1.1 case tt_rte_rtept_link: + { + char* lt = link_text; + if (lt) { + lt = xstrdup(lrtrim(link_text)); + } + + waypt_add_url(wpt_tmp, xstrdup(link_url), lt); + link_text = NULL; + } + break; + case tt_unknown: + end_something_else(); + *s = 0; + return; + default: + break; + } + + if (passthrough) { + end_something_else(); + } + + *s = 0; + xml_free_converted_string(el); } #if ! HAVE_LIBEXPAT static void -gpx_rd_init(const char *fname) +gpx_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); } -static void -gpx_rd_deinit(void) +static void +gpx_rd_deinit(void) { } #else /* NO_EXPAT */ static void -gpx_cdata(void *dta, const XML_Char *xml_el, int len) +gpx_cdata(void* dta, const XML_Char* xml_el, int len) { - char *estr; - int *cdatalen; - char **cdata; - xml_tag *tmp_tag; - size_t slen = strlen(cdatastr.mem); - const char *s = xml_convert_to_char_string_n(xml_el, &len); - - vmem_realloc(&cdatastr, 1 + len + slen); - estr = ((char *) cdatastr.mem) + slen; - memcpy(estr, s, len); - estr[len] = 0; - - if (!cur_tag) - return; - - if ( cur_tag->child ) { - tmp_tag = cur_tag->child; - while ( tmp_tag->sibling ) { - tmp_tag = tmp_tag->sibling; - } - cdata = &(tmp_tag->parentcdata); - cdatalen = &(tmp_tag->parentcdatalen); - } - else { - cdata = &(cur_tag->cdata); - cdatalen = &(cur_tag->cdatalen); - } - estr = *cdata; - *cdata = xrealloc(*cdata, *cdatalen + len + 1); - estr = *cdata + *cdatalen; - memcpy( estr, s, len ); - *(estr+len) = '\0'; - *cdatalen += len; - - xml_free_converted_string(s); + char* estr; + int* cdatalen; + char** cdata; + xml_tag* tmp_tag; + size_t slen = strlen(cdatastr.mem); + const char* s = xml_convert_to_char_string_n(xml_el, &len); + + vmem_realloc(&cdatastr, 1 + len + slen); + estr = ((char*) cdatastr.mem) + slen; + memcpy(estr, s, len); + estr[len] = 0; + + if (!cur_tag) { + return; + } + + if (cur_tag->child) { + tmp_tag = cur_tag->child; + while (tmp_tag->sibling) { + tmp_tag = tmp_tag->sibling; + } + cdata = &(tmp_tag->parentcdata); + cdatalen = &(tmp_tag->parentcdatalen); + } else { + cdata = &(cur_tag->cdata); + cdatalen = &(cur_tag->cdatalen); + } + estr = *cdata; + *cdata = (char*) xrealloc(*cdata, *cdatalen + len + 1); + estr = *cdata + *cdatalen; + memcpy(estr, s, len); + *(estr+len) = '\0'; + *cdatalen += len; + + xml_free_converted_string(s); } static void -gpx_rd_init(const char *fname) +gpx_rd_init(const char* fname) { - if ( fname[0] ) { - fd = gbfopen(fname, "r", MYNAME); - input_fname = fname; - } - else { - fd = NULL; - input_string = fname+1; - input_string_len = strlen(input_string); - input_fname = NULL; - } - - - file_time = 0; - current_tag = vmem_alloc(1, 0); - *((char *)current_tag.mem) = '\0'; - - prescan_tags(); - - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ": Cannot create XML Parser\n"); - } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - - cdatastr = vmem_alloc(1, 0); - *((char *)cdatastr.mem) = '\0'; - - if (!xsi_schema_loc) { - xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); - } - if (!xsi_schema_loc) { - fatal("gpx: Unable to allocate %ld bytes of memory.\n", - (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); - } - - if (NULL == gpx_global) { - gpx_global = xcalloc(sizeof(*gpx_global), 1); - QUEUE_INIT(&gpx_global->name.queue); - QUEUE_INIT(&gpx_global->desc.queue); - QUEUE_INIT(&gpx_global->author.queue); - QUEUE_INIT(&gpx_global->email.queue); - QUEUE_INIT(&gpx_global->url.queue); - QUEUE_INIT(&gpx_global->urlname.queue); - QUEUE_INIT(&gpx_global->keywords.queue); - } - - XML_SetElementHandler(psr, gpx_start, gpx_end); - XML_SetCharacterDataHandler(psr, gpx_cdata); - fs_ptr = NULL; + if (fname[0]) { + fd = gbfopen(fname, "r", MYNAME); + input_fname = fname; + } else { + fd = NULL; + input_string = fname+1; + input_string_len = strlen(input_string); + input_fname = NULL; + } + + + file_time = 0; + current_tag = vmem_alloc(1, 0); + *((char*)current_tag.mem) = '\0'; + + prescan_tags(); + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ": Cannot create XML Parser\n"); + } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + + cdatastr = vmem_alloc(1, 0); + *((char*)cdatastr.mem) = '\0'; + + if (!xsi_schema_loc) { + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); + } + if (!xsi_schema_loc) { + fatal("gpx: Unable to allocate %ld bytes of memory.\n", + (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); + } + + if (NULL == gpx_global) { + gpx_global = (struct gpx_global*) xcalloc(sizeof(*gpx_global), 1); + QUEUE_INIT(&gpx_global->name.queue); + QUEUE_INIT(&gpx_global->desc.queue); + QUEUE_INIT(&gpx_global->author.queue); + QUEUE_INIT(&gpx_global->email.queue); + QUEUE_INIT(&gpx_global->url.queue); + QUEUE_INIT(&gpx_global->urlname.queue); + QUEUE_INIT(&gpx_global->keywords.queue); + } + + XML_SetElementHandler(psr, gpx_start, gpx_end); + XML_SetCharacterDataHandler(psr, gpx_cdata); + fs_ptr = NULL; } -static -void -gpx_rd_deinit(void) +static +void +gpx_rd_deinit(void) { - vmem_free(¤t_tag); - vmem_free(&cdatastr); - /* - * Don't free schema_loc. It really is important that we preserve - * this across reads or else merges/copies of files with different - * schemas won't retain the headers. - * - * moved to gpx_exit - - if ( xsi_schema_loc ) { - xfree(xsi_schema_loc); - xsi_schema_loc = NULL; - } - */ - - if ( gpx_email ) { - xfree(gpx_email); - gpx_email = NULL; - } - if ( gpx_author ) { - xfree(gpx_author); - gpx_author = NULL; - } - if (fd) { - gbfclose(fd); - } - XML_ParserFree(psr); - psr = NULL; - wpt_tmp = NULL; - cur_tag = NULL; - input_fname = NULL; + vmem_free(¤t_tag); + vmem_free(&cdatastr); + /* + * Don't free schema_loc. It really is important that we preserve + * this across reads or else merges/copies of files with different + * schemas won't retain the headers. + * + * moved to gpx_exit + + if ( xsi_schema_loc ) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + */ + + if (gpx_email) { + xfree(gpx_email); + gpx_email = NULL; + } + if (gpx_author) { + xfree(gpx_author); + gpx_author = NULL; + } + if (fd) { + gbfclose(fd); + } + XML_ParserFree(psr); + psr = NULL; + wpt_tmp = NULL; + cur_tag = NULL; + input_fname = NULL; } #endif static void -gpx_wr_init(const char *fname) +gpx_wr_init(const char* fname) { - mkshort_handle = mkshort_new_handle(); + mkshort_handle = mkshort_new_handle(); - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void gpx_wr_deinit(void) { - gbfclose(ofd); - mkshort_del_handle(&mkshort_handle); + gbfclose(ofd); + mkshort_del_handle(&mkshort_handle); } void gpx_read(void) { #if HAVE_LIBEXPAT - int len; - int done = 0; - char *buf = xmalloc(MY_CBUF_SZ); - int result = 0; - int extra; - - while (!done) { - if ( fd ) { - /* - * The majority of this block (in fact, all but the - * call to XML_Parse) are a disgusting hack to - * correct defective GPX files that Geocaching.com - * issues as pocket queries. They contain escape - * characters as entities (�-) which makes - * them not validate which croaks expat and torments - * users. - * - * Look for '&' in the last maxentlength chars. If - * we find it, strip it, then read byte-at-a-time - * until we find a non-entity. - */ - char *badchar; - char *semi; - int maxentlength = 8; - len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); - done = gbfeof(fd) || !len; - buf[len] = '\0'; - if (len < maxentlength) { - maxentlength = len; - } - badchar = buf+len-maxentlength; - badchar = strchr( badchar, '&' ); - extra = maxentlength - 1; /* for terminator */ - while ( badchar && len < MY_CBUF_SZ-1) { - semi = strchr( badchar, ';'); - while ( extra && !semi ) { - len += gbfread( buf+len, 1, 1, fd); - buf[len]='\0'; - extra--; - if ( buf[len-1] == ';') - semi= buf+len-1; - } - badchar = strchr( badchar+1, '&' ); - } - { - char hex[]="0123456789abcdef"; - badchar = strstr( buf, "&#x" ); - while ( badchar ) { - int val = 0; - char *hexit = badchar+3; - semi = strchr( badchar, ';' ); - if ( semi ) { - while (*hexit && *hexit != ';') { - char hc = isalpha(*hexit) ? tolower (*hexit) : *hexit; - val *= 16; - val += strchr( hex, hc)-hex; - hexit++; - } - - if ( val < 32 ) { - warning( MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)" ); - memmove( badchar, semi+1, strlen(semi+1)+1 ); - len -= (semi-badchar)+1; - badchar--; - } - } - badchar = strstr( badchar+1, "&#x" ); - } - } - result = XML_Parse(psr, buf, len, done); - } - else if (input_string) { - done = 0; - result = XML_Parse(psr, input_string, - input_string_len, done ); - done = 1; - } - else { - done = 1; - result = -1; - } - if (!result) { - fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", - (int) XML_GetCurrentLineNumber(psr), - input_fname ? input_fname : "unknown file", - XML_ErrorString(XML_GetErrorCode(psr))); - } - } - xfree(buf); + int len; + int done = 0; + char* buf = (char*) xmalloc(MY_CBUF_SZ); + int result = 0; + int extra; + + while (!done) { + if (fd) { + /* + * The majority of this block (in fact, all but the + * call to XML_Parse) are a disgusting hack to + * correct defective GPX files that Geocaching.com + * issues as pocket queries. They contain escape + * characters as entities (�-) which makes + * them not validate which croaks expat and torments + * users. + * + * Look for '&' in the last maxentlength chars. If + * we find it, strip it, then read byte-at-a-time + * until we find a non-entity. + */ + char* badchar; + char* semi; + int maxentlength = 8; + len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); + done = gbfeof(fd) || !len; + buf[len] = '\0'; + if (len < maxentlength) { + maxentlength = len; + } + badchar = buf+len-maxentlength; + badchar = strchr(badchar, '&'); + extra = maxentlength - 1; /* for terminator */ + while (badchar && len < MY_CBUF_SZ-1) { + semi = strchr(badchar, ';'); + while (extra && !semi) { + len += gbfread(buf+len, 1, 1, fd); + buf[len]='\0'; + extra--; + if (buf[len-1] == ';') { + semi= buf+len-1; + } + } + badchar = strchr(badchar+1, '&'); + } + { + char hex[]="0123456789abcdef"; + badchar = strstr(buf, "&#x"); + while (badchar) { + int val = 0; + char* hexit = badchar+3; + semi = strchr(badchar, ';'); + if (semi) { + while (*hexit && *hexit != ';') { + char hc = isalpha(*hexit) ? tolower(*hexit) : *hexit; + val *= 16; + val += strchr(hex, hc)-hex; + hexit++; + } + + if (val < 32) { + warning(MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)"); + memmove(badchar, semi+1, strlen(semi+1)+1); + len -= (semi-badchar)+1; + badchar--; + } + } + badchar = strstr(badchar+1, "&#x"); + } + } + result = XML_Parse(psr, buf, len, done); + } else if (input_string) { + done = 0; + result = XML_Parse(psr, input_string, + input_string_len, done); + done = 1; + } else { + done = 1; + result = -1; + } + if (!result) { + fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", + (int) XML_GetCurrentLineNumber(psr), + input_fname ? input_fname : "unknown file", + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + xfree(buf); #endif /* HAVE_LIBEXPAT */ } static void -fprint_tag_and_attrs( const char *prefix, const char *suffix, xml_tag *tag ) +fprint_tag_and_attrs(const char* prefix, const char* suffix, xml_tag* tag) { - char **pa; - gbfprintf( ofd, "%s%s", prefix, tag->tagname ); - pa = tag->attributes; - if ( pa ) { - while ( *pa ) { - gbfprintf( ofd, " %s=\"%s\"", pa[0], pa[1] ); - pa += 2; - } - } - gbfprintf( ofd, "%s", suffix ); + char** pa; + gbfprintf(ofd, "%s%s", prefix, tag->tagname); + pa = tag->attributes; + if (pa) { + while (*pa) { + gbfprintf(ofd, " %s=\"%s\"", pa[0], pa[1]); + pa += 2; + } + } + gbfprintf(ofd, "%s", suffix); } static void -fprint_xml_chain( xml_tag *tag, const waypoint *wpt ) +fprint_xml_chain(xml_tag* tag, const waypoint* wpt) { - char *tmp_ent; - while ( tag ) { - if ( !tag->cdata && !tag->child ) { - fprint_tag_and_attrs( "<", " />", tag ); - } - else { - fprint_tag_and_attrs( "<", ">", tag ); - - if ( tag->cdata ) { - tmp_ent = xml_entitize( tag->cdata ); - gbfprintf( ofd, "%s", tmp_ent ); - xfree(tmp_ent); - } - if ( tag->child ) { - fprint_xml_chain(tag->child, wpt); - } - if ( wpt && wpt->gc_data->exported && - strcmp(tag->tagname, "groundspeak:cache" ) == 0 ) { - xml_write_time( ofd, wpt->gc_data->exported, 0, - "groundspeak:exported" ); - } - gbfprintf( ofd, "\n", tag->tagname); - } - if ( tag->parentcdata ) { - tmp_ent = xml_entitize(tag->parentcdata); - gbfprintf(ofd, "%s", tmp_ent ); - xfree(tmp_ent); - } - tag = tag->sibling; - } -} - -void free_gpx_extras( xml_tag *tag ) + while (tag) { + if (!tag->cdata && !tag->child) { + fprint_tag_and_attrs("<", " />", tag); + } else { + fprint_tag_and_attrs("<", ">", tag); + + if (tag->cdata) { + char* tmp_ent; + tmp_ent = xml_entitize(tag->cdata); + gbfprintf(ofd, "%s", tmp_ent); + xfree(tmp_ent); + } + if (tag->child) { + fprint_xml_chain(tag->child, wpt); + } + if (wpt && wpt->gc_data->exported && + strcmp(tag->tagname, "groundspeak:cache") == 0) { + xml_write_time(ofd, wpt->gc_data->exported, 0, + "groundspeak:exported"); + } + gbfprintf(ofd, "\n", tag->tagname); + } + if (tag->parentcdata) { + // retain whitespacing, but nuke leading NL as the above will add a trailing. + + char* otmp_ent, *tmp_ent = NULL; + otmp_ent = xml_entitize(tag->parentcdata); + if (otmp_ent[0] == '\n') + tmp_ent = otmp_ent+1; + else + tmp_ent = otmp_ent; + gbfprintf(ofd, "%s", tmp_ent); + xfree(otmp_ent); + } + tag = tag->sibling; + } +} + +void free_gpx_extras(xml_tag* tag) { - xml_tag *next = NULL; - char **ap; - - while ( tag ) { - if (tag->cdata) { - xfree(tag->cdata); - } - if (tag->child) { - free_gpx_extras(tag->child); - } - if (tag->parentcdata) { - xfree(tag->parentcdata); - } - if (tag->tagname) { - xfree(tag->tagname); - } - if (tag->attributes) { - ap = tag->attributes; - - while (*ap) - xfree(*ap++); - - xfree(tag->attributes); - } - - next = tag->sibling; - xfree(tag); - tag = next; - } + xml_tag* next = NULL; + char** ap; + + while (tag) { + if (tag->cdata) { + xfree(tag->cdata); + } + if (tag->child) { + free_gpx_extras(tag->child); + } + if (tag->parentcdata) { + xfree(tag->parentcdata); + } + if (tag->tagname) { + xfree(tag->tagname); + } + if (tag->attributes) { + ap = tag->attributes; + + while (*ap) { + xfree(*ap++); + } + + xfree(tag->attributes); + } + + next = tag->sibling; + xfree(tag); + tag = next; + } } /* * Handle the grossness of GPX 1.0 vs. 1.1 handling of linky links. */ static void -write_gpx_url(const waypoint *waypointp) +write_gpx_url(const waypoint* waypointp) { - char *tmp_ent; - - if (waypointp->url == NULL) { - return; - } - - if (gpx_wversion_num > 10) { - url_link *tail; - for (tail = (url_link *)&waypointp->url_next; tail; tail = tail->url_next) { - tmp_ent = xml_entitize(tail->url); - gbfprintf(ofd, " \n", - urlbase ? urlbase : "", tmp_ent); - write_optional_xml_entity(ofd, " ", "text", - tail->url_link_text); - gbfprintf(ofd, " \n"); - xfree(tmp_ent); - } - } else { - tmp_ent = xml_entitize(waypointp->url); - gbfprintf(ofd, " %s%s\n", - urlbase ? urlbase : "", tmp_ent); - write_optional_xml_entity(ofd, " ", "urlname", - waypointp->url_link_text); - xfree(tmp_ent); - } + char* tmp_ent; + + if (waypointp->url == NULL) { + return; + } + + if (gpx_wversion_num > 10) { + url_link* tail; + for (tail = (url_link*)&waypointp->url_next; tail; tail = tail->url_next) { + tmp_ent = xml_entitize(tail->url); + gbfprintf(ofd, " \n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "text", + tail->url_link_text); + gbfprintf(ofd, " \n"); + xfree(tmp_ent); + } + } else { + tmp_ent = xml_entitize(waypointp->url); + gbfprintf(ofd, " %s%s\n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "urlname", + waypointp->url_link_text); + xfree(tmp_ent); + } } /* @@ -1561,458 +1583,496 @@ write_gpx_url(const waypoint *waypointp) * Order counts. */ static void -gpx_write_common_acc(const waypoint *waypointp, const char *indent) +gpx_write_common_acc(const waypoint* waypointp, const char* indent) { - const char *fix = NULL; - - switch (waypointp->fix) { - case fix_2d: - fix = "2d"; - break; - case fix_3d: - fix = "3d"; - break; - case fix_dgps: - fix = "dgps"; - break; - case fix_pps: - fix = "pps"; - break; - case fix_none: - fix = "none"; - break; - /* GPX spec says omit if we don't know. */ - case fix_unknown: - default: - break; - } - if (fix) { - gbfprintf(ofd, "%s%s\n", indent, fix); - } - if (waypointp->sat > 0) { - gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); - } - if (waypointp->hdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); - } - if (waypointp->vdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); - } - if (waypointp->pdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); - } + const char* fix = NULL; + + switch (waypointp->fix) { + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + case fix_none: + fix = "none"; + break; + /* GPX spec says omit if we don't know. */ + case fix_unknown: + default: + break; + } + if (fix) { + gbfprintf(ofd, "%s%s\n", indent, fix); + } + if (waypointp->sat > 0) { + gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); + } + if (waypointp->hdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); + } + if (waypointp->vdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); + } + if (waypointp->pdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); + } } static void -gpx_write_common_position(const waypoint *waypointp, const char *indent) +gpx_write_common_position(const waypoint* waypointp, const char* indent) { - if (waypointp->altitude != unknown_alt) { - gbfprintf(ofd, "%s%f\n", - indent, waypointp->altitude); - } - if (waypointp->creation_time) { - gbfprintf(ofd, indent); - xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); - } + if (waypointp->altitude != unknown_alt) { + gbfprintf(ofd, "%s%f\n", + indent, waypointp->altitude); + } + if (waypointp->creation_time) { + gbfprintf(ofd, indent); + xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); + } } static void -gpx_write_common_extensions(const waypoint *waypointp, const char *indent) +gpx_write_common_extensions(const waypoint* waypointp, const char* indent) { - if (((opt_humminbirdext || opt_garminext) && (waypointp->depth != 0 || waypointp->temperature != 0)) - || (opt_garminext && (waypointp->heartrate != 0 || waypointp->cadence != 0))) { - gbfprintf(ofd, "%s\n", indent); - if (waypointp->depth != 0) { - if (opt_humminbirdext) - gbfprintf(ofd, "%s %f\n", - indent, waypointp->depth*100.0); - if (opt_garminext) - gbfprintf(ofd, "%s %f\n", - indent, waypointp->depth); - } - if (waypointp->temperature != 0) { - if (opt_humminbirdext) - gbfprintf(ofd, "%s %f\n", - indent, waypointp->temperature); - if (opt_garminext) - gbfprintf(ofd, "%s %f\n", - indent, waypointp->temperature); - } - if (opt_garminext && (waypointp->heartrate != 0 || waypointp->cadence != 0)) { - gbfprintf(ofd, "%s \n", indent); - if (waypointp->heartrate != 0) - gbfprintf(ofd, "%s %u\n", - indent, waypointp->heartrate); - if (waypointp->cadence != 0) - gbfprintf(ofd, "%s %u\n", - indent, waypointp->cadence); - gbfprintf(ofd, "%s \n", indent); - } - gbfprintf(ofd, "%s\n", indent); - } + if (((opt_humminbirdext || opt_garminext) && (waypointp->depth != 0 || waypointp->temperature != 0)) + || (opt_garminext && (waypointp->heartrate != 0 || waypointp->cadence != 0))) { + gbfprintf(ofd, "%s\n", indent); + if (waypointp->depth != 0) { + if (opt_humminbirdext) + gbfprintf(ofd, "%s %f\n", + indent, waypointp->depth*100.0); + if (opt_garminext) + gbfprintf(ofd, "%s %f\n", + indent, waypointp->depth); + } + if (waypointp->temperature != 0) { + if (opt_humminbirdext) + gbfprintf(ofd, "%s %f\n", + indent, waypointp->temperature); + if (opt_garminext) + gbfprintf(ofd, "%s %f\n", + indent, waypointp->temperature); + } + if (opt_garminext && (waypointp->heartrate != 0 || waypointp->cadence != 0)) { + gbfprintf(ofd, "%s \n", indent); + if (waypointp->heartrate != 0) + gbfprintf(ofd, "%s %u\n", + indent, waypointp->heartrate); + if (waypointp->cadence != 0) + gbfprintf(ofd, "%s %u\n", + indent, waypointp->cadence); + gbfprintf(ofd, "%s \n", indent); + } + gbfprintf(ofd, "%s\n", indent); + } } static void -gpx_write_common_description(const waypoint *waypointp, const char *indent, - const char *oname) +gpx_write_common_description(const waypoint* waypointp, const char* indent, + const char* oname) { - write_optional_xml_entity(ofd, indent, "name", oname); - write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); - if (waypointp->notes && waypointp->notes[0]) - write_xml_entity(ofd, indent, "desc", waypointp->notes); - else - write_optional_xml_entity(ofd, indent, "desc", waypointp->description); - write_gpx_url(waypointp); - write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); + write_optional_xml_entity(ofd, indent, "name", oname); + write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); + if (waypointp->notes && waypointp->notes[0]) { + write_xml_entity(ofd, indent, "desc", waypointp->notes); + } else { + write_optional_xml_entity(ofd, indent, "desc", waypointp->description); + } + write_gpx_url(waypointp); + write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); } static void -gpx_waypt_pr(const waypoint *waypointp) +gpx_waypt_pr(const waypoint* waypointp) { - const char *oname; - char *odesc; - fs_xml *fs_gpx; - garmin_fs_t *gmsd; /* gARmIN sPECIAL dATA */ - - /* - * Desparation time, try very hard to get a good shortname - */ - odesc = waypointp->notes; - if (!odesc) { - odesc = waypointp->description; - } - if (!odesc) { - odesc = waypointp->shortname; - } - - oname = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, odesc) : - waypointp->shortname; - - gbfprintf(ofd, "\n", - waypointp->latitude, - waypointp->longitude); - - gpx_write_common_position(waypointp, " "); - gpx_write_common_description(waypointp, " ", oname); - gpx_write_common_acc(waypointp, " "); - - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - gmsd = GMSD_FIND(waypointp); - if ( fs_gpx ) { - if (! gmsd) fprint_xml_chain( fs_gpx->tag, waypointp ); - } - if (gmsd && (gpx_wversion_num > 10)) { - /* MapSource doesn't accepts extensions from 1.0 */ - garmin_fs_xml_fprint(ofd, waypointp); - } - gpx_write_common_extensions(waypointp, " "); - gbfprintf(ofd, "\n"); + const char* oname; + char* odesc; + fs_xml* fs_gpx; + garmin_fs_t* gmsd; /* gARmIN sPECIAL dATA */ + + /* + * Desparation time, try very hard to get a good shortname + */ + odesc = waypointp->notes; + if (!odesc) { + odesc = waypointp->description; + } + if (!odesc) { + odesc = waypointp->shortname; + } + + oname = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, odesc) : + waypointp->shortname; + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", oname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml*)fs_chain_find(waypointp->fs, FS_GPX); + gmsd = GMSD_FIND(waypointp); + if (fs_gpx) { + if (! gmsd) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } + } + if (gmsd && (gpx_wversion_num > 10)) { + /* MapSource doesn't accepts extensions from 1.0 */ + garmin_fs_xml_fprint(ofd, waypointp); + } + gpx_write_common_extensions(waypointp, " "); + gbfprintf(ofd, "\n"); } static void -gpx_track_hdr(const route_head *rte) +gpx_track_hdr(const route_head* rte) { - fs_xml *fs_gpx; - current_trk_head = rte; - - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "name", rte->rte_name); - write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); - if (rte->rte_num) { - gbfprintf(ofd, "%d\n", rte->rte_num); - } - - if (gpx_wversion_num > 10) { - fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, NULL ); - } - } + fs_xml* fs_gpx; + current_trk_head = rte; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, "%d\n", rte->rte_num); + } + + if (gpx_wversion_num > 10) { + fs_gpx = (fs_xml*)fs_chain_find(rte->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, NULL); + } + } } static void -gpx_track_disp(const waypoint *waypointp) +gpx_track_disp(const waypoint* waypointp) { - fs_xml *fs_gpx; - int first_in_trk; - first_in_trk = waypointp->Q.prev == ¤t_trk_head->waypoint_list; - - if (waypointp->wpt_flags.new_trkseg) { - if (!first_in_trk) { - gbfprintf(ofd, "\n"); - } - gbfprintf(ofd, "\n"); - } - - gbfprintf(ofd, "\n", - waypointp->latitude, - waypointp->longitude); - - gpx_write_common_position(waypointp, " "); - - /* These were accidentally removed from 1.1 */ - if (gpx_wversion_num == 10) { - if WAYPT_HAS(waypointp, course) { - gbfprintf(ofd, " %f\n", - waypointp->course); - } - if WAYPT_HAS(waypointp, speed) { - gbfprintf(ofd, " %f\n", - waypointp->speed); - } - } - - /* GPX doesn't require a name on output, so if we made one up - * on input, we might as well say nothing. - */ - gpx_write_common_description(waypointp, " ", - waypointp->wpt_flags.shortname_is_synthetic ? - NULL : waypointp->shortname); - gpx_write_common_acc(waypointp, " "); - - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, waypointp ); - } - - gpx_write_common_extensions(waypointp, " "); - gbfprintf(ofd, "\n"); + fs_xml* fs_gpx; + int first_in_trk; + first_in_trk = waypointp->Q.prev == ¤t_trk_head->waypoint_list; + + if (waypointp->wpt_flags.new_trkseg) { + if (!first_in_trk) { + gbfprintf(ofd, "\n"); + } + gbfprintf(ofd, "\n"); + } + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + + /* These were accidentally removed from 1.1 */ + if (gpx_wversion_num == 10) { + if WAYPT_HAS(waypointp, course) { + gbfprintf(ofd, " %f\n", + waypointp->course); + } + if WAYPT_HAS(waypointp, speed) { + gbfprintf(ofd, " %f\n", + waypointp->speed); + } + } + + /* GPX doesn't require a name on output, so if we made one up + * on input, we might as well say nothing. + */ + gpx_write_common_description(waypointp, " ", + waypointp->wpt_flags.shortname_is_synthetic ? + NULL : waypointp->shortname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml*)fs_chain_find(waypointp->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } + + gpx_write_common_extensions(waypointp, " "); + gbfprintf(ofd, "\n"); } static void -gpx_track_tlr(const route_head *rte) +gpx_track_tlr(const route_head* rte) { - if (!QUEUE_EMPTY(¤t_trk_head->waypoint_list)) { - gbfprintf(ofd, "\n"); - } - gbfprintf(ofd, "\n"); - current_trk_head = NULL; + if (!QUEUE_EMPTY(¤t_trk_head->waypoint_list)) { + gbfprintf(ofd, "\n"); + } + gbfprintf(ofd, "\n"); + current_trk_head = NULL; } static void gpx_track_pr() { - track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); + track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); } static void -gpx_route_hdr(const route_head *rte) +gpx_route_hdr(const route_head* rte) { - fs_xml *fs_gpx; - - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "name", rte->rte_name); - write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); - if (rte->rte_num) { - gbfprintf(ofd, " %d\n", rte->rte_num); - } - - if (gpx_wversion_num > 10) { - fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, NULL ); - } - } + fs_xml* fs_gpx; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, " %d\n", rte->rte_num); + } + + if (gpx_wversion_num > 10) { + fs_gpx = (fs_xml*)fs_chain_find(rte->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, NULL); + } + } } static void -gpx_route_disp(const waypoint *waypointp) +gpx_route_disp(const waypoint* waypointp) { - fs_xml *fs_gpx; + fs_xml* fs_gpx; - gbfprintf(ofd, " \n", - waypointp->latitude, - waypointp->longitude); + gbfprintf(ofd, " \n", + waypointp->latitude, + waypointp->longitude); - gpx_write_common_position(waypointp, " "); - gpx_write_common_description(waypointp, " ", waypointp->shortname); - gpx_write_common_acc(waypointp, " "); + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", waypointp->shortname); + gpx_write_common_acc(waypointp, " "); - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, waypointp ); - } + fs_gpx = (fs_xml*)fs_chain_find(waypointp->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } - gpx_write_common_extensions(waypointp, " "); - gbfprintf(ofd, " \n"); + gpx_write_common_extensions(waypointp, " "); + gbfprintf(ofd, " \n"); } static void -gpx_route_tlr(const route_head *rte) +gpx_route_tlr(const route_head* rte) { - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void gpx_route_pr() { - /* output routes */ - route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); + /* output routes */ + route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); } static void -gpx_waypt_bound_calc(const waypoint *waypointp) +gpx_waypt_bound_calc(const waypoint* waypointp) { - waypt_add_to_bounds(&all_bounds, waypointp); + waypt_add_to_bounds(&all_bounds, waypointp); } static void gpx_write_bounds(void) { - waypt_init_bounds(&all_bounds); - - waypt_disp_all(gpx_waypt_bound_calc); - route_disp_all(NULL, NULL, gpx_waypt_bound_calc); - track_disp_all(NULL, NULL, gpx_waypt_bound_calc); - - if (waypt_bounds_valid(&all_bounds)) { - gbfprintf(ofd, "\n", - all_bounds.min_lat, all_bounds.min_lon, - all_bounds.max_lat, all_bounds.max_lon); - } + waypt_init_bounds(&all_bounds); + + waypt_disp_all(gpx_waypt_bound_calc); + route_disp_all(NULL, NULL, gpx_waypt_bound_calc); + track_disp_all(NULL, NULL, gpx_waypt_bound_calc); + + if (waypt_bounds_valid(&all_bounds)) { + gbfprintf(ofd, "\n", + all_bounds.min_lat, all_bounds.min_lon, + all_bounds.max_lat, all_bounds.max_lon); + } } static void gpx_write(void) { - time_t now = 0; - int short_length; - - if (opt_humminbirdext || opt_garminext) - gpx_wversion = (char *)"1.1"; - - gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; - - if (gpx_wversion_num <= 0) { - fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); - } - - now = current_time(); - - short_length = atoi(snlen); - - if (suppresswhite) { - setshort_whitespace_ok(mkshort_handle, 0); - } - - setshort_length(mkshort_handle, short_length); - - gbfprintf(ofd, "\n", global_opts.charset_name); - gbfprintf(ofd, "\n", xsi_schema_loc); - } else { - gbfprintf(ofd, - " xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", - gpx_wversion[0], gpx_wversion[2], - gpx_wversion[0], gpx_wversion[2]); - } - - if (gpx_wversion_num > 10) { - gbfprintf(ofd, "\n"); - } - gpx_write_gdata(&gpx_global->name, "name"); - gpx_write_gdata(&gpx_global->desc, "desc"); - /* In GPX 1.1, author changed from a string to a PersonType. - * since it's optional, we just drop it instead of rewriting it. - */ - if (gpx_wversion_num < 11) { - gpx_write_gdata(&gpx_global->author, "author"); - } - gpx_write_gdata(&gpx_global->email, "email"); - gpx_write_gdata(&gpx_global->url, "url"); - gpx_write_gdata(&gpx_global->urlname, "urlname"); - xml_write_time( ofd, now, 0, "time" ); - gpx_write_gdata(&gpx_global->keywords, "keywords"); - - gpx_write_bounds(); - - if (gpx_wversion_num > 10) { - gbfprintf(ofd, "\n"); - } - - waypt_disp_all(gpx_waypt_pr); - gpx_route_pr(); - gpx_track_pr(); - - gbfprintf(ofd, "\n"); + time_t now = 0; + int short_length; + + /* if an output version is not specified and an input version is + * available use it, otherwise use the default. + */ + if (! gpx_wversion) { + if (! gpx_version) { + gpx_wversion = (char *)"1.0"; + } else { + gpx_wversion = (char *)gpx_version; + } + } + + if (opt_humminbirdext || opt_garminext) { + gpx_wversion = (char*)"1.1"; + } + + gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; + + if (gpx_wversion_num <= 0) { + fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); + } + + now = current_time(); + + short_length = atoi(snlen); + + if (suppresswhite) { + setshort_whitespace_ok(mkshort_handle, 0); + } + + setshort_length(mkshort_handle, short_length); + + gbfprintf(ofd, "\n", global_opts.charset_name); + gbfprintf(ofd, "\n", xsi_schema_loc); + } else { + gbfprintf(ofd, + " xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", + gpx_wversion[0], gpx_wversion[2], + gpx_wversion[0], gpx_wversion[2]); + } + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + gpx_write_gdata(&gpx_global->name, "name"); + gpx_write_gdata(&gpx_global->desc, "desc"); + /* In GPX 1.1, author changed from a string to a PersonType. + * since it's optional, we just drop it instead of rewriting it. + */ + if (gpx_wversion_num < 11) { + gpx_write_gdata(&gpx_global->author, "author"); + } + /* In GPX 1.1 email, url, urlname aren't allowed. */ + if (gpx_wversion_num < 11) { + gpx_write_gdata(&gpx_global->email, "email"); + gpx_write_gdata(&gpx_global->url, "url"); + gpx_write_gdata(&gpx_global->urlname, "urlname"); + } + xml_write_time(ofd, now, 0, "time"); + gpx_write_gdata(&gpx_global->keywords, "keywords"); + + gpx_write_bounds(); + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + + waypt_disp_all(gpx_waypt_pr); + gpx_route_pr(); + gpx_track_pr(); + + gbfprintf(ofd, "\n"); } static void gpx_free_gpx_global(void) { - gpx_rm_from_global(&gpx_global->name); - gpx_rm_from_global(&gpx_global->desc); - gpx_rm_from_global(&gpx_global->author); - gpx_rm_from_global(&gpx_global->email); - gpx_rm_from_global(&gpx_global->url); - gpx_rm_from_global(&gpx_global->urlname); - gpx_rm_from_global(&gpx_global->keywords); - xfree(gpx_global); + gpx_rm_from_global(&gpx_global->name); + gpx_rm_from_global(&gpx_global->desc); + gpx_rm_from_global(&gpx_global->author); + gpx_rm_from_global(&gpx_global->email); + gpx_rm_from_global(&gpx_global->url); + gpx_rm_from_global(&gpx_global->urlname); + gpx_rm_from_global(&gpx_global->keywords); + xfree(gpx_global); } static void gpx_exit(void) { - if ( xsi_schema_loc ) { - xfree(xsi_schema_loc); - xsi_schema_loc = NULL; - } - - if (gpx_global) { - gpx_free_gpx_global(); - gpx_global = NULL; - } + if (gpx_version) { + xfree(gpx_version); + gpx_version = NULL; + } + + if (xsi_schema_loc) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + + if (gpx_global) { + gpx_free_gpx_global(); + gpx_global = NULL; + } } static arglist_t gpx_args[] = { - { "snlen", &snlen, "Length of generated shortnames", - "32", ARGTYPE_INT, "1", NULL }, - { "suppresswhite", &suppresswhite, - "No whitespace in generated shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logpoint", &opt_logpoint, - "Create waypoints from geocache log entries", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "urlbase", &urlbase, "Base URL for link tag in output", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - { "gpxver", &gpx_wversion, "Target GPX version for output", - "1.0", ARGTYPE_STRING, ARG_NOMINMAX}, - { "humminbirdextensions", &opt_humminbirdext, - "Add info (depth) as Humminbird extension", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "garminextensions", &opt_garminext, - "Add info (depth) as Garmin extension", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "snlen", &snlen, "Length of generated shortnames", + "32", ARGTYPE_INT, "1", NULL + }, + { + "suppresswhite", &suppresswhite, + "No whitespace in generated shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logpoint", &opt_logpoint, + "Create waypoints from geocache log entries", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "urlbase", &urlbase, "Base URL for link tag in output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "gpxver", &gpx_wversion, "Target GPX version for output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "humminbirdextensions", &opt_humminbirdext, + "Add info (depth) as Humminbird extension", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "garminextensions", &opt_garminext, + "Add info (depth) as Garmin extension", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t gpx_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - gpx_rd_init, - gpx_wr_init, - gpx_rd_deinit, - gpx_wr_deinit, - gpx_read, - gpx_write, - gpx_exit, - gpx_args, - CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + gpx_rd_init, + gpx_wr_init, + gpx_rd_deinit, + gpx_wr_deinit, + gpx_read, + gpx_write, + gpx_exit, + gpx_args, + CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ }; diff --git a/gpsbabel/grtcirc.c b/gpsbabel/grtcirc.c index 44ecf1adf..8e98d204e 100644 --- a/gpsbabel/grtcirc.c +++ b/gpsbabel/grtcirc.c @@ -25,16 +25,18 @@ static const double EARTH_RAD = 6378137.0; -static void crossproduct( double x1, double y1, double z1, - double x2, double y2, double z2, - double *xa, double *ya, double *za ) { - *xa = y1*z2-y2*z1; - *ya = z1*x2-z2*x1; - *za = x1*y2-y1*x2; +static void crossproduct(double x1, double y1, double z1, + double x2, double y2, double z2, + double* xa, double* ya, double* za) +{ + *xa = y1*z2-y2*z1; + *ya = z1*x2-z2*x1; + *za = x1*y2-y1*x2; } -static double dotproduct( double x1, double y1, double z1, - double x2, double y2, double z2 ) { +static double dotproduct(double x1, double y1, double z1, + double x2, double y2, double z2) +{ return (x1*x2+y1*y2+z1*z2); } @@ -49,140 +51,163 @@ static double dotproduct( double x1, double y1, double z1, * time, so why not leave the expression human-readable? */ -double radtomiles( double rads ) { - const double radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0; - return (rads*radmiles); +double radtomiles(double rads) +{ + const double radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0; + return (rads*radmiles); } -double radtometers( double rads ) { - return ( rads * EARTH_RAD ); +double radtometers(double rads) +{ + return (rads * EARTH_RAD); } -double gcdist( double lat1, double lon1, double lat2, double lon2 ) +double gcdist(double lat1, double lon1, double lat2, double lon2) { - double res; - double sdlat, sdlon; + double res; + double sdlat, sdlon; - errno = 0; + errno = 0; - sdlat = sin((lat1 - lat2) / 2.0); - sdlon = sin((lon1 - lon2) / 2.0); + sdlat = sin((lat1 - lat2) / 2.0); + sdlon = sin((lon1 - lon2) / 2.0); - res = sqrt(sdlat * sdlat + cos(lat1) * cos(lat2) * sdlon * sdlon); + res = sqrt(sdlat * sdlat + cos(lat1) * cos(lat2) * sdlon * sdlon); - if (res > 1.0) { - res = 1.0; - } else if (res < -1.0) { - res = -1.0; - } + if (res > 1.0) { + res = 1.0; + } else if (res < -1.0) { + res = -1.0; + } - res = asin(res); + res = asin(res); - if ( + if ( #if defined isnan - /* This is a C99-ism. */ - (isnan(res)) || + /* This is a C99-ism. */ + (isnan(res)) || #endif - (errno == EDOM)) { /* this should never happen: */ - errno = 0; /* Math argument out of domain of + (errno == EDOM)) { /* this should never happen: */ + errno = 0; /* Math argument out of domain of function, */ - return 0; /* or value returned is not a number */ - } + return 0; /* or value returned is not a number */ + } - return 2.0 * res; + return 2.0 * res; } -/* This value is the heading you'd leave point 1 at to arrive at point 2. +/* This value is the heading you'd leave point 1 at to arrive at point 2. * Inputs and outputs are in radians. */ -double heading( double lat1, double lon1, double lat2, double lon2 ) { +double heading(double lat1, double lon1, double lat2, double lon2) +{ double v1, v2; v1 = sin(lon1 - lon2) * cos(lat2); v2 = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon1 - lon2); /* rounding error protection */ - if (fabs(v1) < 1e-15) v1 = 0.0; - if (fabs(v2) < 1e-15) v2 = 0.0; + if (fabs(v1) < 1e-15) { + v1 = 0.0; + } + if (fabs(v2) < 1e-15) { + v2 = 0.0; + } return atan2(v1, v2); } /* As above, but outputs is in degrees from 0 - 359. Inputs are still radians. */ -double heading_true_degrees( double lat1, double lon1, double lat2, double lon2 ) +double heading_true_degrees(double lat1, double lon1, double lat2, double lon2) { double h = 360.0 - DEG(heading(lat1, lon1, lat2, lon2)); - if (h >= 360.0) h -= 360.0; + if (h >= 360.0) { + h -= 360.0; + } return h; } - -double linedist(double lat1, double lon1, - double lat2, double lon2, - double lat3, double lon3 ) { +double linedistprj(double lat1, double lon1, + double lat2, double lon2, + double lat3, double lon3, + double* prjlat, double* prjlon, + double* frac) +{ static double _lat1 = -9999; static double _lat2 = -9999; static double _lon1 = -9999; static double _lon2 = -9999; - + static double x1,y1,z1; static double x2,y2,z2; static double xa,ya,za,la; - + double x3,y3,z3; double xp,yp,zp,lp; - + double xa1,ya1,za1; double xa2,ya2,za2; - + double d1, d2; double c1, c2; double dot; int newpoints; - + + *prjlat = lat1; + *prjlon = lon1; + *frac = 0; + /* degrees to radians */ - lat1 = RAD(lat1); lon1 = RAD(lon1); - lat2 = RAD(lat2); lon2 = RAD(lon2); - lat3 = RAD(lat3); lon3 = RAD(lon3); + lat1 = RAD(lat1); + lon1 = RAD(lon1); + lat2 = RAD(lat2); + lon2 = RAD(lon2); + lat3 = RAD(lat3); + lon3 = RAD(lon3); newpoints = 1; - if ( lat1 == _lat1 && lat2 == _lat2 && lon1 == _lon1 && lon2 == _lon2) { + if (lat1 == _lat1 && lat2 == _lat2 && lon1 == _lon1 && lon2 == _lon2) { newpoints = 0; - } - else { + } else { _lat1 = lat1; _lat2 = lat2; _lon1 = lon1; _lon2 = lon2; } - + /* polar to ECEF rectangular */ - if ( newpoints ) { - x1 = cos(lon1)*cos(lat1); y1 = sin(lat1); z1 = sin(lon1)*cos(lat1); - x2 = cos(lon2)*cos(lat2); y2 = sin(lat2); z2 = sin(lon2)*cos(lat2); + if (newpoints) { + x1 = cos(lon1)*cos(lat1); + y1 = sin(lat1); + z1 = sin(lon1)*cos(lat1); + x2 = cos(lon2)*cos(lat2); + y2 = sin(lat2); + z2 = sin(lon2)*cos(lat2); } - x3 = cos(lon3)*cos(lat3); y3 = sin(lat3); z3 = sin(lon3)*cos(lat3); - - if ( newpoints ) { - /* 'a' is the axis; the line that passes through the center of the earth - * and is perpendicular to the great circle through point 1 and point 2 - * It is computed by taking the cross product of the '1' and '2' vectors.*/ - crossproduct( x1, y1, z1, x2, y2, z2, &xa, &ya, &za ); + x3 = cos(lon3)*cos(lat3); + y3 = sin(lat3); + z3 = sin(lon3)*cos(lat3); + + if (newpoints) { + /* 'a' is the axis; the line that passes through the center of the earth + * and is perpendicular to the great circle through point 1 and point 2 + * It is computed by taking the cross product of the '1' and '2' vectors.*/ + crossproduct(x1, y1, z1, x2, y2, z2, &xa, &ya, &za); la = sqrt(xa*xa+ya*ya+za*za); - if ( la ) { + if (la) { xa /= la; ya /= la; za /= la; } } - if ( la ) { + if (la) { /* dot is the component of the length of '3' that is along the axis. - * What's left is a non-normalized vector that lies in the plane of + * What's left is a non-normalized vector that lies in the plane of * 1 and 2. */ - + dot = dotproduct(x3,y3,z3,xa,ya,za); xp = x3-dot*xa; @@ -191,97 +216,115 @@ double linedist(double lat1, double lon1, lp = sqrt(xp*xp+yp*yp+zp*zp); - if ( lp ) { + if (lp) { /* After this, 'p' is normalized */ xp /= lp; yp /= lp; zp /= lp; - - crossproduct(x1,y1,z1,xp,yp,zp,&xa1,&ya1,&za1); - d1 = dotproduct( xa1, ya1, za1, xa, ya, za ); + + crossproduct(x1,y1,z1,xp,yp,zp,&xa1,&ya1,&za1); + d1 = dotproduct(xa1, ya1, za1, xa, ya, za); crossproduct(xp,yp,zp,x2,y2,z2,&xa2,&ya2,&za2); - d2 = dotproduct( xa2, ya2, za2, xa, ya, za ); - - if ( d1 >= 0 && d2 >= 0 ) { - /* rather than call gcdist and all its sines and cosines and - * worse, we can get the angle directly. It's the arctangent - * of the length of the component of vector 3 along the axis - * divided by the length of the component of vector 3 in the - * plane. We already have both of those numbers. - * - * atan2 would be overkill because lp and fabs(dot) are both - * known to be positive. */ - - return atan( fabs(dot)/lp ); + d2 = dotproduct(xa2, ya2, za2, xa, ya, za); + + if (d1 >= 0 && d2 >= 0) { + /* rather than call gcdist and all its sines and cosines and + * worse, we can get the angle directly. It's the arctangent + * of the length of the component of vector 3 along the axis + * divided by the length of the component of vector 3 in the + * plane. We already have both of those numbers. + * + * atan2 would be overkill because lp and fabs(dot) are both + * known to be positive. */ + + *prjlat = DEG(asin(yp)); + if(xp == 0 && zp == 0) { + *prjlon = 0; + } + else { + *prjlon = DEG(atan2(zp, xp)); + } + *frac = d1/(d1 + d2); + + return atan(fabs(dot)/lp); } - + /* otherwise, get the distance from the closest endpoint */ - c1 = dotproduct( x1,y1,z1,xp,yp,zp ); - c2 = dotproduct( x2,y2,z2,xp,yp,zp ); + c1 = dotproduct(x1,y1,z1,xp,yp,zp); + c2 = dotproduct(x2,y2,z2,xp,yp,zp); d1 = fabs(d1); d2 = fabs(d2); - + /* This is a hack. d$n$ is proportional to the sine of the angle * between point $n$ and point p. That preserves orderedness up * to an angle of 90 degrees. c$n$ is proportional to the cosine * of the same angle; if the angle is over 90 degrees, c$n$ is * negative. In that case, we flop the sine across the y=1 axis - * so that the resulting value increases as the angle increases. - * + * so that the resulting value increases as the angle increases. + * * This only works because all of the points are on a unit sphere. */ - if ( c1 < 0 ) { - d1 = 2 - d1; + if (c1 < 0) { + d1 = 2 - d1; } - if ( c2 < 0 ) { - d2 = 2 - d2; + if (c2 < 0) { + d2 = 2 - d2; } - if ( fabs(d1) < fabs(d2)) { - return gcdist(lat1,lon1,lat3,lon3); - } - else { + if (fabs(d1) < fabs(d2)) { + return gcdist(lat1,lon1,lat3,lon3); + } else { + *prjlat = DEG(lat2); + *prjlon = DEG(lon2); + *frac = 1.0; return gcdist(lat2,lon2,lat3,lon3); } - } - else { + } else { /* lp is 0 when 3 is 90 degrees from the great circle */ return M_PI/2; - } - } - else { + } + } else { /* la is 0 when 1 and 2 are either the same point or 180 degrees apart */ dot = dotproduct(x1,y1,z1,x2,y2,z2); - if ( dot >= 0 ) { + if (dot >= 0) { return gcdist(lat1,lon1,lat3,lon3); - } - else { + } else { return 0; } } return 0; } -/* - * Compute the position of a point partially along the geodesic from + +double linedist(double lat1, double lon1, + double lat2, double lon2, + double lat3, double lon3) +{ + double dummy; + return linedistprj(lat1, lon1, lat2, lon2, lat3, lon3, &dummy, &dummy, &dummy); +} + +/* + * Compute the position of a point partially along the geodesic from * lat1,lon1 to lat2,lon2 - * + * * Ref: http://mathworld.wolfram.com/RotationFormula.html */ void linepart(double lat1, double lon1, - double lat2, double lon2, - double frac, - double *reslat, double *reslon ) { + double lat2, double lon2, + double frac, + double* reslat, double* reslon) +{ double x1,y1,z1; double x2,y2,z2; double xa,ya,za,la; double xr, yr, zr; double xx, yx, zx; - + double theta = 0; double phi = 0; double cosphi = 0; @@ -290,59 +333,76 @@ void linepart(double lat1, double lon1, /* result must be in degrees */ *reslat = lat1; *reslon = lon1; - + /* degrees to radians */ - lat1 = RAD(lat1); lon1 = RAD(lon1); - lat2 = RAD(lat2); lon2 = RAD(lon2); + lat1 = RAD(lat1); + lon1 = RAD(lon1); + lat2 = RAD(lat2); + lon2 = RAD(lon2); /* polar to ECEF rectangular */ - x1 = cos(lon1)*cos(lat1); y1 = sin(lat1); z1 = sin(lon1)*cos(lat1); - x2 = cos(lon2)*cos(lat2); y2 = sin(lat2); z2 = sin(lon2)*cos(lat2); + x1 = cos(lon1)*cos(lat1); + y1 = sin(lat1); + z1 = sin(lon1)*cos(lat1); + x2 = cos(lon2)*cos(lat2); + y2 = sin(lat2); + z2 = sin(lon2)*cos(lat2); /* 'a' is the axis; the line that passes through the center of the earth - * and is perpendicular to the great circle through point 1 and point 2 + * and is perpendicular to the great circle through point 1 and point 2 * It is computed by taking the cross product of the '1' and '2' vectors.*/ - crossproduct( x1, y1, z1, x2, y2, z2, &xa, &ya, &za ); + crossproduct(x1, y1, z1, x2, y2, z2, &xa, &ya, &za); la = sqrt(xa*xa+ya*ya+za*za); - if ( la ) { + if (la) { xa /= la; ya /= la; za /= la; } - /* if la is zero, the points are either equal or directly opposite + /* if la is zero, the points are either equal or directly opposite * each other. Either way, there's no single geodesic, so we punt. */ - if ( la ) { - crossproduct( x1, y1, z1, xa, ya, za, &xx, &yx, &zx ); - - - theta = atan2( dotproduct(xx,yx,zx,x2,y2,z2), - dotproduct(x1,y1,z1,x2,y2,z2)); - + if (la) { + crossproduct(x1, y1, z1, xa, ya, za, &xx, &yx, &zx); + + + theta = atan2(dotproduct(xx,yx,zx,x2,y2,z2), + dotproduct(x1,y1,z1,x2,y2,z2)); + phi = frac * theta; cosphi = cos(phi); sinphi = sin(phi); - - + + /* The second term of the formula from the mathworld reference is always * zero, because r (lat1,lon1) is always perpendicular to n (a here) */ xr = x1*cosphi + xx * sinphi; yr = y1*cosphi + yx * sinphi; zr = z1*cosphi + zx * sinphi; - - if ( xr > 1 ) xr = 1; - if ( xr < -1 ) xr = -1; - if ( yr > 1 ) yr = 1; - if ( yr < -1 ) yr = -1; - if ( zr > 1 ) zr = 1; - if ( zr < -1 ) zr = -1; - + + if (xr > 1) { + xr = 1; + } + if (xr < -1) { + xr = -1; + } + if (yr > 1) { + yr = 1; + } + if (yr < -1) { + yr = -1; + } + if (zr > 1) { + zr = 1; + } + if (zr < -1) { + zr = -1; + } + *reslat = DEG(asin(yr)); - if( xr == 0 && zr == 0 ) { + if (xr == 0 && zr == 0) { *reslon = 0; + } else { + *reslon = DEG(atan2(zr, xr)); } - else { - *reslon = DEG(atan2( zr, xr )); - } } } diff --git a/gpsbabel/grtcirc.h b/gpsbabel/grtcirc.h index c47e77dd4..273657ace 100644 --- a/gpsbabel/grtcirc.h +++ b/gpsbabel/grtcirc.h @@ -18,25 +18,31 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #ifndef GRTCIRC_H #define GRTCIRC_H -double gcdist( double lat1, double lon1, double lat2, double lon2 ); -double heading( double lat1, double lon1, double lat2, double lon2 ); -double heading_true_degrees( double lat1, double lon1, double lat2, double lon2 ); +double gcdist(double lat1, double lon1, double lat2, double lon2); +double heading(double lat1, double lon1, double lat2, double lon2); +double heading_true_degrees(double lat1, double lon1, double lat2, double lon2); + +double linedistprj(double lat1, double lon1, + double lat2, double lon2, + double lat3, double lon3, + double* prjlat, double* prjlon, + double* frac ); double linedist(double lat1, double lon1, - double lat2, double lon2, - double lat3, double lon3 ); + double lat2, double lon2, + double lat3, double lon3); -double radtometers( double rads ); -double radtomiles( double rads ); +double radtometers(double rads); +double radtomiles(double rads); void linepart(double lat1, double lon1, - double lat2, double lon2, - double frac, - double *reslat, double *reslon ); + double lat2, double lon2, + double frac, + double* reslat, double* reslon); /* Degrees to radians */ #define DEG(x) ((x)*180.0/M_PI) diff --git a/gpsbabel/gtm.c b/gpsbabel/gtm.c index a1f7a2a5e..916b2dbf0 100644 --- a/gpsbabel/gtm.c +++ b/gpsbabel/gtm.c @@ -21,7 +21,7 @@ #include "defs.h" #include "jeeps/gpsmath.h" -static gbfile *file_in, *file_out; +static gbfile* file_in, *file_out; static int indatum; static int wp_count; static int ws_count; @@ -29,7 +29,7 @@ static int tr_count; static int ts_count; static int rt_count; static int im_count; -static const route_head *rte_active; +static const route_head* rte_active; static int start_new; #define MYNAME "GTM" @@ -55,11 +55,11 @@ static int start_new; #if 0 /* not used */ static short int -fread_bool(gbfile *fd) +fread_bool(gbfile* fd) { - char buf[2]; - gbfread(buf, 2, 1, fd); - return le_read16(buf) ? 1 : 0; + char buf[2]; + gbfread(buf, 2, 1, fd); + return le_read16(buf) ? 1 : 0; } #endif @@ -68,53 +68,57 @@ fread_bool(gbfile *fd) #define fread_single(a) gbfgetflt(a) #define fread_double(a) gbfgetdbl(a) -static char * -fread_string(gbfile *fd) +static char* +fread_string(gbfile* fd) { - char *val; - int len = fread_integer(fd); - - if (len == 0) return NULL; - - val = xmalloc(len+1); - gbfread(val, 1, len, fd); - while (len != 0 && val[len-1] == ' ') - len--; - val[len] = 0; - return val; + char* val; + int len = fread_integer(fd); + + if (len == 0) { + return NULL; + } + + val = (char*) xmalloc(len+1); + gbfread(val, 1, len, fd); + while (len != 0 && val[len-1] == ' ') { + len--; + } + val[len] = 0; + return val; } static void -fread_string_discard(gbfile *fd) +fread_string_discard(gbfile* fd) { - char *temp = fread_string(fd); + char* temp = fread_string(fd); - if (temp != NULL) { - xfree(temp); - } + if (temp != NULL) { + xfree(temp); + } } -static char * -fread_fixedstring(gbfile *fd, int len) +static char* +fread_fixedstring(gbfile* fd, int len) { - char *val = xmalloc(len+1); - - gbfread(val, 1, len, fd); - while (len != 0 && val[len-1] == ' ') - len--; - val[len] = 0; - return val; + char* val = (char*) xmalloc(len+1); + + gbfread(val, 1, len, fd); + while (len != 0 && val[len-1] == ' ') { + len--; + } + val[len] = 0; + return val; } /* Write functions, according to specification. */ static void -fwrite_null(gbfile *fd, int len) +fwrite_null(gbfile* fd, int len) { - char buf[1024]; + char buf[1024]; - memset(buf, 0, len); - gbfwrite(buf, 1, len, fd); + memset(buf, 0, len); + gbfwrite(buf, 1, len, fd); } #define fwrite_byte(a,b) gbfputc((signed char)(b), a) @@ -125,29 +129,31 @@ fwrite_null(gbfile *fd, int len) #define fwrite_double(a,b) gbfputdbl((b), a) static void -fwrite_string(gbfile *fd, const char *str) +fwrite_string(gbfile* fd, const char* str) { - if (str && str[0]) { - int len = strlen(str); - fwrite_integer(fd, len); - gbfwrite(str, 1, len, fd); - } - else { - fwrite_integer(fd, 0); - } + if (str && str[0]) { + int len = strlen(str); + fwrite_integer(fd, len); + gbfwrite(str, 1, len, fd); + } else { + fwrite_integer(fd, 0); + } } void -fwrite_fixedstring(gbfile *fd, const char *str, int fieldlen) +fwrite_fixedstring(gbfile* fd, const char* str, int fieldlen) { - int len = str ? strlen(str) : 0; - - if (len > fieldlen) - len = fieldlen; - if (str) - gbfwrite(str, 1, len, fd); - for (; len != fieldlen; len++) - gbfputc(' ', fd); + int len = str ? strlen(str) : 0; + + if (len > fieldlen) { + len = fieldlen; + } + if (str) { + gbfwrite(str, 1, len, fd); + } + for (; len != fieldlen; len++) { + gbfputc(' ', fd); + } } /* Auxiliar functions */ @@ -155,535 +161,665 @@ fwrite_fixedstring(gbfile *fd, const char *str, int fieldlen) void set_datum(int n) { - indatum = -1; - if (n < 1) {} - else if (n < 8) { indatum = 0; } /* Adindan */ - else if (n < 9) { indatum = 1; } /* Afgooye */ - else if (n < 10) { indatum = 2; } /* Ain el Abd */ - else if (n < 14) {} - else if (n < 23) { indatum = 6; } /* ARC 1950 */ - else if (n < 26) { indatum = 7; } /* ARC 1960 */ - else if (n < 27) { indatum = 8; } /* Ascension Island 58 */ - else if (n < 32) {} - else if (n < 33) { indatum = 13; } /* Australian Geo 84 */ - else if (n < 34) {} - else if (n < 35) { indatum = 15; } /* Bellevue IGN */ - else if (n < 36) { indatum = 16; } /* Bermuda 1957 */ - else if (n < 38) {} - else if (n < 39) { indatum = 17; } /* Bukit Rimpah */ - else if (n < 40) { indatum = 18; } /* Camp Area Astro */ - else if (n < 41) { indatum = 19; } /* Campo Inchauspe */ - else if (n < 42) { indatum = 22; } /* Canton Islan 1966 */ - else if (n < 43) { indatum = 23; } /* Cape */ - else if (n < 44) { indatum = 24; } /* Cape Canaveral */ - else if (n < 45) { indatum = 26; } /* Carthe */ - else if (n < 46) { indatum = 28; } /* Chatham */ - else if (n < 47) { indatum = 29; } /* Chua Astro */ - else if (n < 48) { indatum = 30; } /* Corrego Alegre*/ - else if (n < 50) {} - else if (n < 51) { indatum = 33; } /* Djakarta (Batavia) */ - else if (n < 52) { indatum = 34; } /* DOS 1968 */ - else if (n < 53) { indatum = 35; } /* Easter Island 1967 */ - else if (n < 54) {} - else if (n < 69) { indatum = 38; } /* European 1950 Mean */ - else if (n < 70) { indatum = 39; } /* European 1979 Mean */ - else if (n < 71) {} - else if (n < 72) { indatum = 41; } /* Gandajika */ - else if (n < 73) { indatum = 42; } /* Geodetic Datum 49 */ - else if (n < 74) {} - else if (n < 75) { indatum = 45; } /* Guam 1963 */ - else if (n < 76) { indatum = 46; } /* Gunung Segara */ - else if (n < 77) {} - else if (n < 78) { indatum = 49; } /* Hearth North */ - else if (n < 79) {} - else if (n < 80) { indatum = 50; } /* Hjorsey 1955 */ - else if (n < 81) { indatum = 51; } /* Hong Kong 1963 */ - else if (n < 82) { indatum = 52; } /* Hu-Tzu-Shan */ - else if (n < 89) { indatum = 53; } /* Indian */ - else if (n < 90) {} - else if (n < 91) { indatum = 55; } /* Ireland 1965 */ - else if (n < 92) {} - else if (n < 93) { indatum = 56; } /* ISTS 073 69 */ - else if (n < 94) { indatum = 57; } /* Johnston Island 61 */ - else if (n < 95) { indatum = 58; } /* Kandawala */ - else if (n < 96) { indatum = 59; } /* Kerguelen Island */ - else if (n < 97) { indatum = 60; } /* Kertau 48 */ - else if (n < 99) {} - else if (n < 100) { indatum = 61; } /* L.C. 5 Astro */ - else if (n < 101) {} - else if (n < 102) { indatum = 63; } /* Liberia 1964 */ - else if (n < 104) { indatum = 64; } /* Luzon */ - else if (n < 105) {} - else if (n < 106) { indatum = 65; } /* Mahe 1971 */ - else if (n < 107) {} - else if (n < 108) { indatum = 69; } /* Merchich */ - else if (n < 109) { indatum = 71; } /* Midway Astro 61 */ - else if (n < 111) { indatum = 73; } /* Minna */ - else if (n < 112) {} - else if (n < 115) { indatum = 75; } /* Nahrwan */ - else if (n < 116) { indatum = 76; } /* Naparima BWI */ - else if (n < 116) {} - else if (n < 119) { indatum = 3; } /* Alaska NAD27 */ - else if (n < 121) { indatum = 14; } /* Bahamas NAD27 */ - else if (n < 126) { indatum = 20; } /* Canada Mean NAD27 */ - else if (n < 127) { indatum = 21; } /* Canal Zone NAD27 */ - else if (n < 128) { indatum = 31; } /* Cuba NAD27 */ - else if (n < 129) { indatum = 44; } /* Greenland NAD27 */ - else if (n < 131) {} - else if (n < 132) { indatum = 20; } /* Canada Mean NAD27 */ - else if (n < 135) {} - else if (n < 136) { indatum = 70; } /* Mexico NAD27 */ - else if (n < 144) {} - else if (n < 145) { indatum = 80; } /* Old Egyptian */ - else if (n < 146) { indatum = 81; } /* Old Hawaiian */ - else if (n < 147) { indatum = 82; } /* Old Hawaiian Kauai */ - else if (n < 148) { indatum = 83; } /* Old Hawaiian Maui */ - else if (n < 149) { indatum = 81; } /* Old Hawaiian Mean */ - else if (n < 150) { indatum = 84; } /* Old Hawaiian Oahu */ - else if (n < 151) { indatum = 85; } /* Oman */ - else if (n < 156) { indatum = 86; } /* OSG Britain */ - else if (n < 157) { indatum = 87; } /* Pico de Las Nieves */ - else if (n < 158) { indatum = 88; } /* Pitcairn Astro 67 */ - else if (n < 171) {} - else if (n < 172) { indatum = 91; } /* Puerto Rico */ - else if (n < 173) { indatum = 92; } /* Pulkovo 1942 */ - else if (n < 174) { indatum = 94; } /* Quatar National */ - else if (n < 176) {} - else if (n < 177) { indatum = 95; } /* Rome 1940 */ - else if (n < 184) { indatum = 96; } /* S-42 (Pulkovo 1942) */ - else if (n < 185) {} - else if (n < 186) { indatum = 100; } /* Santo DOS */ - else if (n < 187) { indatum = 99; } /* Sao Braz */ - else if (n < 191) {} - else if (n < 193) { indatum = 105; } /* SAD-69/Mean */ - else if (n < 194) { indatum = 98; } /* SAD-69/Brazil */ - else if (n < 204) { indatum = 105; } /* SAD-69/Mean */ - else if (n < 205) { indatum = 106; } /* South Asia */ - else if (n < 206) { indatum = 109; } /* Tananarive 1926 */ - else if (n < 207) { indatum = 111; } /* Timbalai 1948 */ - else if (n < 211) { indatum = 112; } /* Tokyo mean */ - else if (n < 212) { indatum = 113; } /* Tristan Astro 1968 */ - else if (n < 213) { indatum = 115; } /* Viti Levu 1916 */ - else if (n < 215) {} - else if (n < 216) { indatum = 116; } /* Wake Eniwetok 1960 */ - else if (n < 217) { indatum = 117; } /* WGS 72 */ - else if (n < 218) { indatum = 118; } /* WGS 84 */ - else if (n < 219) { indatum = 119; } /* Yacare */ - else if (n < 220) { indatum = 120; } /* Zanderij */ - else if (n < 231) {} - else if (n < 232) { indatum = 98; } /* SAD-69/Brazil*/ - else if (n < 234) {} - else if (n < 235) { indatum = 117; } /* WGS 72 */ - else if (n < 236) { indatum = 0; } /* Adindan */ - else if (n < 237) { indatum = 2; } /* Ain el Abd */ - else if (n < 238) { indatum = 7; } /* ARC 1960 */ - else if (n < 239) { indatum = 8; } /* Ascension Island 58 */ - else if (n < 241) {} - else if (n < 242) { indatum = 52; } /* Hu-Tzu-Shan */ - else if (n < 245) { indatum = 53; } /* Indian */ - else if (n < 246) {} - else if (n < 247) { indatum = 57; } /* Johnston Island 61 */ - else if (n < 248) { indatum = 64; } /* Luzon */ - else if (n < 249) {} - else if (n < 250) { indatum = 75; } /* Nahrwan */ - else if (n < 251) { indatum = 76; } /* Naparima BWI */ - else if (n < 254) {} - else if (n < 255) { indatum = 82; } /* Old Hawaiian Kauai */ - else if (n < 256) { indatum = 83; } /* Old Hawaiian Maui */ - else if (n < 257) { indatum = 84; } /* Old Hawaiian Oahu */ - else if (n < 259) {} - else if (n < 260) { indatum = 101; } /* Sapper Hill 43 */ - else if (n < 261) { indatum = 111; } /* Timbalai 1948 */ - else if (n < 262) { indatum = 112; } /* Tokyo mean */ - else if (n < 263) { indatum = 116; } /* Wake Eniwetok 1960 */ - - if (indatum == -1) - warning(MYNAME ": Unsupported datum (%d), won't convert to WGS84\n", n); + indatum = -1; + if (n < 1) {} + else if (n < 8) { + indatum = 0; /* Adindan */ + } else if (n < 9) { + indatum = 1; /* Afgooye */ + } else if (n < 10) { + indatum = 2; /* Ain el Abd */ + } else if (n < 14) {} + else if (n < 23) { + indatum = 6; /* ARC 1950 */ + } else if (n < 26) { + indatum = 7; /* ARC 1960 */ + } else if (n < 27) { + indatum = 8; /* Ascension Island 58 */ + } else if (n < 32) {} + else if (n < 33) { + indatum = 13; /* Australian Geo 84 */ + } else if (n < 34) {} + else if (n < 35) { + indatum = 15; /* Bellevue IGN */ + } else if (n < 36) { + indatum = 16; /* Bermuda 1957 */ + } else if (n < 38) {} + else if (n < 39) { + indatum = 17; /* Bukit Rimpah */ + } else if (n < 40) { + indatum = 18; /* Camp Area Astro */ + } else if (n < 41) { + indatum = 19; /* Campo Inchauspe */ + } else if (n < 42) { + indatum = 22; /* Canton Islan 1966 */ + } else if (n < 43) { + indatum = 23; /* Cape */ + } else if (n < 44) { + indatum = 24; /* Cape Canaveral */ + } else if (n < 45) { + indatum = 26; /* Carthe */ + } else if (n < 46) { + indatum = 28; /* Chatham */ + } else if (n < 47) { + indatum = 29; /* Chua Astro */ + } else if (n < 48) { + indatum = 30; /* Corrego Alegre*/ + } else if (n < 50) {} + else if (n < 51) { + indatum = 33; /* Djakarta (Batavia) */ + } else if (n < 52) { + indatum = 34; /* DOS 1968 */ + } else if (n < 53) { + indatum = 35; /* Easter Island 1967 */ + } else if (n < 54) {} + else if (n < 69) { + indatum = 38; /* European 1950 Mean */ + } else if (n < 70) { + indatum = 39; /* European 1979 Mean */ + } else if (n < 71) {} + else if (n < 72) { + indatum = 41; /* Gandajika */ + } else if (n < 73) { + indatum = 42; /* Geodetic Datum 49 */ + } else if (n < 74) {} + else if (n < 75) { + indatum = 45; /* Guam 1963 */ + } else if (n < 76) { + indatum = 46; /* Gunung Segara */ + } else if (n < 77) {} + else if (n < 78) { + indatum = 49; /* Hearth North */ + } else if (n < 79) {} + else if (n < 80) { + indatum = 50; /* Hjorsey 1955 */ + } else if (n < 81) { + indatum = 51; /* Hong Kong 1963 */ + } else if (n < 82) { + indatum = 52; /* Hu-Tzu-Shan */ + } else if (n < 89) { + indatum = 53; /* Indian */ + } else if (n < 90) {} + else if (n < 91) { + indatum = 55; /* Ireland 1965 */ + } else if (n < 92) {} + else if (n < 93) { + indatum = 56; /* ISTS 073 69 */ + } else if (n < 94) { + indatum = 57; /* Johnston Island 61 */ + } else if (n < 95) { + indatum = 58; /* Kandawala */ + } else if (n < 96) { + indatum = 59; /* Kerguelen Island */ + } else if (n < 97) { + indatum = 60; /* Kertau 48 */ + } else if (n < 99) {} + else if (n < 100) { + indatum = 61; /* L.C. 5 Astro */ + } else if (n < 101) {} + else if (n < 102) { + indatum = 63; /* Liberia 1964 */ + } else if (n < 104) { + indatum = 64; /* Luzon */ + } else if (n < 105) {} + else if (n < 106) { + indatum = 65; /* Mahe 1971 */ + } else if (n < 107) {} + else if (n < 108) { + indatum = 69; /* Merchich */ + } else if (n < 109) { + indatum = 71; /* Midway Astro 61 */ + } else if (n < 111) { + indatum = 73; /* Minna */ + } else if (n < 112) {} + else if (n < 115) { + indatum = 75; /* Nahrwan */ + } else if (n < 116) { + indatum = 76; /* Naparima BWI */ + } else if (n < 116) {} + else if (n < 119) { + indatum = 3; /* Alaska NAD27 */ + } else if (n < 121) { + indatum = 14; /* Bahamas NAD27 */ + } else if (n < 126) { + indatum = 20; /* Canada Mean NAD27 */ + } else if (n < 127) { + indatum = 21; /* Canal Zone NAD27 */ + } else if (n < 128) { + indatum = 31; /* Cuba NAD27 */ + } else if (n < 129) { + indatum = 44; /* Greenland NAD27 */ + } else if (n < 131) {} + else if (n < 132) { + indatum = 20; /* Canada Mean NAD27 */ + } else if (n < 135) {} + else if (n < 136) { + indatum = 70; /* Mexico NAD27 */ + } else if (n < 144) {} + else if (n < 145) { + indatum = 80; /* Old Egyptian */ + } else if (n < 146) { + indatum = 81; /* Old Hawaiian */ + } else if (n < 147) { + indatum = 82; /* Old Hawaiian Kauai */ + } else if (n < 148) { + indatum = 83; /* Old Hawaiian Maui */ + } else if (n < 149) { + indatum = 81; /* Old Hawaiian Mean */ + } else if (n < 150) { + indatum = 84; /* Old Hawaiian Oahu */ + } else if (n < 151) { + indatum = 85; /* Oman */ + } else if (n < 156) { + indatum = 86; /* OSG Britain */ + } else if (n < 157) { + indatum = 87; /* Pico de Las Nieves */ + } else if (n < 158) { + indatum = 88; /* Pitcairn Astro 67 */ + } else if (n < 171) {} + else if (n < 172) { + indatum = 91; /* Puerto Rico */ + } else if (n < 173) { + indatum = 92; /* Pulkovo 1942 */ + } else if (n < 174) { + indatum = 94; /* Quatar National */ + } else if (n < 176) {} + else if (n < 177) { + indatum = 95; /* Rome 1940 */ + } else if (n < 184) { + indatum = 96; /* S-42 (Pulkovo 1942) */ + } else if (n < 185) {} + else if (n < 186) { + indatum = 100; /* Santo DOS */ + } else if (n < 187) { + indatum = 99; /* Sao Braz */ + } else if (n < 191) {} + else if (n < 193) { + indatum = 105; /* SAD-69/Mean */ + } else if (n < 194) { + indatum = 98; /* SAD-69/Brazil */ + } else if (n < 204) { + indatum = 105; /* SAD-69/Mean */ + } else if (n < 205) { + indatum = 106; /* South Asia */ + } else if (n < 206) { + indatum = 109; /* Tananarive 1926 */ + } else if (n < 207) { + indatum = 111; /* Timbalai 1948 */ + } else if (n < 211) { + indatum = 112; /* Tokyo mean */ + } else if (n < 212) { + indatum = 113; /* Tristan Astro 1968 */ + } else if (n < 213) { + indatum = 115; /* Viti Levu 1916 */ + } else if (n < 215) {} + else if (n < 216) { + indatum = 116; /* Wake Eniwetok 1960 */ + } else if (n < 217) { + indatum = 117; /* WGS 72 */ + } else if (n < 218) { + indatum = 118; /* WGS 84 */ + } else if (n < 219) { + indatum = 119; /* Yacare */ + } else if (n < 220) { + indatum = 120; /* Zanderij */ + } else if (n < 231) {} + else if (n < 232) { + indatum = 98; /* SAD-69/Brazil*/ + } else if (n < 234) {} + else if (n < 235) { + indatum = 117; /* WGS 72 */ + } else if (n < 236) { + indatum = 0; /* Adindan */ + } else if (n < 237) { + indatum = 2; /* Ain el Abd */ + } else if (n < 238) { + indatum = 7; /* ARC 1960 */ + } else if (n < 239) { + indatum = 8; /* Ascension Island 58 */ + } else if (n < 241) {} + else if (n < 242) { + indatum = 52; /* Hu-Tzu-Shan */ + } else if (n < 245) { + indatum = 53; /* Indian */ + } else if (n < 246) {} + else if (n < 247) { + indatum = 57; /* Johnston Island 61 */ + } else if (n < 248) { + indatum = 64; /* Luzon */ + } else if (n < 249) {} + else if (n < 250) { + indatum = 75; /* Nahrwan */ + } else if (n < 251) { + indatum = 76; /* Naparima BWI */ + } else if (n < 254) {} + else if (n < 255) { + indatum = 82; /* Old Hawaiian Kauai */ + } else if (n < 256) { + indatum = 83; /* Old Hawaiian Maui */ + } else if (n < 257) { + indatum = 84; /* Old Hawaiian Oahu */ + } else if (n < 259) {} + else if (n < 260) { + indatum = 101; /* Sapper Hill 43 */ + } else if (n < 261) { + indatum = 111; /* Timbalai 1948 */ + } else if (n < 262) { + indatum = 112; /* Tokyo mean */ + } else if (n < 263) { + indatum = 116; /* Wake Eniwetok 1960 */ + } + + if (indatum == -1) { + warning(MYNAME ": Unsupported datum (%d), won't convert to WGS84\n", n); + } } -static const char *icon_descr[] = { -"", "Airport", "Ball Park", "Bank", "Bar", "Boat Ramp", "Campground", "Car", -"City (Large)", "City (Medium)", "City (Small)", "Dam", "Danger Area", -"Drinking Water", "Fishing Area", "Gas Station", "Glider Area", "Golf Course", -"Heliport", "Hotel", "Animals", "Information", "Man Overboard", "Marina", -"Mine", "Medical Facility", "Parachute Area", "Park", "Parking Area", -"Picnic Area", "Private Field", "Residence", "Restaurant", "Restroom", -"Scenic Area", "School", "Seaplane Base", "Shipwreck", "Shopping Center", -"Short Tower", "Policy Station", "Ski Resort", "Soft Field", "Swimming Area", -"Tall Tower", "Telephone", "Tracback Point", "Ultralight Area", "Waypoint", -"Boat", "Exit", "Flag", "Duck", "Buoy", "Back Track", "Beach", "Bridge", -"Building", "Car Repair", "Cemetery", "Church", "Civil", "Convenience Store", -"Crossing", "Fast Food", "Forest", "Ghost Town", "Levee", "Military", -"Oil Field", "Post Office", "Rv Park", "Scales", "Summit", "Toll Booth", -"Trail Head", "Truck Stop", "Tunnel", "Highway", "Gate", "Fall", "Fence", -"Mata-Burro", "Fitness Center", "Movie Theater", "Live Theater", "Zoo", "Horn", -"Bowling", "Car Rental", "City (Capitol)", "Controlled Area", "Stadium", -"Museum", "Amusement Park", "Skull", "Department Store", "Pharmacy", "Pizza", -"Diver Down Flag 1", "Light", "Pin", "", "Pigsty", "Tree", "Bamboo", -"Banana Plant", "Arrow-Down", "Bifurcation", "Cavern", "River", "Rock", -"Arrow-Up", "Trunk", "Soccer Field", "Sporting Court", "Flag, Green", "Trench", -"Ship-Yellow", "Green Sign", "Swamp", "Lake", "Stop!", -"Fishing Hot Spot Facility", "Speed Reducer", "Stairway", "Cactus", "Ship-Red", -"Letter - S", "Letter - D", "Letter - N", -"Crossing", "Cross", "Flag, Red", "Curve1", "Curve2", "Curve3", "Curve4", -"Letter - W", "Letter - L", "Letter - R", "Radio Beacon", "Road Sign", -"Geocache", "Geocache Found", "Traffic Light", "Bus Station", "Train Station", -"School", "Mile Marker", "Conservation Area", "Waypoint", "Box", "Aerial", -"Auto Repair", "Boat", "Exit Ramp", "Fixed Nav Aid", "Floating Buoy", "Garden", -"Fish Farm", "Lighthouse", "Truck Service", "Resort", "Scuba", "Shooting", -"Sight Seeing", "Sounding", "Winery", "Navaid, Amber", "Navaid, Black", -"Navaid, Blue", "Navaid, Green", "Navaid, Green/Red", "Navaid, Green/White", -"Navaid, Orange", "Navaid, Red", "Navaid, Red/Green", "Navaid, Red/White", -"Navaid, Violet", "Navaid, White", "Navaid, White/Green", "Navaid, White/Red", -"Buoy, White", "Dot, White", "Red Square", "Red Diamond", "Green Square", -"Green Diamond", "Restricted Area", "Navaid (unlit)", "Dot (Small)", "Libraries", "Waypoint", "Waypoint1", -"Waypoint2", "Mark (1)", "Mark (2)", "Mark (3)", "Cross (Red)", "Store", -"Exclamation", "Flag (EUA)", "Flag (CAN)", "Flag (BRA)", "Man", "Animals", -"Deer Tracks", "Tree Stand", "Bridge", "Fence", "Intersection", -"Non Direct Beacon", "VHF Omni Range", "Vor/Tacan", "Vor-Dme", -"1st Approach Fix", "Localizer Outer", "Missed Appr. Pt", "Tacan", -"CheckPoint", NULL +static const char* icon_descr[] = { + "", "Airport", "Ball Park", "Bank", "Bar", "Boat Ramp", "Campground", "Car", + "City (Large)", "City (Medium)", "City (Small)", "Dam", "Danger Area", + "Drinking Water", "Fishing Area", "Gas Station", "Glider Area", "Golf Course", + "Heliport", "Hotel", "Animals", "Information", "Man Overboard", "Marina", + "Mine", "Medical Facility", "Parachute Area", "Park", "Parking Area", + "Picnic Area", "Private Field", "Residence", "Restaurant", "Restroom", + "Scenic Area", "School", "Seaplane Base", "Shipwreck", "Shopping Center", + "Short Tower", "Policy Station", "Ski Resort", "Soft Field", "Swimming Area", + "Tall Tower", "Telephone", "Tracback Point", "Ultralight Area", "Waypoint", + "Boat", "Exit", "Flag", "Duck", "Buoy", "Back Track", "Beach", "Bridge", + "Building", "Car Repair", "Cemetery", "Church", "Civil", "Convenience Store", + "Crossing", "Fast Food", "Forest", "Ghost Town", "Levee", "Military", + "Oil Field", "Post Office", "Rv Park", "Scales", "Summit", "Toll Booth", + "Trail Head", "Truck Stop", "Tunnel", "Highway", "Gate", "Fall", "Fence", + "Mata-Burro", "Fitness Center", "Movie Theater", "Live Theater", "Zoo", "Horn", + "Bowling", "Car Rental", "City (Capitol)", "Controlled Area", "Stadium", + "Museum", "Amusement Park", "Skull", "Department Store", "Pharmacy", "Pizza", + "Diver Down Flag 1", "Light", "Pin", "", "Pigsty", "Tree", "Bamboo", + "Banana Plant", "Arrow-Down", "Bifurcation", "Cavern", "River", "Rock", + "Arrow-Up", "Trunk", "Soccer Field", "Sporting Court", "Flag, Green", "Trench", + "Ship-Yellow", "Green Sign", "Swamp", "Lake", "Stop!", + "Fishing Hot Spot Facility", "Speed Reducer", "Stairway", "Cactus", "Ship-Red", + "Letter - S", "Letter - D", "Letter - N", + "Crossing", "Cross", "Flag, Red", "Curve1", "Curve2", "Curve3", "Curve4", + "Letter - W", "Letter - L", "Letter - R", "Radio Beacon", "Road Sign", + "Geocache", "Geocache Found", "Traffic Light", "Bus Station", "Train Station", + "School", "Mile Marker", "Conservation Area", "Waypoint", "Box", "Aerial", + "Auto Repair", "Boat", "Exit Ramp", "Fixed Nav Aid", "Floating Buoy", "Garden", + "Fish Farm", "Lighthouse", "Truck Service", "Resort", "Scuba", "Shooting", + "Sight Seeing", "Sounding", "Winery", "Navaid, Amber", "Navaid, Black", + "Navaid, Blue", "Navaid, Green", "Navaid, Green/Red", "Navaid, Green/White", + "Navaid, Orange", "Navaid, Red", "Navaid, Red/Green", "Navaid, Red/White", + "Navaid, Violet", "Navaid, White", "Navaid, White/Green", "Navaid, White/Red", + "Buoy, White", "Dot, White", "Red Square", "Red Diamond", "Green Square", + "Green Diamond", "Restricted Area", "Navaid (unlit)", "Dot (Small)", "Libraries", "Waypoint", "Waypoint1", + "Waypoint2", "Mark (1)", "Mark (2)", "Mark (3)", "Cross (Red)", "Store", + "Exclamation", "Flag (EUA)", "Flag (CAN)", "Flag (BRA)", "Man", "Animals", + "Deer Tracks", "Tree Stand", "Bridge", "Fence", "Intersection", + "Non Direct Beacon", "VHF Omni Range", "Vor/Tacan", "Vor-Dme", + "1st Approach Fix", "Localizer Outer", "Missed Appr. Pt", "Tacan", + "CheckPoint", NULL }; -void convert_datum(double *lat, double *lon) +void convert_datum(double* lat, double* lon) { - double amt; - if (indatum != -1 && indatum != 118) { - GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, - lat, lon, &amt, indatum); - } + double amt; + if (indatum != -1 && indatum != 118) { + GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, + lat, lon, &amt, indatum); + } } /* Callbacks */ static void -gtm_rd_init(const char *fname) +gtm_rd_init(const char* fname) { - int version; - char *name; - file_in = gbfopen_le(fname, "rb", MYNAME); - version = fread_integer(file_in); - name = fread_fixedstring(file_in, 10); - if (version == -29921) - fatal(MYNAME ": Uncompress the file first\n"); - if (strcmp(name, "TrackMaker") != 0) - fatal(MYNAME ": Invalid file format\n"); - if (version != 211) - fatal(MYNAME ": Invalid format version\n"); - xfree(name); - - /* Header */ - fread_discard(file_in, 15); - ws_count = fread_long(file_in); - fread_discard(file_in, 4); - wp_count = fread_long(file_in); - tr_count = fread_long(file_in); - rt_count = fread_long(file_in); - fread_discard(file_in, 16); - im_count = fread_long(file_in); - ts_count = fread_long(file_in); - fread_discard(file_in, 28); - fread_string_discard(file_in); - fread_string_discard(file_in); - fread_string_discard(file_in); - fread_string_discard(file_in); - - /* User Grid and Datum */ - fread_discard(file_in, 34); - set_datum(fread_integer(file_in)); - fread_discard(file_in, 22); + int version; + char* name; + file_in = gbfopen_le(fname, "rb", MYNAME); + version = fread_integer(file_in); + name = fread_fixedstring(file_in, 10); + if (version == -29921) { + fatal(MYNAME ": Uncompress the file first\n"); + } + if (strcmp(name, "TrackMaker") != 0) { + fatal(MYNAME ": Invalid file format\n"); + } + if (version != 211) { + fatal(MYNAME ": Invalid format version\n"); + } + xfree(name); + + /* Header */ + fread_discard(file_in, 15); + ws_count = fread_long(file_in); + fread_discard(file_in, 4); + wp_count = fread_long(file_in); + tr_count = fread_long(file_in); + rt_count = fread_long(file_in); + fread_discard(file_in, 16); + im_count = fread_long(file_in); + ts_count = fread_long(file_in); + fread_discard(file_in, 28); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_string_discard(file_in); + + /* User Grid and Datum */ + fread_discard(file_in, 34); + set_datum(fread_integer(file_in)); + fread_discard(file_in, 22); } -static void -gtm_rd_deinit(void) +static void +gtm_rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } -static void count_route_waypts(const waypoint *wpt) { rt_count++; } -static void count_track_waypts(const waypoint *wpt) { tr_count++; } +static void count_route_waypts(const waypoint* wpt) +{ + rt_count++; +} +static void count_track_waypts(const waypoint* wpt) +{ + tr_count++; +} static void -gtm_wr_init(const char *fname) +gtm_wr_init(const char* fname) { - rt_count = tr_count = 0; - track_disp_all(NULL, NULL, count_track_waypts); - route_disp_all(NULL, NULL, count_route_waypts); - - file_out = gbfopen_le(fname, "wb", MYNAME); /* little endian */ - - /* Header */ - fwrite_integer(file_out, 211); - fwrite_fixedstring(file_out, "TrackMaker", 10); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 8); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_long(file_out, 0); - fwrite_long(file_out, 16777215); - fwrite_long(file_out, waypt_count() ? 4 : 0); /* num waypoint styles */ - fwrite_long(file_out, 0); - fwrite_long(file_out, waypt_count()); /* num waypoints */ - fwrite_long(file_out, tr_count); - fwrite_long(file_out, rt_count); - fwrite_single(file_out, 0); /* maxlon */ - fwrite_single(file_out, 0); /* minlon */ - fwrite_single(file_out, 0); /* maxlat */ - fwrite_single(file_out, 0); /* minlat */ - fwrite_long(file_out, 0); - fwrite_long(file_out, track_count()); /* num tracklog styles */ - fwrite_single(file_out, 0); - fwrite_single(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_string(file_out, "Times New Roman"); - fwrite_string(file_out, ""); - fwrite_string(file_out, ""); - fwrite_string(file_out, ""); - - /* User Grid and Datum */ - fwrite_null(file_out, 34); - fwrite_integer(file_out, 217); /* WGS84 */ - fwrite_null(file_out, 22); + rt_count = tr_count = 0; + track_disp_all(NULL, NULL, count_track_waypts); + route_disp_all(NULL, NULL, count_route_waypts); + + file_out = gbfopen_le(fname, "wb", MYNAME); /* little endian */ + + /* Header */ + fwrite_integer(file_out, 211); + fwrite_fixedstring(file_out, "TrackMaker", 10); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 8); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_long(file_out, 0); + fwrite_long(file_out, 16777215); + fwrite_long(file_out, waypt_count() ? 4 : 0); /* num waypoint styles */ + fwrite_long(file_out, 0); + fwrite_long(file_out, waypt_count()); /* num waypoints */ + fwrite_long(file_out, tr_count); + fwrite_long(file_out, rt_count); + fwrite_single(file_out, 0); /* maxlon */ + fwrite_single(file_out, 0); /* minlon */ + fwrite_single(file_out, 0); /* maxlat */ + fwrite_single(file_out, 0); /* minlat */ + fwrite_long(file_out, 0); + fwrite_long(file_out, track_count()); /* num tracklog styles */ + fwrite_single(file_out, 0); + fwrite_single(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_string(file_out, "Times New Roman"); + fwrite_string(file_out, ""); + fwrite_string(file_out, ""); + fwrite_string(file_out, ""); + + /* User Grid and Datum */ + fwrite_null(file_out, 34); + fwrite_integer(file_out, 217); /* WGS84 */ + fwrite_null(file_out, 22); } static void gtm_wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } static void gtm_read(void) { - route_head *first_trk_head = NULL; - route_head *trk_head = NULL; - route_head *rte_head = NULL; - waypoint *wpt; - int real_tr_count = 0; - char *route_name; - unsigned int icon; - int i; - - /* Image information */ - for (i = 0; i != im_count; i++) { - fread_string_discard(file_in); - fread_string_discard(file_in); - fread_discard(file_in, 30); - } - - /* Waypoints */ - for (i = 0; i != wp_count; i++) { - wpt = waypt_new(); - wpt->latitude = fread_double(file_in); - wpt->longitude = fread_double(file_in); - convert_datum(&wpt->latitude, &wpt->longitude); - wpt->shortname = fread_fixedstring(file_in, 10); - wpt->description = fread_string(file_in); - icon = fread_integer(file_in); - if (icon < sizeof(icon_descr)/sizeof(char*)) - wpt->icon_descr = icon_descr[icon]; - fread_discard(file_in, 1); - wpt->creation_time = fread_long(file_in); - if (wpt->creation_time) - wpt->creation_time += EPOCH89DIFF; - fread_discard(file_in, 2); - wpt->altitude = fread_single(file_in); - if (wpt->altitude == unknown_alt_gtm) - wpt->altitude = unknown_alt; - fread_discard(file_in, 2); - waypt_add(wpt); - } - - /* Waypoint Styles */ - if (wp_count) { - for (i = 0; i != ws_count; i++) { - fread_discard(file_in, 4); - fread_string_discard(file_in); - fread_discard(file_in, 24); - } - } - - /* Tracklogs */ - for (i = 0; i != tr_count; i++) { - wpt = waypt_new(); - wpt->latitude = fread_double(file_in); - wpt->longitude = fread_double(file_in); - convert_datum(&wpt->latitude, &wpt->longitude); - wpt->creation_time = fread_long(file_in); - if (wpt->creation_time) - wpt->creation_time += EPOCH89DIFF; - start_new = fread_byte(file_in); - wpt->altitude = fread_single(file_in); - if (wpt->altitude == unknown_alt_gtm) - wpt->altitude = unknown_alt; - if (start_new || !trk_head) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - real_tr_count++; - if (!first_trk_head) - first_trk_head = trk_head; - } - track_add_wpt(trk_head, wpt); - } - - /* Tracklog styles */ - trk_head = first_trk_head; - for (i = 0; i != ts_count && i != real_tr_count; i++) { - trk_head->rte_name = fread_string(file_in); - fread_discard(file_in, 12); - trk_head = (route_head *)QUEUE_NEXT(&trk_head->Q); - } - - /* Routes */ - for (i = 0; i != rt_count; i++) { - wpt = waypt_new(); - wpt->latitude = fread_double(file_in); - wpt->longitude = fread_double(file_in); - convert_datum(&wpt->latitude, &wpt->longitude); - wpt->shortname = fread_fixedstring(file_in, 10); - wpt->description = fread_string(file_in); - route_name = fread_string(file_in); - icon = fread_integer(file_in); - if (icon < sizeof(icon_descr)/sizeof(char*)) - wpt->icon_descr = icon_descr[icon]; - fread_discard(file_in, 1); - start_new = fread_byte(file_in); - fread_discard(file_in, 6); - wpt->altitude = fread_single(file_in); - if (wpt->altitude == unknown_alt_gtm) - wpt->altitude = unknown_alt; - fread_discard(file_in, 2); - - if (start_new || !rte_head) { - rte_head = route_head_alloc(); - rte_head->rte_name = route_name; - route_add_head(rte_head); - } - else { - xfree(route_name); - } - route_add_wpt(rte_head, wpt); - } + route_head* first_trk_head = NULL; + route_head* trk_head = NULL; + route_head* rte_head = NULL; + waypoint* wpt; + int real_tr_count = 0; + char* route_name; + unsigned int icon; + int i; + + /* Image information */ + for (i = 0; i != im_count; i++) { + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_discard(file_in, 30); + } + + /* Waypoints */ + for (i = 0; i != wp_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->shortname = fread_fixedstring(file_in, 10); + wpt->description = fread_string(file_in); + icon = fread_integer(file_in); + if (icon < sizeof(icon_descr)/sizeof(char*)) { + wpt->icon_descr = icon_descr[icon]; + } + fread_discard(file_in, 1); + wpt->creation_time = fread_long(file_in); + if (wpt->creation_time) { + wpt->creation_time += EPOCH89DIFF; + } + fread_discard(file_in, 2); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) { + wpt->altitude = unknown_alt; + } + fread_discard(file_in, 2); + waypt_add(wpt); + } + + /* Waypoint Styles */ + if (wp_count) { + for (i = 0; i != ws_count; i++) { + fread_discard(file_in, 4); + fread_string_discard(file_in); + fread_discard(file_in, 24); + } + } + + /* Tracklogs */ + for (i = 0; i != tr_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->creation_time = fread_long(file_in); + if (wpt->creation_time) { + wpt->creation_time += EPOCH89DIFF; + } + start_new = fread_byte(file_in); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) { + wpt->altitude = unknown_alt; + } + if (start_new || !trk_head) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + real_tr_count++; + if (!first_trk_head) { + first_trk_head = trk_head; + } + } + track_add_wpt(trk_head, wpt); + } + + /* Tracklog styles */ + trk_head = first_trk_head; + for (i = 0; i != ts_count && i != real_tr_count; i++) { + trk_head->rte_name = fread_string(file_in); + fread_discard(file_in, 12); + trk_head = (route_head*)QUEUE_NEXT(&trk_head->Q); + } + + /* Routes */ + for (i = 0; i != rt_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->shortname = fread_fixedstring(file_in, 10); + wpt->description = fread_string(file_in); + route_name = fread_string(file_in); + icon = fread_integer(file_in); + if (icon < sizeof(icon_descr)/sizeof(char*)) { + wpt->icon_descr = icon_descr[icon]; + } + fread_discard(file_in, 1); + start_new = fread_byte(file_in); + fread_discard(file_in, 6); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) { + wpt->altitude = unknown_alt; + } + fread_discard(file_in, 2); + + if (start_new || !rte_head) { + rte_head = route_head_alloc(); + rte_head->rte_name = route_name; + route_add_head(rte_head); + } else { + xfree(route_name); + } + route_add_wpt(rte_head, wpt); + } } -int icon_from_descr(const char *descr) +int icon_from_descr(const char* descr) { - if (descr) { - int i; - for (i = 0; icon_descr[i]; i++) - if (strcmp(icon_descr[i], descr) == 0) - return i; - } - return 48; + if (descr) { + int i; + for (i = 0; icon_descr[i]; i++) + if (strcmp(icon_descr[i], descr) == 0) { + return i; + } + } + return 48; } -static void write_waypt(const waypoint *wpt) +static void write_waypt(const waypoint* wpt) { - fwrite_double(file_out, wpt->latitude); - fwrite_double(file_out, wpt->longitude); - fwrite_fixedstring(file_out, wpt->shortname, 10); - fwrite_string(file_out, wpt->description); - fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); - fwrite_byte(file_out, 3); - if (wpt->creation_time) - fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); - else - fwrite_long(file_out, 0); - fwrite_integer(file_out, 0); - if (wpt->altitude == unknown_alt) - fwrite_single(file_out, unknown_alt_gtm); - else - fwrite_single(file_out, wpt->altitude); - fwrite_integer(file_out, 0); + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_fixedstring(file_out, wpt->shortname, 10); + fwrite_string(file_out, wpt->description); + fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); + fwrite_byte(file_out, 3); + if (wpt->creation_time) { + fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); + } else { + fwrite_long(file_out, 0); + } + fwrite_integer(file_out, 0); + if (wpt->altitude == unknown_alt) { + fwrite_single(file_out, unknown_alt_gtm); + } else { + fwrite_single(file_out, wpt->altitude); + } + fwrite_integer(file_out, 0); } -static void start_rte(const route_head *rte) +static void start_rte(const route_head* rte) { - rte_active = rte; - start_new = 1; + rte_active = rte; + start_new = 1; } -static void write_trk_waypt(const waypoint *wpt) +static void write_trk_waypt(const waypoint* wpt) { - fwrite_double(file_out, wpt->latitude); - fwrite_double(file_out, wpt->longitude); - fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); - fwrite_byte(file_out, start_new); - if (wpt->altitude == unknown_alt) - fwrite_single(file_out, unknown_alt_gtm); - else - fwrite_single(file_out, wpt->altitude); - start_new = 0; + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); + fwrite_byte(file_out, start_new); + if (wpt->altitude == unknown_alt) { + fwrite_single(file_out, unknown_alt_gtm); + } else { + fwrite_single(file_out, wpt->altitude); + } + start_new = 0; } -static void write_trk_style(const route_head *trk) +static void write_trk_style(const route_head* trk) { - fwrite_string(file_out, trk->rte_name); - fwrite_byte(file_out, 1); - fwrite_long(file_out, 0); - fwrite_single(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_integer(file_out, 0); + fwrite_string(file_out, trk->rte_name); + fwrite_byte(file_out, 1); + fwrite_long(file_out, 0); + fwrite_single(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_integer(file_out, 0); } -static void write_rte_waypt(const waypoint *wpt) +static void write_rte_waypt(const waypoint* wpt) { - fwrite_double(file_out, wpt->latitude); - fwrite_double(file_out, wpt->longitude); - fwrite_fixedstring(file_out, wpt->shortname, 10); - fwrite_string(file_out, wpt->description); - fwrite_string(file_out, rte_active->rte_name); - fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); - fwrite_byte(file_out, 3); - fwrite_byte(file_out, start_new); - fwrite_long(file_out, 0); - fwrite_integer(file_out, 0); - if (wpt->altitude == unknown_alt) - fwrite_single(file_out, unknown_alt_gtm); - else - fwrite_single(file_out, wpt->altitude); - fwrite_integer(file_out, 0); - start_new = 0; + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_fixedstring(file_out, wpt->shortname, 10); + fwrite_string(file_out, wpt->description); + fwrite_string(file_out, rte_active->rte_name); + fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); + fwrite_byte(file_out, 3); + fwrite_byte(file_out, start_new); + fwrite_long(file_out, 0); + fwrite_integer(file_out, 0); + if (wpt->altitude == unknown_alt) { + fwrite_single(file_out, unknown_alt_gtm); + } else { + fwrite_single(file_out, wpt->altitude); + } + fwrite_integer(file_out, 0); + start_new = 0; } static void gtm_write(void) { - waypt_disp_all(write_waypt); - if (waypt_count()) - gbfwrite(WAYPOINTSTYLES, 1, sizeof(WAYPOINTSTYLES)-1, file_out); - track_disp_all(start_rte, NULL, write_trk_waypt); - track_disp_all(write_trk_style, NULL, NULL); - route_disp_all(start_rte, NULL, write_rte_waypt); + waypt_disp_all(write_waypt); + if (waypt_count()) { + gbfwrite(WAYPOINTSTYLES, 1, sizeof(WAYPOINTSTYLES)-1, file_out); + } + track_disp_all(start_rte, NULL, write_trk_waypt); + track_disp_all(write_trk_style, NULL, NULL); + route_disp_all(start_rte, NULL, write_rte_waypt); } static arglist_t gtm_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; ff_vecs_t gtm_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - gtm_rd_init, - gtm_wr_init, - gtm_rd_deinit, - gtm_wr_deinit, - gtm_read, - gtm_write, - NULL, - gtm_args, + ff_type_file, + FF_CAP_RW_ALL, + gtm_rd_init, + gtm_wr_init, + gtm_rd_deinit, + gtm_wr_deinit, + gtm_read, + gtm_write, + NULL, + gtm_args, }; diff --git a/gpsbabel/gtrnctr.c b/gpsbabel/gtrnctr.c index 5c343ec51..c224cac86 100644 --- a/gpsbabel/gtrnctr.c +++ b/gpsbabel/gtrnctr.c @@ -22,12 +22,12 @@ #include "defs.h" #include "xmlgeneric.h" -static gbfile *ofd; +static gbfile* ofd; static int lap_ct = 0; static int lap_s = 0; -static waypoint *wpt_tmp; -static route_head *trk_head; -static computed_trkdata *tdata; +static waypoint* wpt_tmp; +static route_head* trk_head; +static computed_trkdata* tdata; #define MYNAME "gtc" @@ -45,22 +45,26 @@ static double gtc_start_long; static double gtc_end_lat; static double gtc_end_long; -static char *opt_sport, *opt_course; +static char* opt_sport, *opt_course; static arglist_t gtc_args[] = { - { "course", &opt_course, "Write course rather than history, default yes", - "1", ARGTYPE_BOOL, ARG_NOMINMAX}, - { "sport", &opt_sport, "Sport: Biking (deflt), Running, MultiSport, Other", - "Biking", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "course", &opt_course, "Write course rather than history, default yes", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "sport", &opt_sport, "Sport: Biking (deflt), Running, MultiSport, Other", + "Biking", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #if ! HAVE_LIBEXPAT static void -gtc_rd_init(const char *fname) +gtc_rd_init(const char* fname) { - fatal(MYNAME ": this format does not support reading.\n"); + fatal(MYNAME ": this format does not support reading.\n"); } static void @@ -87,469 +91,538 @@ static xg_callback gtc_trk_alt; static xg_callback gtc_trk_hr; static xg_callback gtc_trk_cad; static xg_callback gtc_trk_pwr; +static xg_callback gtc_wpt_crs_s, gtc_wpt_crs_e; static xg_callback gtc_wpt_pnt_s, gtc_wpt_pnt_e; +static xg_callback gtc_wpt_ident; static xg_callback gtc_wpt_lat; static xg_callback gtc_wpt_long; +static xg_callback gtc_wpt_icon; +static xg_callback gtc_wpt_notes; static xg_tag_mapping gtc_map[] = { - /* courses tcx v1 & v2 */ - { gtc_trk_s, cb_start, "/Courses/Course" }, - { gtc_trk_ident,cb_cdata, "/Courses/Course/Name"}, - { gtc_trk_pnt_s,cb_start, "/Courses/Course/Track/Trackpoint" }, - { gtc_trk_pnt_e,cb_end, "/Courses/Course/Track/Trackpoint" }, - { gtc_trk_utc, cb_cdata, "/Courses/Course/Track/Trackpoint/Time" }, - { gtc_trk_lat, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LatitudeDegrees" }, - { gtc_trk_long, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LongitudeDegrees" }, - { gtc_trk_alt, cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" }, - { gtc_trk_alt, cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" }, - { gtc_trk_hr, cb_cdata, "/Courses/Course/Track/Trackpoint/HeartRateBpm" }, - { gtc_trk_cad, cb_cdata, "/Courses/Course/Track/Trackpoint/Cadence" }, - - /* history tcx v2 (activities) */ - { gtc_trk_s, cb_start, "/Activities/Activity" }, - { gtc_trk_ident,cb_cdata, "/Activities/Activity/Id" }, - { gtc_trk_lap_s,cb_start, "/Activities/Activity/Lap" }, - { gtc_trk_lap_e,cb_end, "/Activities/Activity/Lap" }, - { gtc_trk_pnt_s,cb_start, "/Activities/Activity/Lap/Track/Trackpoint" }, - { gtc_trk_pnt_e,cb_end, "/Activities/Activity/Lap/Track/Trackpoint" }, - { gtc_trk_utc, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Time" }, - { gtc_trk_lat, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LatitudeDegrees" }, - { gtc_trk_long, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LongitudeDegrees" }, - { gtc_trk_alt, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/AltitudeMeters" }, - { gtc_trk_hr, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/HeartRateBpm" }, - { gtc_trk_cad, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Cadence" }, - { gtc_trk_pwr, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/ns3:TPX/ns3:Watts" }, - - /* history tcx v1 */ - { gtc_trk_s, cb_start, "/History/Run" }, - { gtc_trk_ident,cb_cdata, "/History/Run/Id" }, - { gtc_trk_lap_s,cb_start, "/History/Run/Lap" }, - { gtc_trk_lap_e,cb_end, "/History/Run/Lap" }, - { gtc_trk_pnt_s,cb_start, "/History/Run/Lap/Track/Trackpoint" }, - { gtc_trk_pnt_e,cb_end, "/History/Run/Lap/Track/Trackpoint" }, - { gtc_trk_utc, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Time" }, - { gtc_trk_lat, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LatitudeDegrees" }, - { gtc_trk_long, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LongitudeDegrees" }, - { gtc_trk_alt, cb_cdata, "/History/Run/Lap/Track/Trackpoint/AltitudeMeters" }, - { gtc_trk_hr, cb_cdata, "/History/Run/Lap/Track/Trackpoint/HeartRateBpm" }, - { gtc_trk_cad, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Cadence" }, - - { gtc_wpt_pnt_s,cb_start, "/Courses/Course/Lap/BeginPosition" }, - { gtc_wpt_pnt_e,cb_end, "/Courses/Course/Lap/BeginPosition" }, - { gtc_wpt_lat, cb_cdata, "/Courses/Course/Lap/BeginPosition/LatitudeDegrees" }, - { gtc_wpt_long, cb_cdata, "/Courses/Course/Lap/BeginPosition/LongitudeDegrees" }, - - { NULL, 0, NULL} + /* courses tcx v1 & v2 */ + { gtc_trk_s, cb_start, "/Courses/Course" }, + { gtc_trk_ident,cb_cdata, "/Courses/Course/Name"}, + { gtc_trk_pnt_s,cb_start, "/Courses/Course/Track/Trackpoint" }, + { gtc_trk_pnt_e,cb_end, "/Courses/Course/Track/Trackpoint" }, + { gtc_trk_utc, cb_cdata, "/Courses/Course/Track/Trackpoint/Time" }, + { gtc_trk_lat, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LatitudeDegrees" }, + { gtc_trk_long, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LongitudeDegrees" }, + { gtc_trk_alt, cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" }, + { gtc_trk_hr, cb_cdata, "/Courses/Course/Track/Trackpoint/HeartRateBpm" }, + { gtc_trk_cad, cb_cdata, "/Courses/Course/Track/Trackpoint/Cadence" }, + { gtc_wpt_crs_s,cb_start, "/Courses/Course/CoursePoint" }, + { gtc_wpt_crs_e,cb_end, "/Courses/Course/CoursePoint" }, + { gtc_wpt_ident,cb_cdata, "/Courses/Course/CoursePoint/Name"}, + { gtc_trk_utc, cb_cdata, "/Courses/Course/CoursePoint/Time"}, + { gtc_wpt_lat, cb_cdata, "/Courses/Course/CoursePoint/Position/LatitudeDegrees"}, + { gtc_wpt_long, cb_cdata, "/Courses/Course/CoursePoint/Position/LongitudeDegrees"}, + { gtc_trk_alt, cb_cdata, "/Courses/Course/CoursePoint/AltitudeMeters" }, + { gtc_wpt_icon, cb_cdata, "/Courses/Course/CoursePoint/PointType" }, + { gtc_wpt_notes,cb_cdata, "/Courses/Course/CoursePoint/Notes" }, + + /* history tcx v2 (activities) */ + { gtc_trk_s, cb_start, "/Activities/Activity" }, + { gtc_trk_ident,cb_cdata, "/Activities/Activity/Id" }, + { gtc_trk_lap_s,cb_start, "/Activities/Activity/Lap" }, + { gtc_trk_lap_e,cb_end, "/Activities/Activity/Lap" }, + { gtc_trk_pnt_s,cb_start, "/Activities/Activity/Lap/Track/Trackpoint" }, + { gtc_trk_pnt_e,cb_end, "/Activities/Activity/Lap/Track/Trackpoint" }, + { gtc_trk_utc, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Time" }, + { gtc_trk_lat, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LatitudeDegrees" }, + { gtc_trk_long, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LongitudeDegrees" }, + { gtc_trk_alt, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/AltitudeMeters" }, + { gtc_trk_hr, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/HeartRateBpm" }, + { gtc_trk_cad, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Cadence" }, + { gtc_trk_pwr, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/ns3:TPX/ns3:Watts" }, + + /* history tcx v1 */ + { gtc_trk_s, cb_start, "/History/Run" }, + { gtc_trk_ident,cb_cdata, "/History/Run/Id" }, + { gtc_trk_lap_s,cb_start, "/History/Run/Lap" }, + { gtc_trk_lap_e,cb_end, "/History/Run/Lap" }, + { gtc_trk_pnt_s,cb_start, "/History/Run/Lap/Track/Trackpoint" }, + { gtc_trk_pnt_e,cb_end, "/History/Run/Lap/Track/Trackpoint" }, + { gtc_trk_utc, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Time" }, + { gtc_trk_lat, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LatitudeDegrees" }, + { gtc_trk_long, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LongitudeDegrees" }, + { gtc_trk_alt, cb_cdata, "/History/Run/Lap/Track/Trackpoint/AltitudeMeters" }, + { gtc_trk_hr, cb_cdata, "/History/Run/Lap/Track/Trackpoint/HeartRateBpm" }, + { gtc_trk_cad, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Cadence" }, + + { gtc_wpt_pnt_s,cb_start, "/Courses/Course/Lap/BeginPosition" }, + { gtc_wpt_pnt_e,cb_end, "/Courses/Course/Lap/BeginPosition" }, + { gtc_wpt_lat, cb_cdata, "/Courses/Course/Lap/BeginPosition/LatitudeDegrees" }, + { gtc_wpt_long, cb_cdata, "/Courses/Course/Lap/BeginPosition/LongitudeDegrees" }, + { gtc_trk_alt, cb_cdata, "/Courses/Course/Lap/BeginAltitudeMeters" }, + + { NULL, (xg_cb_type)0, NULL} }; -static const char * +static const char* gtc_tags_to_ignore[] = { - "TrainingCenterDatabase", - "CourseFolder", - "Running", - "Biking", - "Other", - "Multisport", - NULL, + "TrainingCenterDatabase", + "CourseFolder", + "Running", + "Biking", + "Other", + "Multisport", + NULL, }; static void -gtc_rd_init(const char *fname) +gtc_rd_init(const char* fname) { - xml_init(fname, gtc_map, NULL); - xml_ignore_tags(gtc_tags_to_ignore); + xml_init(fname, gtc_map, NULL); + xml_ignore_tags(gtc_tags_to_ignore); } static void gtc_read(void) { - xml_read(); + xml_read(); } static void gtc_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } #endif static void -gtc_wr_init(const char *fname) +gtc_wr_init(const char* fname) { - int i; + int i; - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); - if(opt_sport) { - for(i = 0; i < MAX_SPORTS; i++) { - if(0 == case_ignore_strncmp(opt_sport, gtc_sportlist[i], 2)) { - gtc_sport = i; - break; - } - } - } - gtc_course_flag = atoi(opt_course); + if (opt_sport) { + for (i = 0; i < MAX_SPORTS; i++) { + if (0 == case_ignore_strncmp(opt_sport, gtc_sportlist[i], 2)) { + gtc_sport = i; + break; + } + } + } + gtc_course_flag = atoi(opt_course); } static void gtc_wr_deinit(void) { - gbfclose(ofd); - xfree(tdata); + gbfclose(ofd); } static int gtc_indent_level; static void -gtc_write_xml(int indent, const char *fmt, ...) +gtc_write_xml(int indent, const char* fmt, ...) { - va_list args; + va_list args; - va_start(args, fmt); + va_start(args, fmt); - if (indent < 0) gtc_indent_level--; + if (indent < 0) { + gtc_indent_level--; + } - gbfprintf(ofd, "%*s", gtc_indent_level * 2, ""); - gbvfprintf(ofd, fmt, args); + gbfprintf(ofd, "%*s", gtc_indent_level * 2, ""); + gbvfprintf(ofd, fmt, args); - if (indent > 0) gtc_indent_level++; + if (indent > 0) { + gtc_indent_level++; + } - va_end(args); + va_end(args); } static void -gtc_waypt_pr(const waypoint *wpt) -{ - if (wpt->wpt_flags.is_split != 0) { - gtc_write_xml(1, "\n"); - } else { - gtc_write_xml(1, "\n"); - } - - if (wpt->creation_time) { - char time_string[100]; - xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, - XML_LONG_TIME); - if (time_string[0]) { - gtc_write_xml(0, "\n", - time_string); - } - } - gtc_write_xml(1, "\n"); - gtc_write_xml(0, "%f\n", wpt->latitude); - gtc_write_xml(0, "%f\n", wpt->longitude); - gtc_write_xml(-1, "\n"); - if (wpt->altitude != unknown_alt) { - gtc_write_xml(0, "%f\n", wpt->altitude); - } - if (wpt->heartrate) { - //gtc_write_xml(0, "%d\n", wpt->heartrate); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%d\n", wpt->heartrate); - gtc_write_xml(-1,"\n"); - } - if (wpt->cadence) { - gtc_write_xml(0, "%d\n", wpt->cadence); - } - - gtc_write_xml(-1, "\n"); +gtc_lap_start(const route_head* rte) +{ + gtc_least_time = 0; + gtc_most_time = 0; } static void -gtc_fake_hdr(void) +gtc_new_study_lap(const route_head* rte) { - long secs = 0; - if (gtc_least_time && gtc_most_time) { - secs = gtc_most_time - gtc_least_time; - } - if(gtc_course_flag) { /* course format */ - - gtc_write_xml(0, "%d\n", secs); - gtc_write_xml(0, "%lf\n", - tdata->distance_meters ? tdata->distance_meters : 0); - gtc_write_xml(1, "\n"); - gtc_write_xml(0, "%lf\n", gtc_start_lat); - gtc_write_xml(0, "%lf\n", gtc_start_long); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0, "%lf\n", gtc_end_lat); - gtc_write_xml(0, "%lf\n", gtc_end_long); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%d\n", - tdata->avg_hrt ? (int)(tdata->avg_hrt + .5): 100); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%d\n", - tdata->max_hrt ? tdata->max_hrt : 200); - gtc_write_xml(-1,"\n"); - gtc_write_xml(0, "Active\n"); - - } else { /* activity (history) format */ - - gtc_write_xml(0, "%d\n", secs); - gtc_write_xml(0, "%lf\n", - tdata->distance_meters ? tdata->distance_meters : 1000); - gtc_write_xml(0, "0\n"); - gtc_write_xml(0, "0\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%g\n", - tdata->avg_hrt ? tdata->avg_hrt : 100); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%d\n", - tdata->max_hrt ? (int) tdata->max_hrt : 200); - gtc_write_xml(-1,"\n"); - gtc_write_xml(0, "Active\n"); - gtc_write_xml(0, "Manual\n"); - } + track_recompute(rte, &tdata); /* called routine allocates space for tdata */ } static void -gtc_act_hdr( const route_head *rte) -{ - gtc_write_xml(1, "\n", gtc_sportlist[gtc_sport]); - if (gtc_least_time) { - char time_string[100]; - xml_fill_in_time(time_string, gtc_least_time, 0, XML_LONG_TIME); - gtc_write_xml(0, "%s\n", time_string); - gtc_write_xml(1, "\n", time_string); - } else { - gtc_write_xml(1, "\n"); - } - gtc_fake_hdr(); - gtc_write_xml(1,"\n"); +gtc_study_lap(const waypoint* wpt) +{ + if (wpt->creation_time && (gtc_least_time == 0)) { + gtc_least_time = wpt->creation_time; + gtc_start_lat = wpt->latitude; + gtc_start_long = wpt->longitude; + } + + if (wpt->creation_time && (gtc_least_time > wpt->creation_time)) { + gtc_least_time = wpt->creation_time; + gtc_start_lat = wpt->latitude; + gtc_start_long = wpt->longitude; + } + if (wpt->creation_time > gtc_most_time) { + gtc_most_time = wpt->creation_time; + gtc_end_lat = wpt->latitude; + gtc_end_long = wpt->longitude; + } } static void -gtc_act_ftr(const route_head *rte) -{ - gtc_write_xml(-1, "\n"); - gtc_write_xml(-1, "\n"); - gtc_write_xml(-1, "\n"); +gtc_waypt_pr(const waypoint* wpt) +{ + if (wpt->wpt_flags.is_split != 0) { + gtc_write_xml(1, "\n"); + } else { + gtc_write_xml(1, "\n"); + } + + if (wpt->creation_time) { + char time_string[100]; + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, + XML_LONG_TIME); + if (time_string[0]) { + gtc_write_xml(0, "\n", + time_string); + } + } + gtc_write_xml(1, "\n"); + gtc_write_xml(0, "%f\n", wpt->latitude); + gtc_write_xml(0, "%f\n", wpt->longitude); + gtc_write_xml(-1, "\n"); + if (wpt->altitude != unknown_alt) { + gtc_write_xml(0, "%f\n", wpt->altitude); + } + if (wpt->heartrate) { + //gtc_write_xml(0, "%d\n", wpt->heartrate); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%d\n", wpt->heartrate); + gtc_write_xml(-1,"\n"); + } + if (wpt->cadence) { + gtc_write_xml(0, "%d\n", wpt->cadence); + } + + gtc_write_xml(-1, "\n"); } static void -gtc_crs_hdr( const route_head *rte) +gtc_fake_hdr(void) { - - gtc_write_xml(1, "\n"); - if(rte->rte_name) { - char *name = xstrndup(rte->rte_name, GTC_MAX_NAME_LEN); - gtc_write_xml(0, "%s\n", name); - xfree(name); - } else { - gtc_write_xml(0, "New Course\n"); - } - /* write_optional_xml_entity(ofd, " ", "Name", rte->rte_name); */ - gtc_write_xml(1, "\n"); - gtc_fake_hdr(); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1,"\n"); + long secs = 0; + if (gtc_least_time && gtc_most_time) { + secs = gtc_most_time - gtc_least_time; + } + if (gtc_course_flag) { /* course format */ + + gtc_write_xml(0, "%d\n", secs); + gtc_write_xml(0, "%lf\n", + tdata->distance_meters ? tdata->distance_meters : 0); + gtc_write_xml(1, "\n"); + gtc_write_xml(0, "%lf\n", gtc_start_lat); + gtc_write_xml(0, "%lf\n", gtc_start_long); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0, "%lf\n", gtc_end_lat); + gtc_write_xml(0, "%lf\n", gtc_end_long); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%d\n", + tdata->avg_hrt ? (int)(tdata->avg_hrt + .5): 100); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%d\n", + tdata->max_hrt ? tdata->max_hrt : 200); + gtc_write_xml(-1,"\n"); + gtc_write_xml(0, "Active\n"); + + } else { /* activity (history) format */ + + gtc_write_xml(0, "%d\n", secs); + gtc_write_xml(0, "%lf\n", + tdata->distance_meters ? tdata->distance_meters : 1000); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "0\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%g\n", + tdata->avg_hrt ? tdata->avg_hrt : 100); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%d\n", + tdata->max_hrt ? (int) tdata->max_hrt : 200); + gtc_write_xml(-1,"\n"); + gtc_write_xml(0, "Active\n"); + gtc_write_xml(0, "Manual\n"); + } } static void -gtc_crs_ftr(const route_head *rte) -{ - gtc_write_xml(-1,"\n"); - gtc_write_xml(-1, "\n"); - +gtc_act_hdr(const route_head* rte) +{ + gtc_write_xml(1, "\n", gtc_sportlist[gtc_sport]); + gtc_lap_start(NULL); + gtc_new_study_lap(rte); + route_disp(rte, gtc_study_lap); + if (gtc_least_time) { + char time_string[100]; + xml_fill_in_time(time_string, gtc_least_time, 0, XML_LONG_TIME); + gtc_write_xml(0, "%s\n", time_string); + gtc_write_xml(1, "\n", time_string); + } else { + gtc_write_xml(1, "\n"); + } + gtc_fake_hdr(); + xfree(tdata); + gtc_write_xml(1,"\n"); } static void -gtc_lap_start(const route_head *rte) +gtc_act_ftr(const route_head* rte) { - gtc_least_time = 0; - gtc_most_time = 0; + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); } static void -gtc_new_study_lap(const route_head *rte) -{ - track_recompute(rte, &tdata); /* called routine allocates space for tdata */ +gtc_crs_hdr(const route_head* rte) +{ + + gtc_write_xml(1, "\n"); + gtc_lap_start(NULL); + gtc_new_study_lap(rte); + route_disp(rte, gtc_study_lap); + if (rte->rte_name) { + char* name = xstrndup(rte->rte_name, GTC_MAX_NAME_LEN); + gtc_write_xml(0, "%s\n", name); + xfree(name); + } else { + gtc_write_xml(0, "New Course\n"); + } + /* write_optional_xml_entity(ofd, " ", "Name", rte->rte_name); */ + gtc_write_xml(1, "\n"); + gtc_fake_hdr(); + gtc_write_xml(-1, "\n"); + xfree(tdata); + gtc_write_xml(1,"\n"); } static void -gtc_study_lap(const waypoint *wpt) -{ - if (wpt->creation_time && (gtc_least_time == 0)) { - gtc_least_time = wpt->creation_time; - gtc_start_lat = wpt->latitude; - gtc_start_long = wpt->longitude; - } - - if (wpt->creation_time && (gtc_least_time > wpt->creation_time)) { - gtc_least_time = wpt->creation_time; - gtc_start_lat = wpt->latitude; - gtc_start_long = wpt->longitude; - } - if (wpt->creation_time > gtc_most_time) { - gtc_most_time = wpt->creation_time; - gtc_end_lat = wpt->latitude; - gtc_end_long = wpt->longitude; - } +gtc_crs_ftr(const route_head* rte) +{ + gtc_write_xml(-1,"\n"); + gtc_write_xml(-1, "\n"); + } void gtc_write(void) { - gtc_write_xml(0, "\n"); - gtc_write_xml(1, "\n"); + gtc_write_xml(0, "\n"); + gtc_write_xml(1, "\n"); - gtc_lap_start(NULL); - track_disp_all(NULL, NULL, gtc_study_lap); - track_disp_all(gtc_new_study_lap, NULL, NULL); + if (gtc_course_flag) { + gtc_write_xml(1, "\n"); + track_disp_all(gtc_crs_hdr, gtc_crs_ftr, gtc_waypt_pr); + gtc_write_xml(-1, "\n"); + } else { + gtc_write_xml(1, "\n"); + track_disp_all(gtc_act_hdr, gtc_act_ftr, gtc_waypt_pr); + gtc_write_xml(-1, "\n"); + } - if(gtc_course_flag) { - gtc_write_xml(1, "\n"); - track_disp_all(gtc_crs_hdr, gtc_crs_ftr, gtc_waypt_pr); - gtc_write_xml(-1, "\n"); - } else { - gtc_write_xml(1, "\n"); - track_disp_all(gtc_act_hdr, gtc_act_ftr, gtc_waypt_pr); - gtc_write_xml(-1, "\n"); - } + gtc_write_xml(-1, "\n"); +} - gtc_write_xml(-1, "\n"); +void +gtc_trk_s(const char* unused, const char** attrv) +{ + trk_head = route_head_alloc(); + track_add_head(trk_head); } void -gtc_trk_s(const char *unused, const char **attrv) +gtc_trk_ident(const char* args, const char** unused) { - trk_head = route_head_alloc(); - track_add_head(trk_head); + trk_head->rte_name = xstrdup(args); } void -gtc_trk_ident(const char *args, const char **unused) +gtc_trk_lap_s(const char* unused, const char** attrv) { - trk_head->rte_name = xstrdup(args); + lap_ct++; + lap_s = 1; } void -gtc_trk_lap_s(const char *unused, const char **attrv) +gtc_trk_lap_e(const char* unused, const char** attrv) { - lap_ct++; - lap_s = 1; + lap_s = 0; } void -gtc_trk_lap_e(const char *unused, const char **attrv) +gtc_trk_pnt_s(const char* unused, const char** attrv) { - lap_s = 0; + wpt_tmp = waypt_new(); } void -gtc_trk_pnt_s(const char *unused, const char **attrv) +gtc_trk_pnt_e(const char* args, const char** unused) { - wpt_tmp = waypt_new(); + if (wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) { + if (lap_s) { + /* Add the first point of an ActivityLap as + a waypoint as well as a trackpoint. */ + char cbuf[10]; + waypoint* wpt_lap_s = waypt_dupe(wpt_tmp); + snprintf(cbuf, sizeof(cbuf), "LAP%03d", lap_ct); + wpt_lap_s->shortname = xstrdup(cbuf); + waypt_add(wpt_lap_s); + } + + track_add_wpt(trk_head, wpt_tmp); + } else { + waypt_free(wpt_tmp); + } + + wpt_tmp = NULL; + lap_s = 0; } void -gtc_trk_pnt_e(const char *args, const char **unused) +gtc_trk_utc(const char* args, const char** unused) { - if(wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) { - if (lap_s) { - /* Add the first point of an ActivityLap as - a waypoint as well as a trackpoint. */ - char cbuf[10]; - waypoint* wpt_lap_s = waypt_dupe(wpt_tmp); - snprintf(cbuf, sizeof(cbuf), "LAP%03d", lap_ct); - wpt_lap_s->shortname = xstrdup(cbuf); - waypt_add(wpt_lap_s); - } + wpt_tmp->creation_time = xml_parse_time(args, NULL); +} - track_add_wpt(trk_head, wpt_tmp); - } - else waypt_free(wpt_tmp); +void +gtc_trk_lat(const char* args, const char** unused) +{ + wpt_tmp->latitude = atof(args); +} - wpt_tmp = NULL; - lap_s = 0; +void +gtc_trk_long(const char* args, const char** unused) +{ + wpt_tmp->longitude = atof(args); } void -gtc_trk_utc(const char *args, const char **unused) +gtc_trk_alt(const char* args, const char** unused) { - wpt_tmp->creation_time = xml_parse_time(args, NULL); + wpt_tmp->altitude = atof(args); } void -gtc_trk_lat(const char *args, const char **unused) +gtc_trk_hr(const char* args, const char** unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->heartrate = atoi(args); } void -gtc_trk_long(const char *args, const char **unused) +gtc_trk_cad(const char* args, const char** unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->cadence = atoi(args); } void -gtc_trk_alt(const char *args, const char **unused) +gtc_trk_pwr(const char* args, const char** unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->power = atof(args); } void -gtc_trk_hr(const char *args, const char **unused) +gtc_wpt_crs_s(const char* unused, const char** attrv) { - wpt_tmp->heartrate = atoi(args); + wpt_tmp = waypt_new(); } void -gtc_trk_cad(const char *args, const char **unused) +gtc_wpt_crs_e(const char* args, const char** unused) { - wpt_tmp->cadence = atoi(args); + if (wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) { + waypt_add(wpt_tmp); + } else { + waypt_free(wpt_tmp); + } + + wpt_tmp = NULL; } void -gtc_trk_pwr(const char *args, const char **unused) +gtc_wpt_pnt_s(const char* unused, const char** attrv) { - wpt_tmp->power = atof(args); + wpt_tmp = waypt_new(); + lap_ct++; } void -gtc_wpt_pnt_s(const char *unused, const char **attrv) +gtc_wpt_pnt_e(const char* args, const char** unused) { - wpt_tmp = waypt_new(); + if (wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) { + /* Add the begin position of a CourseLap as + a waypoint. */ + char *cbuf; + xasprintf(&cbuf, "LAP%03d", lap_ct); + wpt_tmp->shortname = cbuf; + waypt_add(wpt_tmp); + } else { + waypt_free(wpt_tmp); + } + + wpt_tmp = NULL; } void -gtc_wpt_pnt_e(const char *args, const char **unused) +gtc_wpt_ident(const char* args, const char** unused) { - if(wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) waypt_add(wpt_tmp); - else waypt_free(wpt_tmp); + wpt_tmp->shortname = xstrdup(args); + /* Set also as notes for compatibility with garmin usb format */ + wpt_tmp->notes = xstrdup(args); +} - wpt_tmp = NULL; +void +gtc_wpt_lat(const char* args, const char** unused) +{ + wpt_tmp->latitude = atof(args); +} + +void +gtc_wpt_long(const char* args, const char** unused) +{ + wpt_tmp->longitude = atof(args); } void -gtc_wpt_lat(const char *args, const char **unused) +gtc_wpt_icon(const char* args, const char** unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; } void -gtc_wpt_long(const char *args, const char **unused) +gtc_wpt_notes(const char* args, const char** unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->description = xstrdup(args); } ff_vecs_t gtc_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - gtc_rd_init, - gtc_wr_init, - gtc_rd_deinit, - gtc_wr_deinit, - gtc_read, - gtc_write, - NULL, - gtc_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_read /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + gtc_rd_init, + gtc_wr_init, + gtc_rd_deinit, + gtc_wr_deinit, + gtc_read, + gtc_write, + NULL, + gtc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/gui/COPYING.txt b/gpsbabel/gui/COPYING.txt new file mode 100644 index 000000000..514d6c73f --- /dev/null +++ b/gpsbabel/gui/COPYING.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/gpsbabel/gui/aboutdlg.cpp b/gpsbabel/gui/aboutdlg.cpp index e1e251580..e8b75f82d 100644 --- a/gpsbabel/gui/aboutdlg.cpp +++ b/gpsbabel/gui/aboutdlg.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: aboutdlg.cpp,v 1.2 2010/01/17 21:57:00 robertl Exp $ +// $Id: aboutdlg.cpp,v 1.2 2010-01-17 21:57:00 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/aboutdlg.h b/gpsbabel/gui/aboutdlg.h index ec574aca4..b0721ca85 100644 --- a/gpsbabel/gui/aboutdlg.h +++ b/gpsbabel/gui/aboutdlg.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: aboutdlg.h,v 1.1 2009/07/05 21:14:56 robertl Exp $ +// $Id: aboutdlg.h,v 1.1 2009-07-05 21:14:56 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/advdlg.cpp b/gpsbabel/gui/advdlg.cpp index eecd1d346..ba2c25575 100644 --- a/gpsbabel/gui/advdlg.cpp +++ b/gpsbabel/gui/advdlg.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: advdlg.cpp,v 1.3 2009/11/02 20:38:02 robertl Exp $ +// $Id: advdlg.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/advdlg.h b/gpsbabel/gui/advdlg.h index c26821383..0c26e1098 100644 --- a/gpsbabel/gui/advdlg.h +++ b/gpsbabel/gui/advdlg.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: advdlg.h,v 1.2 2009/11/02 20:38:02 robertl Exp $ +// $Id: advdlg.h,v 1.2 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/app.pro b/gpsbabel/gui/app.pro index ed8acb15b..b725446d3 100755 --- a/gpsbabel/gui/app.pro +++ b/gpsbabel/gui/app.pro @@ -1,11 +1,12 @@ -# $Id: app.pro,v 1.18 2010/06/19 23:59:06 robertl Exp $ +# $Id: app.pro,v 1.19 2010-11-01 03:30:42 robertl Exp $ # CONFIG += qt release #CONFIG += qt debug console -# For Mac, build Universal binary. Ignored on other OSes. -CONFIG += x86 ppc +# For Mac, x86 and x64, but not PPC binary. Ignored on other OSes. +macx:CONFIG -= x86_64 +# macx:CONFIG += x86 ICON = images/appicon.icns @@ -25,7 +26,10 @@ UI_DIR = tmp RESOURCES = app.qrc RC_FILE = app.rc -win32:TARGET=GPSBabelFE +win32 { + TARGET=GPSBabelFE + QMAKE_LFLAGS_RELEASE += -static-libgcc +} unix:TARGET=gpsbabelfe-bin mac:TARGET=GPSBabelFE diff --git a/gpsbabel/gui/appname.h b/gpsbabel/gui/appname.h index 39d8ed24d..162531a2a 100644 --- a/gpsbabel/gui/appname.h +++ b/gpsbabel/gui/appname.h @@ -1,4 +1,4 @@ -// $Id: appname.h,v 1.2 2009/09/06 17:04:36 robertl Exp $ +// $Id: appname.h,v 1.2 2009-09-06 17:04:36 robertl Exp $ // //------------------------------------------------------------------------ // diff --git a/gpsbabel/gui/babeldata.h b/gpsbabel/gui/babeldata.h index c120b487e..b237dfcd0 100644 --- a/gpsbabel/gui/babeldata.h +++ b/gpsbabel/gui/babeldata.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: babeldata.h,v 1.8 2010/06/19 23:59:06 robertl Exp $ +// $Id: babeldata.h,v 1.8 2010-06-19 23:59:06 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/dpencode.cpp b/gpsbabel/gui/dpencode.cpp index d06224a99..4fc683ec1 100755 --- a/gpsbabel/gui/dpencode.cpp +++ b/gpsbabel/gui/dpencode.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: dpencode.cpp,v 1.3 2009/09/08 16:06:32 robertl Exp $ +// $Id: dpencode.cpp,v 1.3 2009-09-08 16:06:32 robertl Exp $ //------------------------------------------------------------------------ // // Original in JavaScript: diff --git a/gpsbabel/gui/dpencode.h b/gpsbabel/gui/dpencode.h index 8d2f13c29..feb9b2213 100644 --- a/gpsbabel/gui/dpencode.h +++ b/gpsbabel/gui/dpencode.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: dpencode.h,v 1.2 2009/09/08 16:06:32 robertl Exp $ +// $Id: dpencode.h,v 1.2 2009-09-08 16:06:32 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/filterdata.cpp b/gpsbabel/gui/filterdata.cpp index 1231a3a45..53ac7d9bf 100644 --- a/gpsbabel/gui/filterdata.cpp +++ b/gpsbabel/gui/filterdata.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: filterdata.cpp,v 1.4 2009/11/02 20:38:02 robertl Exp $ +// $Id: filterdata.cpp,v 1.4 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/filterdata.h b/gpsbabel/gui/filterdata.h index a6bc3d195..ca4d8a2aa 100644 --- a/gpsbabel/gui/filterdata.h +++ b/gpsbabel/gui/filterdata.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: filterdata.h,v 1.4 2009/11/02 20:38:02 robertl Exp $ +// $Id: filterdata.h,v 1.4 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/filterdlg.cpp b/gpsbabel/gui/filterdlg.cpp index d542dc4ca..4cc2feefd 100644 --- a/gpsbabel/gui/filterdlg.cpp +++ b/gpsbabel/gui/filterdlg.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: filterdlg.cpp,v 1.4 2009/09/08 16:06:32 robertl Exp $ +// $Id: filterdlg.cpp,v 1.4 2009-09-08 16:06:32 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/filterdlg.h b/gpsbabel/gui/filterdlg.h index 2b8d2435f..98397f7a8 100644 --- a/gpsbabel/gui/filterdlg.h +++ b/gpsbabel/gui/filterdlg.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: filterdlg.h,v 1.1 2009/07/05 21:14:56 robertl Exp $ +// $Id: filterdlg.h,v 1.1 2009-07-05 21:14:56 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/filterwidgets.cpp b/gpsbabel/gui/filterwidgets.cpp index cd17b8c32..09990ed3d 100644 --- a/gpsbabel/gui/filterwidgets.cpp +++ b/gpsbabel/gui/filterwidgets.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: filterwidgets.cpp,v 1.5 2009/11/02 20:38:02 robertl Exp $ +// $Id: filterwidgets.cpp,v 1.5 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/filterwidgets.h b/gpsbabel/gui/filterwidgets.h index 34b2f9de7..fb2a2cc50 100644 --- a/gpsbabel/gui/filterwidgets.h +++ b/gpsbabel/gui/filterwidgets.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: filterwidgets.h,v 1.2 2009/11/02 20:38:02 robertl Exp $ +// $Id: filterwidgets.h,v 1.2 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/format.cpp b/gpsbabel/gui/format.cpp index 54d92dc5b..27b6f1528 100644 --- a/gpsbabel/gui/format.cpp +++ b/gpsbabel/gui/format.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: format.cpp,v 1.4 2010/02/14 05:33:37 robertl Exp $ +// $Id: format.cpp,v 1.4 2010-02-14 05:33:37 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/format.h b/gpsbabel/gui/format.h index e83d2682c..52374d477 100644 --- a/gpsbabel/gui/format.h +++ b/gpsbabel/gui/format.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: format.h,v 1.6 2010/02/15 02:57:00 robertl Exp $ +// $Id: format.h,v 1.6 2010-02-15 02:57:00 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/formatload.cpp b/gpsbabel/gui/formatload.cpp index 7caf39d83..3ca039e44 100644 --- a/gpsbabel/gui/formatload.cpp +++ b/gpsbabel/gui/formatload.cpp @@ -1,5 +1,5 @@ // -*- c++ -*- -// $Id: formatload.cpp,v 1.3 2009/11/02 20:38:02 robertl Exp $ +// $Id: formatload.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/formatload.h b/gpsbabel/gui/formatload.h index 96aecc940..28047f3e8 100644 --- a/gpsbabel/gui/formatload.h +++ b/gpsbabel/gui/formatload.h @@ -1,5 +1,5 @@ // -*- c++ -*- -// $Id: formatload.h,v 1.1 2009/07/05 21:14:56 robertl Exp $ +// $Id: formatload.h,v 1.1 2009-07-05 21:14:56 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/gmapdlg.cpp b/gpsbabel/gui/gmapdlg.cpp index 0b06ed660..d8105a15f 100755 --- a/gpsbabel/gui/gmapdlg.cpp +++ b/gpsbabel/gui/gmapdlg.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: gmapdlg.cpp,v 1.3 2009/11/02 20:38:02 robertl Exp $ +// $Id: gmapdlg.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/gmapdlg.h b/gpsbabel/gui/gmapdlg.h index 901ab4c38..58f2e3420 100755 --- a/gpsbabel/gui/gmapdlg.h +++ b/gpsbabel/gui/gmapdlg.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: gmapdlg.h,v 1.2 2009/11/02 20:38:02 robertl Exp $ +// $Id: gmapdlg.h,v 1.2 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/gpsbabel.desktop b/gpsbabel/gui/gpsbabel.desktop new file mode 100644 index 000000000..4ae452581 --- /dev/null +++ b/gpsbabel/gui/gpsbabel.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Application +Name=GPSBabel +Comment=Qt GUI interface for GPSBabel +GenericName=GPSBabel +Icon=gpsbabel +Exec=gpsbabelfe-bin +Terminal=false +Categories=Geography;Education;Utility; diff --git a/gpsbabel/gui/gpsbabel.ts b/gpsbabel/gui/gpsbabel.ts index 06a937ea9..f3c03b2bd 100644 --- a/gpsbabel/gui/gpsbabel.ts +++ b/gpsbabel/gui/gpsbabel.ts @@ -986,10 +986,6 @@ p, li { white-space: pre-wrap; } MainWindow - - MainWindow - - Input @@ -1279,6 +1275,10 @@ This program cannot continue. Make a Donation... + + GPSBabel + + Map diff --git a/gpsbabel/gui/gpsbabelfe b/gpsbabel/gui/gpsbabelfe index 669285725..273fde322 100644 --- a/gpsbabel/gui/gpsbabelfe +++ b/gpsbabel/gui/gpsbabelfe @@ -1,5 +1,5 @@ #!/bin/sh -# $Id: gpsbabelfe,v 1.2 2009/09/14 14:25:14 robertl Exp $ +# $Id: gpsbabelfe,v 1.2 2009-09-14 14:25:14 robertl Exp $ # Copyright (C) 2009 S. Khai Mong . # # This program is free software; you can redistribute it and/or diff --git a/gpsbabel/gui/gpsbabelfe.ts b/gpsbabel/gui/gpsbabelfe.ts index bb73fc3d2..441bf2630 100644 --- a/gpsbabel/gui/gpsbabelfe.ts +++ b/gpsbabel/gui/gpsbabelfe.ts @@ -402,7 +402,7 @@ p, li { white-space: pre-wrap; } MainWindow - MainWindow + GPSBabel @@ -634,144 +634,144 @@ p, li { white-space: pre-wrap; } - - + + default - + Select one or more input files - + Output File Name - + Error reading format configuration. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. - + Some file/device formats were not found during initialization. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. - + Input and output formats do not support %1 - + Input does not support %1; output format supports %2 - + Input format supports %1; output format does not support %2 - + Both input and output formats support %1 - + waypoints - + tracks - + routes - + There are no input options for format "%1" - - + + Options for %1 - + There are no output options for format "%1" - + No valid waypoints/routes/tracks translation specified - + No input file specified - + No valid output specified - + No output file specified - + Process "%1" did not start - + Process exited unsucessfully with code %1 - + Translation successful - + Error running gpsbabel: %1 - + Are you sure you want to reset all format options to default values? - + About %1 - + One or more data filters are active - + No data filters are active @@ -1368,37 +1368,37 @@ This option computes (or recomputes) a value for the GPS heading at each trackpo UpgradeCheck - + HTTP - + Download failed: %1. - + Error - + Invalid return data at line %1: %2. - + A new version of GPSBabel is available.<br />Your version is %1 <br />The latest version is %2 - + Upgrade - + Do you wish to download an upgrade? diff --git a/gpsbabel/gui/gpsbabelfe_de.qm b/gpsbabel/gui/gpsbabelfe_de.qm index b2a80d69557add7e573f8df1a7d1147705fcf27d..9e879819a6b376a50c34a14e5b4c826f20f2cd89 100644 GIT binary patch delta 1804 zcmX90k$c@Xbea-1W;h{BG}Fe&lI2iJ9do7BSW>y9bSg6) zOG?9B9VtdCOA0wzW{jmF9A_}nIG97`&Hd~7e!uVcd*A1M-sgM2!_~}#BTRvfl~bW@ ztZ^j3WCN?G5bh>i4)8aC;tha6?~31Auwwux042e6#zgxaK5ukJg+ujP) z7lZ9|1?)9oZ{-30vn?1~Yr*;!uzwT)<-TB_>j0xX!}2g9#)2XJ;Kr;1PVEF2b{^Q2 z32xq0fc*e2v6R-0;C8UU*m2+v65(cmtBwP5CGb@Y5gP@*mWUP406##;dL@M5NFurl z!a$soeGp13341X-xf@2rIUqQ$0*Jkfa1W|F{ywIcBoIRlA{UnfjWLM4bd#7?V~(r^ zX!1o=8wHjh!on3NfSfQaJWND#?jTx0m78>kt9S)$9D~(KCL&UScmu zrJhiHIe=5>g~7667;3?gbI31w2!vaqu+;__?SsRvFNshBs-9*5$xC34l1Sq9X#FvU zh&?p<%G~t6Ryo?^fV>yElu`_I3g4rHrfN52X4F##Q@0 z;N!%2g&JtTfzhw80TfzBUqRjTH8O!&4B)(k`TBF*W+vi6Bz3KjS@^tw*m2Co+C4x* z&UWTuLnm;thv~V#2+$~*cOCYCT?D(T-J6QO!>0LV18y7GjG;ux`8d0!R!`!rVGp)Z zfV7!xjn@IdFO;phMr%7K_Lr>rBXeG&d=r;khGr*tT9m!S#HK;!n7Z_ z2<8=;s+Wtz5J3NdOFBut_1Mg<=gdHynae%aLg)8$MVATH{uUe?XF>nlT-jBMBiqeY z`q90qx445gl~k4kXFicha{kBFFD03b9(7!Ox-&Js(Sp`83+me~7~I1(M3K%J-*DHS zb&>wBx&BB00E1h&Pjg)W+eY5gn!Mm9@MHHx0_R%!1zR7}r<%gY{6z(LPUmA|NFMhE zdd7g&Z8yT1^0>&eYS zcL|>rvMv@vPj01(qJ&v|58$E|<_D|=O3Q>yGZm6>R>;<8k=q-E?cS7#+bn!m$dE0R z4Wl?-eu8-=5gRd7pu&x0`#Pb!lp1ARA^cnHL;m|t)NW4(M#{v|mx(}Nrs#deKtt%Z z7!XVjJF{GzymdM`>V~-Bs0s)fCN5{mVdLkCD>S5#M-jD*<#SMQlKvE}R-F?8JPih#LyjF?Q z&D+61`grN?)MG$^LhhAA!j;M7`n6X9Zx?yc+-KDKv8FuUQGZ6Bx`|lDe<81C>2yn` z{PYfDZI~&4k~kCC(yH)GolK5)RCq0lp{zSi_jpHZPeoPNWng%|;!PsuF8kS}5*&=4 zPnBbu&ym*U%8B+m;HwPfs$9~x{GhVv0%@p-SMFW>l0H60*)}kVPMuXTHPi!pvr73i zh};KN@_W)gBwCg4Nz$a9Rh?WDNK$-K)d%^|#JZyD8{PygcT=mosFX>S>IuC=$UL#? z@MS$Pz&2F9xRXYnE?J$fB`sWDt20LtKh{;fV_G-;aSGJUeUy-MQQv+|*wkgZC)io% zY5d>4BCA}{1RXsDOu1{~L`R2gO^2U>{z$2s?zT=~$9qj*EyXbPF9WVPn0~XLWZo!t LXwBO^9gh4D1J(fw delta 1845 zcmX9<3sj707=D`nK36nMwCSR<4jZ!Twz?=1BbV;l-O=jeQq)dVqS)L^ z%NdS@T_&L23gUtR0rc7(+Sw1k{ z6bCQ`!16-E3c?0}zX4RW0D?169caVLeK?Mu^J$HlPz7YC1KT9XiXH+=7qFMk0nN9; zcIyEr4cK2wfw5*A#{Xl(6D-) zQ+)?QO+69!hhs($Oh|}FXhI#3;EZUmTws99suE_NWFe1k87^VT={~*)9?MJk_WuHXZ0rpl|V9<16s6iI;p%;jHX)cxN zOs`~_iZK)`SXOMk3aET#?*lAU#_bGuo_3%1VFm<~x|Qb`*B93T^vuVnzYeaz&Kaji_uy;!Q+HD>P9GGZ6STxi+? z%qZ$)?xd&CLWX(J(hXeHGmow&0U9Oqw$lmF#jt6Ye1N*aY)(J{;L*b74I*N0FWJH- zKN9H(ySJSJ<&?9H-g|(60`oFPXLs0K$at7?xB%^8z<8evZZuQnBDtyIggHNRG0bxy z-=B+xJ>dT-XFN_7^=jp^I14%96<2(?mDbih@FZbY;3}Zzu8?mbj!6&- z{MM3v-w7LiC@S}z@G*Hqo3O)yZ0?;cSe6ls!Gna4IT_vvJvAh_sZn@UHJU`I6QOP2Ak6qjl!dC5yO z`o5-guZp>M7+_+6xY~Xwkl872I5d#jfE6pNh5`M`#p)5q0MBp4mR)63@fNXlG^Ob} zQ0&NW1;!VMo$YNvqPzJ1z(XLSUXm`(q0(L~m{Z@4WJ`3d`UpxWMrkM+Q z7rzhk>@~zGalX8PrPZxg`Kb~jZ77%jnKF%r45t{G9S-;WVn0-}yNLnstkgOvL6;2&e61YXMBlwVm7dnK)TOn`ASYj7(kW$HF-czg zSh@8)NvlXyRwh5A=9;K%@0&O+P%({E8YhcN`8b3e7^cejmr4@0UA1{6DQ3!r>iCLa z(l}Jr95R|}rB?Mio&lCDR;#a5lH(t#$Gxy8Q|(kor;_OgMyQj!X|(wsQ?GWd0Q3fR z{xBlO>eVHm_0T`dRkgL34&;WbZ@nZut5yI0YZ-ZCk@|VaZtAQh8m)06d811+_U&^h z@RM2-a%dkA>1=*4xD092bOsnG>ugO=dpA%Tr0H# MainWindow - - + + default default - + Select one or more input files eine oder mehrere Originaldateien markieren - + Output File Name Zieldatei-Name - + Error reading format configuration. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. @@ -479,7 +479,7 @@ This program cannot continue. Das Programm muss abgebrochen werden. - + Some file/device formats were not found during initialization. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. @@ -488,121 +488,125 @@ This program cannot continue. Das Prgramm muss abgebrochen werden. - + Input and output formats do not support %1 Keine Unterstützung für %1 im Ein- oder Ausgabeformat - + Input does not support %1; output format supports %2 Keine Unterstützung für %1 im Eingabeformat; Ausgabeformat unterstützt %2 - + Input format supports %1; output format does not support %2 Eingabeformat unterstützt %1. Keine Unterstützung für %2 im Ausgabeformat - + Both input and output formats support %1 Ein- und Ausgabeformat unterstützen %1 - + waypoints Wegpunkte - + tracks tracks - + routes Routen - + There are no input options for format "%1" Es gibt keine Eingabeoptionen für das Format "%1" - - + + Options for %1 Optionen für %1 - + There are no output options for format "%1" Es gibt keine Ausgabeoptionen für das Format "%1" - + No valid waypoints/routes/tracks translation specified keine gültige Angabe von Wegpunkt-/Routen-/Trackfiltern - + No input file specified keine Quelldatei angegeben - + No valid output specified keine gültiges Ziel angegeben - + No output file specified keine Zieldatei angegeben - + Process "%1" did not start Prozess "%1" wurde nicht gestartet - + Process exited unsucessfully with code %1 Prozess endete mit code %1 - + Translation successful Konvertierung erfolgreich - + Error running gpsbabel: %1 Fehler beim Aufruf von gpsbabel: %1 - + Are you sure you want to reset all format options to default values? Sind Sie sicher, dass Sie alle Formatoptionen auf die Vorgaben stellen wollen? - + About %1 Über %1 - + One or more data filters are active Einer oder mehrere Datenfilter sind aktiviert - + No data filters are active Keine Datenfilter sind aktiv - MainWindow - Hauptfenster + Hauptfenster + + + + GPSBabel + @@ -1524,32 +1528,32 @@ Diese Option generiert für jeden Trackpunkt einen Geschwindigkeitswert. Sie wir UpgradeCheck - + HTTP HTTP - + Download failed: %1. Download fehlgeschlagen: %1. - + Error - + Invalid return data at line %1: %2. - + A new version of GPSBabel is available.<br />Your version is %1 <br />The latest version is %2 Eine neue Version von GPSBabel ist verfügbar.<br />Die installierte Version ist %1 <br />Die neueste Version ist %2 - + Do you wish to download an upgrade? Möchten Sie die Aktualisierung herunter laden? @@ -1558,7 +1562,7 @@ Diese Option generiert für jeden Trackpunkt einen Geschwindigkeitswert. Sie wir <center><b>Eine neue GPSBabel-Version ist verf&uumlgbar</b><br>Die Version auf diesem Computer ist %1 <br>Die neueste Version ist %2</center> - + Upgrade Update diff --git a/gpsbabel/gui/gpsbabelfe_es.qm b/gpsbabel/gui/gpsbabelfe_es.qm index 2a7e074274e00a729c5573ae3404a9a0a709c368..667f5fbb5f12d42c7514b406eafdb770f17e8b89 100644 GIT binary patch delta 1872 zcmX90DlGOeG?F76ONj3s*=zf=<@)!%k;e!$Vj90B`ET)1BCs)q`DxFTlT1>oZj#8eZJ<^XK6q|V!`5nnzAG<=Hf$ubd;OT*l1Tj}LR6wv9kp8|Pa`O5f||)&>xs_2I&pF^bCfTm)=@*eou& zi5%Owm)pe|$Z;c=-`EC>y}=#tC0ugLjM3-KsMB#}15{_xM_h#`o!jNaRoPZhGJ-k7 zg>2ei!!;-BC_)=+x#qnNfctqf`dFAT_9Zi>G;=LcByT;>4UP=c;~3zkuipdw3b=cE8`)xHd@eUYE`as#?+1d9P$Pi_-fhA!UFCAjUPjIQVu9x3G0Cai2a2<()F zb^HxdK2M1B+5ucH7P1Z0h-?&c-E)ABIHACmE^@gk9Lpf0zTv_nrQ)W9vL~osRH{&U zNuLJnSS}deB&I>r!XqW(orG(pWL;yP@aG8+lJ2-@Uyu&09uw#H5}~bX(e?5Rfb(Ob zmp=vV?o(pG!4MiFIx)Il4Wx{TTiH6Y>_>5%6)E=oS~1z}J}FWt?)i=Z(x%0|HqQVb zx{8PN^)u>=TAt-(|!cj{3NxQ2JpgU>8o%2f!a~&`@lv(SE6*zBZ~)aDBX7q05Pe`WgAAw z@=@ig)-P%NWXqrPTK6zzMi$XN>aDD0>D0tx?h38JE)#DRbK3_@+!|EN&ZnSo#h7XS)@wI zCl8E9Rb~>^XnIw3yptsN_*YeuKw~O2Q`KV{S0iUsldT3)^q5J;btb>bX{Vyk}77XVMz>ROKxxTLk3 gXrLM$A19I7{bZc>eZ%zCG=*W7r4V9Bj$GgHKZ^)Ni2wiq delta 1830 zcmX9;3s{YJ82@#?`{|q$DraG$ga}0{N@CRN(S_({l9U{dYF#AF(lpmhd{LO&nkbd* zpj>8Dni4Y1Glnpi9%U!7HRRcw&hwn__x=Ch|Np+f_xE1fHnQh8vAGr|>$h6Y&-?;l zvVr}-5#|wg0{l&&p$ZT_1unbv;CmzC1X^bT2{NG?NJ|D9B`DTD2F4!-Ta*rX3;}z& z7In}L`MJ(%0sgU_46{*eo0Hu-^Vbp)IhJ?Jx|2NTDG8y*j|`~uGV zB57=P+A)b@{?C7v{w0wsc*f2$>oZG&TiByf?DWw z_;9&Qp|ww8xH>x9`jqM8LE_c_z}U3k0NgAYJL|83SIvx_O)RiLEw?GOQ`R#cYZxHV zn(?c?4!EW=fe%R12nQyjH5aHk%hZ){q<{tUYx#Ck#D}??90vqsFpo|*0iBleBt~l= z%C2z927(u}8GXrjU^M$}xf8G=nk}lQTO|Q(sl!2FVT`zi2>djR3x+umd70B!Qc^-La?3dbu&qD0u7X529^-a25V}6? z!SJpgjIH4ITqQdrj&g-AbZ_}`uE?U0lAp&Jj%U&NVy%OuC?5tBDIp2vD)yL{HX20REmXs_=YFIm;rp`Ln0S?g`Xcuk2v#ScbfW^pWqe+RXdHO#Uy@ z>$(u?mIPdB7P1V)C9l7b?X(8CSR!m1O;$%e5%SW8P$vcnA487v5%zpS^%-_XICw4@ zNZKeEmJuuO55mV-qLvHIyGieg>%!{-XOiHdXtOB=_}nNCr6$6XFmd#ianz{}y+k)J zDvGu^aq5N{)bg=nco~g>1b1->TMEp#7nhom7-RiKz2h4SKSxZz%K$09;!5*Dz@c<; zW0@tDb%dB-Fc_G)UfgMag5>ZQPanvogcpc4&J=dQV6h>q2GI2p8|yDp4*kWh;>Vba zw7}lSjkYIJ4xFQ-UMbXly)TF2mBsLr@JSk zycx{Z*Dd{S8!5O9JoEFNyi(JNAJMB`YttM{UvXw_z zI^D5ac{Yc*N0}?1#svW<^GrvkO$Fu|O&u0SlGmMb7eB0bt7-9#2AZ0_rf=fN_q9{< zc)>a|UNyY>0txPf%Dkr7*gRiN zVmy6MjMl8QA?boPX|e`WI1XQHa(tVC0|PbH9Ykc*R?Y2KgvLjjdv|iFa`H7s&mXDl zdYf73r%~m!o4IxxVT!gpW}an-fK+dJo@hO=*{soJ9N@y5HP<%*=c3Iz%E@ef&P((&Pg^76z-( H+2#KOJ&7<9 diff --git a/gpsbabel/gui/gpsbabelfe_es.ts b/gpsbabel/gui/gpsbabelfe_es.ts index 6f276ca79..0d2a9d92b 100644 --- a/gpsbabel/gui/gpsbabelfe_es.ts +++ b/gpsbabel/gui/gpsbabelfe_es.ts @@ -505,151 +505,155 @@ p, li { white-space: pre-wrap; } MainWindow - - + + default Defecto - + Select one or more input files Seleccionar uno o más archivos de entrada - + Output File Name Nombre del fichero de salida - + Error reading format configuration. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. Se ha producido un error cuando se intentaba leer la configuración. Compruebe que el núcleo de "gpsbabel" está instalado correctamente y que se halla en la RUTA actual. Este programa no puede continuar. - + Some file/device formats were not found during initialization. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. El formato de alfunos ficheros o dispositivos no se halló durante la inicialización. Compruebe que el núcleo de "gpsbabel" está instalado correctamente y que se halla en la RUTA actual. Este programa no puede continuar. - + Input and output formats do not support %1 Formatos de entrada y salida inadmisibles %1 - + Input does not support %1; output format supports %2 Formatos de entrada inadmisible %1; Formatos de salida inadmisible %2 - + Input format supports %1; output format does not support %2 - + Both input and output formats support %1 Formatos de entrada y salida admisibles (ambos) %1 - + waypoints Puntos de interés - + tracks Registro de trazados - + routes Rutas - + There are no input options for format "%1" No hay opciones de entrada para el formato "%1" - - + + Options for %1 Opciones de %1 - + There are no output options for format "%1" No hay opciones de salida para el formato "%1" - + No valid waypoints/routes/tracks translation specified Se han especificicado puntos de interés, trazados o rutas no traducibles - + No input file specified No se ha especificado el fichero de entrada - + No valid output specified El fichero de salida no es válido - + No output file specified No se ha especificado el fichero de salida - + Process "%1" did not start El proceso "%1" no comenzó - + Process exited unsucessfully with code %1 El proceso terminó sin suerte y con el código %1 - + Translation successful Traducción realizada con éxito - + Error running gpsbabel: %1 Error ejecutando gpsbabel: %1 - + Are you sure you want to reset all format options to default values? ¿Estás seguro de que quieres volver a los formatos por defecto? - + About %1 Acerca de %1 - + One or more data filters are active Uno o más filtros de datos están activos - + No data filters are active Ningún filtro de datos está activo - MainWindow - Ventana Principal + Ventana Principal + + + + GPSBabel + @@ -1536,32 +1540,32 @@ Esta opción calcula (o recalcula) un valor para la velocidad de cada punto del UpgradeCheck - + HTTP HTTP - + Download failed: %1. La descarga falló: %1. - + Error Error - + Invalid return data at line %1: %2. Ha devuelto datos no válidos en la línea %1: %2. - + A new version of GPSBabel is available.<br />Your version is %1 <br />The latest version is %2 Una nueva versióon de GPSBabel ha salido ya. <br />Tu versión es la %1 <br />La última versióon sería %2 - + Do you wish to download an upgrade? ¿Quieres bajarte una actualización? @@ -1570,7 +1574,7 @@ Esta opción calcula (o recalcula) un valor para la velocidad de cada punto del <center><b>Una nueva versión de GPSBabel está disponible </b><br>La versión actual es %1 <br> La versión más reciente es %2</center> - + Upgrade Actualizar diff --git a/gpsbabel/gui/gpsbabelfe_fr.ts b/gpsbabel/gui/gpsbabelfe_fr.ts index 80b84b321..dce15ce66 100644 --- a/gpsbabel/gui/gpsbabelfe_fr.ts +++ b/gpsbabel/gui/gpsbabelfe_fr.ts @@ -444,150 +444,150 @@ p, li { white-space: pre-wrap; } MainWindow - - + + default - + Select one or more input files - + Output File Name - + Error reading format configuration. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. - + Some file/device formats were not found during initialization. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. - + Input and output formats do not support %1 - + Input does not support %1; output format supports %2 - + Input format supports %1; output format does not support %2 - + Both input and output formats support %1 - + waypoints - + tracks - + routes - + There are no input options for format "%1" - - + + Options for %1 Options pour %1 - + There are no output options for format "%1" - + No valid waypoints/routes/tracks translation specified - + No input file specified - + No valid output specified - + No output file specified - + Process "%1" did not start - + Process exited unsucessfully with code %1 - + Translation successful - + Error running gpsbabel: %1 - + Are you sure you want to reset all format options to default values? - + About %1 - + One or more data filters are active - + No data filters are active - MainWindow + GPSBabel @@ -1417,37 +1417,37 @@ This option computes a value for the GPS speed at each trackpoint. This is most UpgradeCheck - + HTTP - + Download failed: %1. - + Error - + Invalid return data at line %1: %2. - + A new version of GPSBabel is available.<br />Your version is %1 <br />The latest version is %2 - + Do you wish to download an upgrade? - + Upgrade diff --git a/gpsbabel/gui/gpsbabelfe_hu.ts b/gpsbabel/gui/gpsbabelfe_hu.ts index 5a3ee9bd3..448437966 100644 --- a/gpsbabel/gui/gpsbabelfe_hu.ts +++ b/gpsbabel/gui/gpsbabelfe_hu.ts @@ -444,150 +444,150 @@ p, li { white-space: pre-wrap; } MainWindow - - + + default - + Select one or more input files - + Output File Name - + Error reading format configuration. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. - + Some file/device formats were not found during initialization. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. - + Input and output formats do not support %1 - + Input does not support %1; output format supports %2 - + Input format supports %1; output format does not support %2 - + Both input and output formats support %1 - + waypoints - + tracks - + routes - + There are no input options for format "%1" - - + + Options for %1 - + There are no output options for format "%1" - + No valid waypoints/routes/tracks translation specified - + No input file specified - + No valid output specified - + No output file specified - + Process "%1" did not start - + Process exited unsucessfully with code %1 - + Translation successful - + Error running gpsbabel: %1 - + Are you sure you want to reset all format options to default values? - + About %1 - + One or more data filters are active - + No data filters are active - MainWindow + GPSBabel @@ -1412,37 +1412,37 @@ This option computes a value for the GPS speed at each trackpoint. This is most UpgradeCheck - + HTTP - + Download failed: %1. - + Error - + Invalid return data at line %1: %2. - + A new version of GPSBabel is available.<br />Your version is %1 <br />The latest version is %2 - + Do you wish to download an upgrade? - + Upgrade diff --git a/gpsbabel/gui/gpsbabelfe_it.qm b/gpsbabel/gui/gpsbabelfe_it.qm index b8674f24697d6cf70db0cb78c3190e8f1d04a9ce..eb9befcc398a62fd1ba05a2d1a7e78c67edf7a4e 100644 GIT binary patch delta 1890 zcmX9|4X}l4fgne) zm+OG1Ibd5HfDk9JH+BNc{;;4S!GcfEfxVRj=x(k8`^XjW3ASM9*A`4|1~)1R=v@bH z@&(}ZC2+HYfN{gX#UG@#3EU1Ah#Ls5kcj^`72L5{pn5m>Vul1{gD)e3t*6182?ZX2 zpb019%@E9S+FnCAm=7JUM`Ccw9l&r6n%F$TTuk|hlpN6E)7<&M%>aZi_zrkBAK{nU z>0vo$%4>m_n-I}Jfql{twe%El?qft15s_*wqOC~zl|_in>jr+hg5`;Nde90f=6iw9 zvC3c%EKy=rrMaw)N#9i+rcN|iEMwV%J63~Xq$`J}Q?Uy^4-T}@J)qf?o9Xwp_|55`?lgoomgj1Kv zL%Zno{CIt-+*TLPaP@Td#R#UqH@Vj;W9)j`06!nbVc2@$l{@2Lw~)w2FwOz)w7-{e zTU|n;I~lh;%Ffab#(NV3M9gKT*IWZMc}&RdaLUSZChAcRaT&|h|G<$c*38ASy=2k? z=C7(2$mENdyVv4?Fux~^sc8r>qk&Dj>;l|MVN*Rf19LC3>F*M;h{NobGB@(1hb?TN z04I%XiE{yvc$_V{O6wWB*yEe#P~GKQu>Gq35HnJ@mh-eZ0TfK)yi3UYmtovz{)8tV zav@ANQ02mfV*s$&j!Ued9LD_3t>%nCZYsC+L@k}~=Jqub`l&4#r?FsC1$U^K;&?3O z@;&L^`rBNgO+MAi8P0fW1IcgWDi@Pox>yIUGR+>CIMafGLoFEJW5G3rTvY`5eX5?j z+SNww(#^f@d;&}^=ibcv5SVVoJN2UynCr%m*&9yPE%K4s_W-ZEy!KBL5c`~u(ULvd zTt1y=2;b*-P6z-dwD8{_b3rs-mh%s7!+_aZ{Ie@};XOn^SF@kX!(FzR|-pWq+Rk(AIvQ$|u{A2JSKe9x-?J1P*L847KKsXd-z@??^VubZ(+(!2=$W{pPtqTAbuKX%~X@*hC>3#rOHf8F~_?HwAxct-jy=mZh!QaESQOzzMq+*USIW0@4b zv$}|JU%FyS&3Wp?_bg$AOH1cGy|p2ZWbj#j;oFie-H9A$pX zH%94|XLf0pa>5W-VB=(E(pE~#EpKId0>wC2uH08oS@0dD+`r&4HLsJh!92ivi2~T~rk-ys50}RF%FSG^V+|?s!VrXRr4WZTo4h$CW6r(vT0W#5!ayi1o7`*3!%(zRTnQeS;-mByP1BymU AF8}}l delta 1890 zcmXX{3sj707=C8{`!q8xMJ`J#iluc_x>2)9xvWdAT)I#pYN&~dC`@6IYy6_iv7s&6 zE-u5OV_kBMBua8`<#OygHj+DM-^|WAGtYeA|9$WGywCf5?|)_&o4uROv{tOy+$q9% z9bi@hdy5FS5>^9zJy7Qi2t5c(zoJ4MMd(T6HXvRmTmd8}0`*IwT-6Nd8o(AU2K*hs zUOo%Fx(Bw_9tao!wqXNc_#dPsp&j$hCxd^r)U$b z6GVi&LuijvKL$cx0gR|GLf51wAg3pMBJ+XlCm7kEGRdvR*qj+aV--vS)zhWJ>Shy)|4eV^YO zEXeK+%n8AQqrK&q3MqeVcQV|0TKm?(bo3(iu8(KzUe*D_ycv7jWx(e&#@=ogku78#hr7^x z7UQ&#EaBbEIOS7yV*4;&D;OZSnE9#l8sL-91Uv|$svKuRpJx)6<;?ltITB?mbD=zo zL^{CSNsOlT1DJ;uwNNOPCfS>@8FrdofOH*OR7Kkkf-Q9{ zq~kuZrB`V@W+S_A#T0T|ff*aVm9v<>#`Bz;^?smmJ?B+Qihs!G#`zK+^xy)R7P3q# z7X&LHCZ3BuLY0ejBkA^U8#k zPAh<#vBJ866xF>%*qYpjBn=e4ilBcl?C3(ap5Y=Co=5~zQv_2Su?qAPzUDZmpU{*? zB{`-MUS|&`QErHK>ym&8T||dVbb8`Kao`mfns==gJ$%SYZy$@k8Dpta$YMyDhTPs) zoWqipVlInwElG@_H^kUMZGdN>xcCkOEVUFb-I*kg{KL_;Dk!W{(sW`UQB}K?=(#AU*F&u>tMRXGyWMUjidEQd&$c zb&y7R9B(r^PFj0}=(Z(FS%vj5U%hU(H$x^dG7I3!AU{r6MzbW=I5 zG6FX@sGJgNfGB^JZqhTV=0&-T@9C`fRVAkpx!nG$5|);KaZnv!PvrG~s-8p#0w=y$ z3`q6`qPJK$&J3qxAIP8iz8#t@it8=`<8v(9qUrEPTiI2xH9lAOt2|ALN2opW+Y{fd z9@1?Puv}IfR+G}VGSsPhig8M*-gcgp)%8}Kse13h0nN}FOw+J)L`(|b`m zZaVGy(M|MndZn#wB_i%)v^QT7ew?ShcRLgC>aK0k{YDpYsHJtRA6ciw(*0cvEbuPe zQdhPISk_sdCffFlvaEJ<0e*D0Y^tgSE;w7ZmQ&c8d_5FmyeU_743rjEVwMQ{@bp!Uo31xZ(Ho-TlV#)lo~F9UmVN&L(V#-f diff --git a/gpsbabel/gui/gpsbabelfe_it.ts b/gpsbabel/gui/gpsbabelfe_it.ts index ff92d281d..38f1fa54e 100644 --- a/gpsbabel/gui/gpsbabelfe_it.ts +++ b/gpsbabel/gui/gpsbabelfe_it.ts @@ -423,9 +423,13 @@ p, li { white-space: pre-wrap; } MainWindow - MainWindow - FinestraPrincipale + FinestraPrincipale + + + + GPSBabel + @@ -656,23 +660,23 @@ p, li { white-space: pre-wrap; } - - + + default predefinite - + Select one or more input files Selezionare uno o più file in ingresso - + Output File Name Nome del file in uscita - + Error reading format configuration. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. @@ -681,7 +685,7 @@ This program cannot continue. Questo programma non può proseguire. - + Some file/device formats were not found during initialization. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. @@ -690,115 +694,115 @@ This program cannot continue. Questo programma non può proseguire. - + Input and output formats do not support %1 I formati di ingresso e di uscita non supportano %1 - + Input does not support %1; output format supports %2 L'ingresso non supporta %1, il formato di destinazione supporta %2 - + Input format supports %1; output format does not support %2 Il formato in ingresso supporta %1, il formato di destinazione non supporta %2 - + Both input and output formats support %1 I formati di origine e di destinazione supportano %1 - + waypoints punti di interesse - + tracks tracce - + routes rotte - + There are no input options for format "%1" Non ci sono opzioni in ingresso per il formato "%1" - - + + Options for %1 Opzioni per %1 - + There are no output options for format "%1" Non ci sono opzioni in uscita per il formato "%1" - + No valid waypoints/routes/tracks translation specified Non è stato specificato alcun punto di interesse/rotta/traccia - + No input file specified Il file di origine non è stato specificato - + No valid output specified Non è stata specificata una destinazione valida - + No output file specified Il file di destinazione non è stato specificato - + Process "%1" did not start Il processo "%1" non è stato avviato - + Process exited unsucessfully with code %1 Il processo è terminato con il codice di errorre %1 - + Translation successful Traduzione terminata con successo - + Error running gpsbabel: %1 Errore durante l'esecuzione di gpsbabel: %1 - + Are you sure you want to reset all format options to default values? Si è certi di voler reimpostare tutte le opzioni dei formati ai valori predefiniti? - + About %1 Informazioni su %1 - + One or more data filters are active È attivo uno o più filtri di dati - + No data filters are active Nessun filtro di dati è attivo @@ -1426,37 +1430,37 @@ Questa opzione calcola (o ricalcola) un valore per la direzione del GPS in ogni UpgradeCheck - + HTTP HTTP - + Download failed: %1. Scaricamento non riuscito: %1. - + Error Errore - + Invalid return data at line %1: %2. Dati ricevuti non validi alla linea %1: %2. - + A new version of GPSBabel is available.<br />Your version is %1 <br />The latest version is %2 È disponibile una nuova versione di GPSBabel.<br />Versione corrente: %1 <br />Nuova versione: %2 - + Upgrade Aggiorna - + Do you wish to download an upgrade? Si desidera scaricare un aggiornamento? diff --git a/gpsbabel/gui/gpsbabelfe_ru.qm b/gpsbabel/gui/gpsbabelfe_ru.qm index 9b34020ff642752eec82a3908e4828f9aa373d76..19e8ad9600d04712663dd81db4c626044dd76878 100644 GIT binary patch delta 1852 zcmX9652#TB!a%|lGk!Qp=uYu1Al68@6o`)lYJDI}eFAtK0-L)T&^Lf> ztOi;agKc&MW~YIDun&lIFyn#AW^CO9_E9=uXmkYIF$$RY-i$sk%otYqwYoKu!^4k)D(af?i2Ya`SDtpldp$>#PDdgaS}+bKKr zS7VV(GhEAXHI)0jl^koPo}G-Nb}R6PV;t>P5Z4UjE1AZ?F&^6)V1a^} zRe6W9yqI}^kfdREnBb0d;OYgY<}61FL@>3*nWRWH^SGiJ=#FAq?<@ztImYxf^#^90 zVPhIyfF=ia)A(c{=qj7|C9zmApG_$qP5s|wbL;8-yim5#IR}VnXA5sr+;>I{dv1Fm zFm;|8>rNW87$?JUZoKt*AZs?~QAk3+e9z6%6XxyV<}q)9^A4OptbpZnxu`N4SjZ)A zBWD5*&gFKTucATj)qa;L`Adz)u+xz?x17#BEGNfPBJ zapkK>97D)Ut~|jWaCbH1lzKBR*P3zNX|5uO)Ge6C-EO~2ccX&)^yCdNP09VYzya_c z$dBwp^A1|Xf1T-1R?g)Y?RpAKu;Ii0qy`qB;FpAvKEauMBF_-o@cSlC1>DZ^CkkB1 z!X0z?ml{97ubcnmHVUXt6D)2~+!H9U3>_TeB#hcf7WIBCd{#&wEle%j1#GGn=JTy2 z{5>JiZ5>c|TSzidBN?7T^62frb%U_Sg$^25FJ#0MQT-?3vr^&Dg)AGY7aAkvT!~u@ zY;+V%(Ztl}xbRtt6$6EqV>G$qJfZuDD@k`nwA-^Dn42dKZ6HE1n?;wKV*%GeqMMF< z*6t?iclpp3nJ+FXqRq4Jfw-D2q>-I9W^o!rx|m=!7|8io++EaBkzS2liT>zkaAjzAky~qH` zI*#((TFq!2CfO%bHyc8wq2KHWl6FcV!JmLxj|NF0yG{WgrbtoqdJ}AB%lT?PRw$4I-&7~olpl$mpnh<6*e@R}h*q~E;G1FPNT z&Z!1kFbetTb+>>eesa$R?KFP1v6R=2mgMobnBw$Z&H8KJDM>wU0A z*=2hT_~Ermb(dO>PExsdT9MHPsJtV|h|^7~@MhY8-@aC@jiLYJx>N~v8NkBtRY^mr z9oGca-kB}*m71ce>>?uLqE!$7BJ8+moGfbmMfHT9x8$bFYR{rGWbfJPsm?CISe-f+ zv2>pvse?dqoSV@Z}5>X!Ou;G&@JDyHh!Ya(gZbu_ra{Y`6kw^^9> N%d7lM2SZ2Z{14#TIZ*%r delta 1839 zcmX9<3sj707=D`nKFv&4G1{{$BKJ#C6g8VcHd{oYo6J&FDvly*X;bb|`Q>^FC$**P zo?&%zPhzUIIk~L0c5`WM#FpZ?tajhgoHOV7zwiIP_j}&weZKeaPG`?=VY6&3wrBTS zlF|+^>A*1^;XXnGz~2Ju<^aN%gmu06?h&CIaLo!>CDZ(IATgfCyP??n7;xVYwr~TW zuLs*u3p~jM+vEUzlL_|DZXhb67qd6@;*&*?Eu0Csc!OJU1gIPjE`tTaD!~;J@s~6%A@V1FK?WB9epz^FDnZ z)*c)JMC``esv&Zxg|%D0`3Z=xM&=>XIjI8KwKl+_W)wNRBnG=s{4^Oj(G6puM4EP^ zc6%5xF~}Z@;kJPmTkU@Yg0n47!whU5ZBxC3x#%?7vrAB z01JGX*)=z5)l6pYpCsv$zD#g?7I5(uQ+JXh1&Ww!V@t;r0Fk5Qjf~dfk(|Q}Pl@Ix*;E3# z8Jv45Y1uxR^VJg;HF9&A4l+Xo=MQUOStb{AhH4V>kz2iORIVzL@>hh8kv&+gt%0jb8Un0o z<*EZou97X>FKx|a_78F_t4%q~kInH1UOeT4cC-SM2k>DJiCpMIen}W58hnRO<{82u ze)p8=fa^*ASjjjdw}*eOoe#|K=6hTnf!Zd);s%Z19u!!HP6>$=9M_S-W<3%7f5a`&|jZoFZ{pJrRnl z7RUWO5pW(Tx_XjJ+BS X@oG+~Y`agMn!Q;-QhJ$r=q}_3mQx_#FZIJs2%eP$&PounMIH3g{mRXVM?LH9yd>K3$-A^hYr-p*;Z zGVy!jw)efVgr(IT{gvl3hT}rfSM9pRDx>}X%(KO1tMK$GfN8md~6}OFqZXByhj-nW+{Z#ww zNZ6^rst$xxCkbd*namxfwNCY+#z=X$sF_kKkdK>M^;AbzO;ty^c9A2T)CupXK=GmK z%+aJ;dxE!U`oe1Nt5B-LZ6+@nwl;m;u5R5`--srU(JKx zvdB4InhxCwz~i2kP0S2ny|>lmw;ixVTaT5l><602kQa*s?Q%w0HBOpHf;_WoF*N~a zzqaZsr?@pj6!2a$9u_MC#tvYu*{Q4}JAw6Jb*u{pu>;vD=4TP~ MainWindow - MainWindow - Главное Окно + Главное Окно + + + + GPSBabel + @@ -654,23 +658,23 @@ p, li { white-space: pre-wrap; } Сделать пожертвование... - - + + default по умолчанию - + Select one or more input files Выберите один или несколько файлов - + Output File Name Имя выходного файла - + Error reading format configuration. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. @@ -679,7 +683,7 @@ This program cannot continue. Выполнение программы не может быть продолжено. - + Some file/device formats were not found during initialization. Check that the backend program "gpsbabel" is properly installed and is in the current PATH This program cannot continue. @@ -688,114 +692,114 @@ This program cannot continue. Выполнение программы не может быть продолжено. - + Input and output formats do not support %1 Входной и выходной форматы не поддерживают %1 - + Input does not support %1; output format supports %2 Входной формат не поддерживает %1; выходной формат поддерживает %2 - + Input format supports %1; output format does not support %2 Входной формат поддерживает %1; выходной формат не поддерживаетt %2 - + Both input and output formats support %1 Входной и выходной формат поддерживают %1 - + waypoints маршрутные точки - + tracks треки - + routes маршруты - + There are no input options for format "%1" Нет входных параметров для формата "%1" - - + + Options for %1 Параметры %1 - + There are no output options for format "%1" Нет выходных параметров для формата "%1" - + No valid waypoints/routes/tracks translation specified Не выбрано преобразование маршрутных точек/маршрутов/треков - + No input file specified Не выбран входной файл - + No valid output specified Не выбран выходной файл - + No output file specified Не выбран выходной файл - + Process "%1" did not start Процесс "%1" не запустился - + Process exited unsucessfully with code %1 Процесс завершился неудачей с кодом %1 - + Translation successful Конвертация выполнена - + Error running gpsbabel: %1 Ошибка запуска gpsbabel: %1 - + Are you sure you want to reset all format options to default values? Вы действительно желаете сбросить все параметры формата в значения по умолчанию? - + About %1 О %1 - + One or more data filters are active Один или более фильтров данных активны - + No data filters are active Фильтры данных не активны @@ -1423,37 +1427,37 @@ This option computes (or recomputes) a value for the GPS heading at each trackpo UpgradeCheck - + HTTP - + Download failed: %1. Загрузка завершилась неудачей: %1. - + Error Ошибка - + Invalid return data at line %1: %2. Некорректные данные возвращены в строке %1: %2. - + A new version of GPSBabel is available.<br />Your version is %1 <br />The latest version is %2 Доступна новая версия GPSBabel.<br />Используемая версия %1 <br />Последняя доступная версия %2 - + Upgrade Обновить - + Do you wish to download an upgrade? Загрузить обновление? diff --git a/gpsbabel/gui/gpx.cpp b/gpsbabel/gui/gpx.cpp index 8204d6bf0..86e6da4c4 100755 --- a/gpsbabel/gui/gpx.cpp +++ b/gpsbabel/gui/gpx.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: gpx.cpp,v 1.2 2009/08/28 17:08:55 robertl Exp $ +// $Id: gpx.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/gpx.h b/gpsbabel/gui/gpx.h index 53dab5196..0bcc543d6 100755 --- a/gpsbabel/gui/gpx.h +++ b/gpsbabel/gui/gpx.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: gpx.h,v 1.1 2009/07/05 21:14:56 robertl Exp $ +// $Id: gpx.h,v 1.1 2009-07-05 21:14:56 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/help.cpp b/gpsbabel/gui/help.cpp index 7abaf001b..98fa407f9 100644 --- a/gpsbabel/gui/help.cpp +++ b/gpsbabel/gui/help.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: help.cpp,v 1.8 2009/11/02 20:38:02 robertl Exp $ +// $Id: help.cpp,v 1.8 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/help.h b/gpsbabel/gui/help.h index 9cc3896ff..b9a929ac7 100644 --- a/gpsbabel/gui/help.h +++ b/gpsbabel/gui/help.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: help.h,v 1.4 2009/11/02 20:38:02 robertl Exp $ +// $Id: help.h,v 1.4 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/latlng.cpp b/gpsbabel/gui/latlng.cpp index e27f2c2e2..11e506cb2 100644 --- a/gpsbabel/gui/latlng.cpp +++ b/gpsbabel/gui/latlng.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: latlng.cpp,v 1.2 2009/08/28 17:08:55 robertl Exp $ +// $Id: latlng.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/latlng.h b/gpsbabel/gui/latlng.h index d02d6552b..a514e1dd1 100644 --- a/gpsbabel/gui/latlng.h +++ b/gpsbabel/gui/latlng.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: latlng.h,v 1.1 2009/07/05 21:14:56 robertl Exp $ +// $Id: latlng.h,v 1.1 2009-07-05 21:14:56 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/main.cpp b/gpsbabel/gui/main.cpp index 822184508..0e50b6ed7 100644 --- a/gpsbabel/gui/main.cpp +++ b/gpsbabel/gui/main.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: main.cpp,v 1.8 2010/06/06 00:49:08 robertl Exp $ +// $Id: main.cpp,v 1.8 2010-06-06 00:49:08 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "mainwindow.h" @@ -41,33 +40,6 @@ const char *pathSeparator = ":"; #include #endif -//------------------------------------------------------------------------ -static void installTranslation(QApplication *app, const QString &nm) -{ - QTranslator *xlator = new QTranslator(); - - xlator->load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/" + nm + QLocale::system().name()); - - xlator->load(nm + QLocale::system().name()); - -#if defined (Q_OS_MAC) - CFURLRef pluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef, - kCFURLPOSIXPathStyle); - QString pathPtr(CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding())); - pathPtr += "/Contents/MacOS/lang/" + nm; - // pathPtr += QLocale::system().name().left(2); - pathPtr += QLocale::system().name(); - - xlator->load(pathPtr); - -#endif - - app->installTranslator(xlator); -} - -//------------------------------------------------------------------------ - //------------------------------------------------------------------------ int main(int argc, char**argv) { @@ -81,10 +53,6 @@ int main(int argc, char**argv) strcpy(newPathEnv, newPath.toStdString().c_str()); putenv(newPathEnv); - installTranslation(app, "qt_"); - installTranslation(app, "gpsbabelfe_"); - installTranslation(app, "gpsbabel_"); - QCoreApplication::setOrganizationName("GPSBabel"); QCoreApplication::setOrganizationDomain("gpsbabel.org"); QCoreApplication::setApplicationName("GPSBabel"); @@ -92,5 +60,6 @@ int main(int argc, char**argv) MainWindow mainWindow(0); mainWindow.show(); app->exec(); + return 0; } diff --git a/gpsbabel/gui/mainwindow.cpp b/gpsbabel/gui/mainwindow.cpp index 172fdba58..d9016c9c7 100644 --- a/gpsbabel/gui/mainwindow.cpp +++ b/gpsbabel/gui/mainwindow.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: mainwindow.cpp,v 1.25 2010/09/02 03:10:46 robertl Exp $ +// $Id: mainwindow.cpp,v 1.27 2010-11-01 03:30:42 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . @@ -48,6 +48,9 @@ const int BabelData::noType = -1; const int BabelData::fileType = 0; const int BabelData::deviceType = 1; + +#define FAKE_LANGUAGE_MENU 0 + //------------------------------------------------------------------------ QString MainWindow::findBabelVersion() { @@ -111,8 +114,14 @@ static QString MakeOptions(const QList& options) if (options[i].getSelected()) { str += ","; str += options[i].getName(); - if (options[i].getType() != FormatOption::OPTbool) { - str += "=" + options[i].getValue().toString(); + if (options[i].getType() == FormatOption::OPTbool) { + str += "=1"; + } else { + str += "=" + options[i].getValue().toString(); + } + } else { + if (options[i].getType() == FormatOption::OPTbool) { + str += "," + options[i].getName() + "=0"; } } } @@ -171,6 +180,10 @@ MainWindow::MainWindow(QWidget* parent): QMainWindow(parent) connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(closeActionX())); connect(ui.xlateFiltersBtn, SIGNAL(clicked()), this, SLOT(filtersClicked())); + connect(ui.inputFileNameText, SIGNAL(textEdited(QString)), this, SLOT(inputFileNameEdited())); + connect(ui.outputFileNameText, SIGNAL(textEdited(QString)), this, SLOT(outputFileNameEdited())); + + ui.buttonBox->button(QDialogButtonBox::Apply)->setIcon(QIcon(":images/runit.png")); ui.buttonBox->button(QDialogButtonBox::Close)->setIcon(QIcon(":images/exit.png")); @@ -194,6 +207,14 @@ MainWindow::MainWindow(QWidget* parent): QMainWindow(parent) ui.outputWindow->setReadOnly(true); + langPath = QApplication::applicationDirPath(); + langPath.append("/translations/"); + + // Start up in the current system language. + loadLanguage(QLocale::system().name()); +#if FAKE_LANGUAGE_MENU + createLanguageMenu(); +#endif //--- Restore from registry restoreSettings(); @@ -218,6 +239,108 @@ MainWindow::~MainWindow() if (upgrade) delete upgrade; } +//------------------------------------------------------------------------ +// Dynamic language switching courtesy of +// http://developer.qt.nokia.com/wiki/How_to_create_a_multi_language_application +// We create the menu entries dynamically, dependant on the existing +// translations. +#if FAKE_LANGUAGE_MENU +void MainWindow::createLanguageMenu(void) +{ + QActionGroup* langGroup = new QActionGroup(ui.menuHelp); + langGroup->setExclusive(true); + connect(langGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotLanguageChanged(QAction *))); + + // format systems language + QString defaultLocale = QLocale::system().name(); // e.g. "de_DE" + defaultLocale.truncate(defaultLocale.lastIndexOf('_')); // e.g. "de" + + QDir dir(langPath); + QStringList fileNames = dir.entryList(QStringList("GPSBabelFE*.qm")); + + for (int i = 0; i < fileNames.size(); ++i) { + // get locale extracted by filename + QString locale; + locale = fileNames[i]; // "TranslationExample_de.qm" + locale.truncate(locale.lastIndexOf('.')); // "TranslationExample_de" + locale.remove(0, locale.indexOf('_') + 1); // "de" + + QString lang = QLocale::languageToString(QLocale(locale).language()); + + QAction *action = new QAction(lang, this); + action->setCheckable(true); + action->setData(locale); + + ui.menuHelp->addAction(action); + langGroup->addAction(action); + + // set default translators and language checked + if (defaultLocale == locale) { + action->setChecked(true); + } + } +} +#endif // FAKE_LANGUAGE_MENU + +//------------------------------------------------------------------------ +// Called every time, when a menu entry of the language menu is called +void MainWindow::slotLanguageChanged(QAction* action) +{ + if (0 != action) { + // load the language dependant on the action content. + loadLanguage(action->data().toString()); + } +} + +void MainWindow::switchTranslator(QTranslator& translator, const QString& filename) +{ + // remove the old translator + qApp->removeTranslator(&translator); + + QString full_filename(langPath + "/" + filename); + + // load the new translator + if (translator.load(full_filename)) + qApp->installTranslator(&translator); +} + +void MainWindow::loadLanguage(const QString& rLanguage) +{ + if (currLang != rLanguage) { + currLang = rLanguage; + QLocale locale = QLocale(currLang); + QLocale::setDefault(locale); + QString languageName = QLocale::languageToString(locale.language()); + + switchTranslator(translator, QString("gpsbabelfe_%1.qm").arg(rLanguage)); + switchTranslator(translatorCore, QString("gpsbabel__%1.qm").arg(rLanguage)); + switchTranslator(translatorQt, QString(" qt_%1.qm").arg(rLanguage)); + } +} + +void MainWindow::changeEvent(QEvent* event) +{ + if (0 != event) { + switch(event->type()) { + // This event is sent if a translator is loaded. + case QEvent::LanguageChange: + ui.retranslateUi(this); + break; + // This event is sent if the system language changes. + case QEvent::LocaleChange: + { + QString locale = QLocale::system().name(); + locale.truncate(locale.lastIndexOf('_')); + loadLanguage(locale); + } + break; + default: + break; + } + } + + QMainWindow::changeEvent(event); +} //------------------------------------------------------------------------ void MainWindow::loadInputDeviceNameCombo(const QString &format) @@ -356,6 +479,17 @@ void MainWindow:: outputDeviceOptBtnClicked() } fmtChgInterlock = false; } +void MainWindow::inputFileNameEdited() +{ + bd.inputFileNames.clear(); + bd.inputFileNames << ui.inputFileNameText->text(); +} + +void MainWindow::outputFileNameEdited() +{ + bd.outputFileName = ui.outputFileNameText->text(); + +} //------------------------------------------------------------------------ QString MainWindow::filterForFormat(int idx) @@ -514,7 +648,7 @@ void MainWindow::loadFormats() "Check that the backend program \"gpsbabel\" is properly installed " "and is in the current PATH\n\n" "This program cannot continue.")); - exit(1); + exit(1); } if (inputFileFormatIndices().size() == 0 || inputDeviceFormatIndices().size() == 0 || @@ -933,7 +1067,7 @@ void MainWindow::closeActionX() bd.runCount++; QDateTime now = QDateTime::currentDateTime(); - if((bd.runCount > 5) && (bd.donateSplashed.daysTo(now) > 30)) { + if ((bd.runCount > 5) && (bd.donateSplashed.daysTo(now) > 30)) { Donate donate(0); if (bd.donateSplashed.date() == QDate(2010,1,1)) donate.showNever(false); diff --git a/gpsbabel/gui/mainwindow.h b/gpsbabel/gui/mainwindow.h index 4aa185cd3..0f8a2456e 100644 --- a/gpsbabel/gui/mainwindow.h +++ b/gpsbabel/gui/mainwindow.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: mainwindow.h,v 1.12 2010/06/27 21:12:37 robertl Exp $ +// $Id: mainwindow.h,v 1.13 2010-11-01 03:30:42 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . @@ -28,6 +28,8 @@ #include "babeldata.h" #include "upgrade.h" +#include + class MainWindow: public QMainWindow { Q_OBJECT @@ -36,6 +38,7 @@ class MainWindow: public QMainWindow { MainWindow(QWidget* parent); ~MainWindow(); + private: Ui_MainWindow ui; QList formatList; @@ -46,9 +49,17 @@ private: AllFiltersData filterData; BabelData bd; bool fmtChgInterlock; + QTranslator translator; // translation for the GUI. + QTranslator translatorCore; // translation for the core application. + QTranslator translatorQt; // translations for Qt. + QString currLang; // currently loaded language. + QString langPath; // Absolute path of language files. private: void loadFormats(); + void loadLanguage(const QString& rLanguage); + void switchTranslator(QTranslator&, const QString&); + void createLanguageMenu(); QString filterForFormat(int idx); QString ensureExtensionPresent(const QString &nanme, int idx); QString findBabelVersion(); @@ -89,6 +100,7 @@ private: protected: void closeEvent(QCloseEvent*); + void changeEvent(QEvent*); private slots: void aboutActionX(); @@ -105,15 +117,19 @@ protected: void inputFileOptBtnClicked(); void inputFormatChanged(int); void inputOptionButtonClicked(); + void inputFileNameEdited(); void moreOptionButtonClicked(); void outputDeviceOptBtnClicked(); void outputFileOptBtnClicked(); + void outputFileNameEdited(); void outputFormatChanged(int); void outputOptionButtonClicked(); void preferencesActionX(); void visitWebsiteActionX(); void resetFormatDefaults(); void upgradeCheckActionX(); + void slotLanguageChanged(QAction* action); + }; diff --git a/gpsbabel/gui/mainwinui.ui b/gpsbabel/gui/mainwinui.ui index 897fbdbaa..0650d3b39 100644 --- a/gpsbabel/gui/mainwinui.ui +++ b/gpsbabel/gui/mainwinui.ui @@ -11,7 +11,7 @@ - MainWindow + GPSBabel diff --git a/gpsbabel/gui/makesetup.bat b/gpsbabel/gui/makesetup.bat index ea9656d32..27f93c8de 100644 --- a/gpsbabel/gui/makesetup.bat +++ b/gpsbabel/gui/makesetup.bat @@ -1,4 +1,4 @@ -rem $Id: makesetup.bat,v 1.2 2010/06/27 21:13:07 robertl Exp $ +rem $Id: makesetup.bat,v 1.2 2010-06-27 21:13:07 robertl Exp $ rem rem Copy the Qt stuff into a local directory. The Inno Setup compiler rem cannot handle %QTDIR environment variable in the source file @@ -13,11 +13,15 @@ mkdir qtdir\plugins\imageformats mkdir qtdir\mingw rem Basic Qt runtime DLLs +if "%QTDIR%"=="" call \QtSDK\Desktop\Qt\4.7.4\mingw\bin\qtenv2.bat copy %QTDIR%\bin\QtCore4.dll qtdir\bin copy %QTDIR%\bin\QtGui4.dll qtdir\bin copy %QTDIR%\bin\QtWebkit4.dll qtdir\bin copy %QTDIR%\bin\QtXml4.dll qtdir\bin copy %QTDIR%\bin\QtNetwork4.dll qtdir\bin +copy %QTDIR%\bin\mingwm10.dll qtdir\bin +copy %QTDIR%\bin\libgcc_s_dw2-1.dll qtdir\bin +copy %QTDIR%\bin\phonon4.dll qtdir\bin rem Image format plugins needed at runtime, but not debug verions xcopy %QTDIR%\plugins\imageformats qtdir\plugins\imageformats @@ -33,22 +37,24 @@ copy %QTDIR%\translations\qt_*.qm qtdir\translations del qtdir\translations\qt_help* rem Generate the compiled translations -lrelease gpsbabel_de.ts -lrelease gpsbabel_es.ts -lrelease gpsbabel_fr.ts -lrelease gpsbabel_hu.ts -lrelease gpsbabel_it.ts -lrelease gpsbabelfe_de.ts -lrelease gpsbabelfe_es.ts -lrelease gpsbabelfe_fr.ts -lrelease gpsbabelfe_hu.ts -lrelease gpsbabelfe_it.ts -lrelease gpsbabelfe_ru.ts - +rem lrelease gpsbabel_de.ts +rem lrelease gpsbabel_es.ts +rem lrelease gpsbabel_fr.ts +rem lrelease gpsbabel_hu.ts +rem lrelease gpsbabel_it.ts +rem lrelease gpsbabelfe_de.ts +rem lrelease gpsbabelfe_es.ts +rem lrelease gpsbabelfe_fr.ts +rem lrelease gpsbabelfe_hu.ts +rem lrelease gpsbabelfe_it.ts +rem lrelease gpsbabelfe_ru.ts +rem for /f %%a in (dir /b *.ts) do lrelease %%a + +copy ..\msvc\Expat\libexpat.dll release "c:\Program Files\Inno Setup 5\ISCC.exe" setup.iss rem cleanup rd /q /s qtdir -del gpsbabel_*.qm -del gpsbabelfe_*.qm +rem del gpsbabel_*.qm +rem del gpsbabelfe_*.qm diff --git a/gpsbabel/gui/map.cpp b/gpsbabel/gui/map.cpp index d0070178d..21e4c23ad 100755 --- a/gpsbabel/gui/map.cpp +++ b/gpsbabel/gui/map.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: map.cpp,v 1.2 2009/08/28 17:08:55 robertl Exp $ +// $Id: map.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/map.h b/gpsbabel/gui/map.h index 1e96accf8..def11d28c 100644 --- a/gpsbabel/gui/map.h +++ b/gpsbabel/gui/map.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: map.h,v 1.1 2009/07/05 21:14:56 robertl Exp $ +// $Id: map.h,v 1.1 2009-07-05 21:14:56 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/optionsdlg.cpp b/gpsbabel/gui/optionsdlg.cpp index 8e1b1d0c1..b6564aaff 100644 --- a/gpsbabel/gui/optionsdlg.cpp +++ b/gpsbabel/gui/optionsdlg.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: optionsdlg.cpp,v 1.5 2010/03/01 04:22:28 robertl Exp $ +// $Id: optionsdlg.cpp,v 1.5 2010-03-01 04:22:28 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/optionsdlg.h b/gpsbabel/gui/optionsdlg.h index ba3b03130..7fbdc6229 100644 --- a/gpsbabel/gui/optionsdlg.h +++ b/gpsbabel/gui/optionsdlg.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: optionsdlg.h,v 1.2 2009/11/02 20:38:02 robertl Exp $ +// $Id: optionsdlg.h,v 1.2 2009-11-02 20:38:02 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/preferences.cpp b/gpsbabel/gui/preferences.cpp index 66293661f..11fccf95b 100644 --- a/gpsbabel/gui/preferences.cpp +++ b/gpsbabel/gui/preferences.cpp @@ -43,7 +43,7 @@ Preferences::Preferences(QWidget* parent, QList& formatList, ui_.reportStatisticsCheck->setChecked(bd_.reportStatistics); ui_.ignoreVersionMismatchCheck->setChecked(bd_.ignoreVersionMismatch); // Because of an unfortunate bug in 1.4.0, we turn this off in 1.4.1. - if (VERSION == "1.4.1") + if (VERSION == QString("1.4.1")) bd_.ignoreVersionMismatch = false; connect (ui_.buttonBox, SIGNAL(accepted()), this, SLOT(acceptClicked())); diff --git a/gpsbabel/gui/processwait.cpp b/gpsbabel/gui/processwait.cpp index 375c0549c..09669a942 100644 --- a/gpsbabel/gui/processwait.cpp +++ b/gpsbabel/gui/processwait.cpp @@ -1,5 +1,5 @@ // -*- c++ -*- -// $Id: processwait.cpp,v 1.3 2009/08/28 17:08:55 robertl Exp $ +// $Id: processwait.cpp,v 1.3 2009-08-28 17:08:55 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/processwait.h b/gpsbabel/gui/processwait.h index cc67416ba..72fcb23a8 100644 --- a/gpsbabel/gui/processwait.h +++ b/gpsbabel/gui/processwait.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: processwait.h,v 1.1 2009/07/05 21:14:56 robertl Exp $ +// $Id: processwait.h,v 1.1 2009-07-05 21:14:56 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/serial_unix.cpp b/gpsbabel/gui/serial_unix.cpp index 5f74db5bb..6c65bd0e0 100644 --- a/gpsbabel/gui/serial_unix.cpp +++ b/gpsbabel/gui/serial_unix.cpp @@ -1,4 +1,4 @@ -// $Id: serial_unix.cpp,v 1.2 2010/02/13 23:25:23 robertl Exp $ +// $Id: serial_unix.cpp,v 1.2 2010-02-13 23:25:23 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/serial_win.cpp b/gpsbabel/gui/serial_win.cpp index dc9cc7fc7..7ebf02521 100644 --- a/gpsbabel/gui/serial_win.cpp +++ b/gpsbabel/gui/serial_win.cpp @@ -1,4 +1,4 @@ -// $Id: serial_win.cpp,v 1.3 2010/06/21 02:35:06 robertl Exp $ +// $Id: serial_win.cpp,v 1.3 2010-06-21 02:35:06 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/setting.h b/gpsbabel/gui/setting.h index 2003c9e30..6f9a0cd46 100644 --- a/gpsbabel/gui/setting.h +++ b/gpsbabel/gui/setting.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: setting.h,v 1.3 2010/02/15 02:57:00 robertl Exp $ +// $Id: setting.h,v 1.3 2010-02-15 02:57:00 robertl Exp $ //------------------------------------------------------------------------ // // Copyright (C) 2009 S. Khai Mong . diff --git a/gpsbabel/gui/setup.iss b/gpsbabel/gui/setup.iss index 373ad7639..36494e674 100755 --- a/gpsbabel/gui/setup.iss +++ b/gpsbabel/gui/setup.iss @@ -1,4 +1,3 @@ -; $Id: setup.iss,v 1.24 2010/10/10 19:04:53 robertl Exp $ ; ; NOTE: setup.iss is generated from setup.iss.in via autoconf. ; The generated setup.iss is checked in to help keep the version numbers @@ -17,7 +16,7 @@ ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{1B8FE958-A304-4902-BF7A-4E2F0F5B7017} AppName=GPSBabel -AppVerName=GPSBabel 1.4.2 +AppVerName=GPSBabel 1.4.3 AppPublisher=GPSBabel AppPublisherURL=http://www.gpsbabel.org AppSupportURL=http://www.gpsbabel.org @@ -25,7 +24,7 @@ AppUpdatesURL=http://www.gpsbabel.org DefaultDirName={pf}\GPSBabel DefaultGroupName=GPSBabel OutputDir=release -OutputBaseFilename=GPSBabel-1.4.2-Setup +OutputBaseFilename=GPSBabel-1.4.3-Setup SetupIconFile=images\babel2.ico Compression=lzma SolidCompression=yes @@ -38,12 +37,9 @@ Name: "english"; MessagesFile: "compiler:Default.isl" Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Files] -Source: qtdir\bin\QtCore4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\bin\QtGui4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\bin\QtWebkit4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\bin\QtXml4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\bin\QtNetwork4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\mingw\mingwm10.dll; DestDir: "{app}"; Flags: ignoreversion +; This isn't as wreckless as it seems; these directories are populated on a +; controlled way by the batch file. +Source: qtdir\bin\*.dll; DestDir: "{app}"; Flags: ignoreversion Source: qtdir\plugins\*; DestDir: "{app}\plugins"; Flags: ignoreversion recursesubdirs createallsubdirs Source: gmapbase.html; DestDir: "{app}"; Flags: ignoreversion @@ -52,36 +48,22 @@ Source: qt.conf; DestDir: "{app}"; Flags: ignoreversion Source: release\gpsbabelfe.exe; DestDir: "{app}"; Flags: ignoreversion Source: release\libexpat.dll; DestDir: "{app}"; Flags: ignoreversion Source: release\gpsbabel.exe; DestDir: "{app}"; Flags: ignoreversion -Source: release\help\*; DestDir: "{app}\help"; Flags: ignoreversion recursesubdirs createallsubdirs +; Source: release\help\*; DestDir: "{app}\help"; Flags: ignoreversion recursesubdirs createallsubdirs ; Translation strings extracted from source code. Include it in the dist ; so that users can translate if they want to. -Source: gpsbabel_de.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabel_es.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabel_fr.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabel_hu.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabel_it.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_de.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_es.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_fr.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_hu.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_it.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_ru.ts; DestDir: "{app}\translations"; Flags: ignoreversion +; Source: gpsbabel_*.ts; DestDir: "{app}\translations"; Flags: ignoreversion +; Source: gpsbabelfe_*.ts; DestDir: "{app}\translations"; Flags: ignoreversion ; Compiled translation strings that are used at runtime. -; Only Spanish is adequately translated for now. -Source: gpsbabel_es.qm; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_es.qm; DestDir: "{app}\translations"; Flags: ignoreversion - -; German is usable -Source: gpsbabel_de.qm; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_de.qm; DestDir: "{app}\translations"; Flags: ignoreversion +; Source: gpsbabel_*.qm; DestDir: "{app}\translations"; Flags: ignoreversion +Source: gpsbabelfe*.qm; DestDir: "{app}\translations"; Flags: ignoreversion ; Now translations from Qt's own UI stuff. Source: qtdir\translations\*; DestDir: "{app}\translations"; Flags: ignoreversion recursesubdirs createallsubdirs ; Miscellaneous -Source: COPYING; DestDir: {app}; Flags: ignoreversion +Source: COPYING.txt; DestDir: {app}; Flags: ignoreversion ; Source: AUTHORS; DestDir: {app}; Flags: ignoreversion ; Source: README.contrib; DestDir: {app}; Flags: ignoreversion ; Source: README.gui; DestDir: {app}; Flags: ignoreversion diff --git a/gpsbabel/gui/setup.iss.in b/gpsbabel/gui/setup.iss.in index b1aa19f12..a5f9d6c37 100755 --- a/gpsbabel/gui/setup.iss.in +++ b/gpsbabel/gui/setup.iss.in @@ -1,4 +1,3 @@ -; $Id: setup.iss.in,v 1.6 2010/06/07 00:59:39 robertl Exp $ ; ; NOTE: setup.iss is generated from setup.iss.in via autoconf. ; The generated setup.iss is checked in to help keep the version numbers @@ -38,12 +37,9 @@ Name: "english"; MessagesFile: "compiler:Default.isl" Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Files] -Source: qtdir\bin\QtCore4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\bin\QtGui4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\bin\QtWebkit4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\bin\QtXml4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\bin\QtNetwork4.dll; DestDir: "{app}"; Flags: ignoreversion -Source: qtdir\mingw\mingwm10.dll; DestDir: "{app}"; Flags: ignoreversion +; This isn't as wreckless as it seems; these directories are populated on a +; controlled way by the batch file. +Source: qtdir\bin\*.dll; DestDir: "{app}"; Flags: ignoreversion Source: qtdir\plugins\*; DestDir: "{app}\plugins"; Flags: ignoreversion recursesubdirs createallsubdirs Source: gmapbase.html; DestDir: "{app}"; Flags: ignoreversion @@ -52,36 +48,22 @@ Source: qt.conf; DestDir: "{app}"; Flags: ignoreversion Source: release\gpsbabelfe.exe; DestDir: "{app}"; Flags: ignoreversion Source: release\libexpat.dll; DestDir: "{app}"; Flags: ignoreversion Source: release\gpsbabel.exe; DestDir: "{app}"; Flags: ignoreversion -Source: release\help\*; DestDir: "{app}\help"; Flags: ignoreversion recursesubdirs createallsubdirs +; Source: release\help\*; DestDir: "{app}\help"; Flags: ignoreversion recursesubdirs createallsubdirs ; Translation strings extracted from source code. Include it in the dist ; so that users can translate if they want to. -Source: gpsbabel_de.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabel_es.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabel_fr.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabel_hu.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabel_it.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_de.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_es.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_fr.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_hu.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_it.ts; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_ru.ts; DestDir: "{app}\translations"; Flags: ignoreversion +; Source: gpsbabel_*.ts; DestDir: "{app}\translations"; Flags: ignoreversion +; Source: gpsbabelfe_*.ts; DestDir: "{app}\translations"; Flags: ignoreversion ; Compiled translation strings that are used at runtime. -; Only Spanish is adequately translated for now. -Source: gpsbabel_es.qm; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_es.qm; DestDir: "{app}\translations"; Flags: ignoreversion - -; German is usable -Source: gpsbabel_de.qm; DestDir: "{app}\translations"; Flags: ignoreversion -Source: gpsbabelfe_de.qm; DestDir: "{app}\translations"; Flags: ignoreversion +; Source: gpsbabel_*.qm; DestDir: "{app}\translations"; Flags: ignoreversion +Source: gpsbabelfe*.qm; DestDir: "{app}\translations"; Flags: ignoreversion ; Now translations from Qt's own UI stuff. Source: qtdir\translations\*; DestDir: "{app}\translations"; Flags: ignoreversion recursesubdirs createallsubdirs ; Miscellaneous -Source: COPYING; DestDir: {app}; Flags: ignoreversion +Source: COPYING.txt; DestDir: {app}; Flags: ignoreversion ; Source: AUTHORS; DestDir: {app}; Flags: ignoreversion ; Source: README.contrib; DestDir: {app}; Flags: ignoreversion ; Source: README.gui; DestDir: {app}; Flags: ignoreversion diff --git a/gpsbabel/gui/showUrl.sh b/gpsbabel/gui/showUrl.sh index 2f2e0da2e..aa51333ae 100644 --- a/gpsbabel/gui/showUrl.sh +++ b/gpsbabel/gui/showUrl.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $Id: showUrl.sh,v 1.1 2009/07/05 21:14:56 robertl Exp $ +# $Id: showUrl.sh,v 1.1 2009-07-05 21:14:56 robertl Exp $ if [ "$BROWSER" = "" ]; then BROWSER="firefox" diff --git a/gpsbabel/gui/upgrade.cpp b/gpsbabel/gui/upgrade.cpp index d39fe9620..5b3807216 100644 --- a/gpsbabel/gui/upgrade.cpp +++ b/gpsbabel/gui/upgrade.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -// $Id: upgrade.cpp,v 1.26 2010/06/19 23:59:06 robertl Exp $ +// $Id: upgrade.cpp,v 1.26 2010-06-19 23:59:06 robertl Exp $ /* Copyright (C) 2009, 2010 Robert Lipe, robertlipe@gpsbabel.org @@ -23,8 +23,10 @@ #include "babeldata.h" #include "format.h" #include "upgrade.h" -#include "../config.h" #include "../gbversion.h" +#if HAVE_CONFIG_H +#include "../config.h" +#endif #if HAVE_UNAME #include @@ -93,6 +95,8 @@ QString UpgradeCheck::getOsVersion() case QSysInfo::MV_10_4: return "10.4"; break; case QSysInfo::MV_10_5: return "10.5"; break; case QSysInfo::MV_10_6: return "10.6"; break; + // Disabled while we roll back to 4.7.4 :-( + // case QSysInfo::MV_10_7: return "10.7"; break; default: return QString("Unknown Mac %1").arg(QSysInfo::MacintoshVersion); }; #elif defined (Q_OS_WIN) diff --git a/gpsbabel/height.c b/gpsbabel/height.c index 191cdfd94..632681b15 100755 --- a/gpsbabel/height.c +++ b/gpsbabel/height.c @@ -27,32 +27,42 @@ #define MYNAME "height" #if FILTERS_ENABLED -static char *addopt = NULL; -static char *wgs84tomslopt = NULL; +static char* addopt = NULL; +static char* wgs84tomslopt = NULL; static double addf; static arglist_t height_args[] = { - {"add", &addopt, "Adds a constant value to every altitude (meter, append \"f\" (x.xxf) for feet)", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"wgs84tomsl", &wgs84tomslopt, "Converts WGS84 ellipsoidal height to orthometric height (MSL)", - NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "add", &addopt, "Adds a constant value to every altitude (meter, append \"f\" (x.xxf) for feet)", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "wgs84tomsl", &wgs84tomslopt, "Converts WGS84 ellipsoidal height to orthometric height (MSL)", + NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static double bilinear(double x1, double y1, double x2, double y2, double x, double y, double z11, double z12, double z21, double z22) { - double delta; + double delta; - if (y1 == y2 && x1 == x2 ) return (z11); - if (y1 == y2 && x1 != x2 ) return (z22*(x-x1)+z11*(x2-x))/(x2-x1); - if (x1 == x2 && y1 != y2 ) return (z22*(y-y1)+z11*(y2-y))/(y2-y1); + if (y1 == y2 && x1 == x2) { + return (z11); + } + if (y1 == y2 && x1 != x2) { + return (z22*(x-x1)+z11*(x2-x))/(x2-x1); + } + if (x1 == x2 && y1 != y2) { + return (z22*(y-y1)+z11*(y2-y))/(y2-y1); + } - delta=(y2-y1)*(x2-x1); + delta=(y2-y1)*(x2-x1); - return (z22*(y-y1)*(x-x1)+z12*(y2-y)*(x-x1)+z21*(y-y1)*(x2-x)+z11*(y2-y)*(x2-x))/delta; + return (z22*(y-y1)*(x-x1)+z12*(y2-y)*(x-x1)+z21*(y-y1)*(x2-x)+z11*(y2-y)*(x2-x))/delta; } @@ -61,106 +71,107 @@ static double wgs84_separation(double lat, double lon) { #define GEOID_ROW 19 #define GEOID_COL 37 - static const char geoid_delta[GEOID_COL*GEOID_ROW]={ - /* 90S */ -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, - /* 80S */ -53,-54,-55,-52,-48,-42,-38,-38,-29,-26,-26,-24,-23,-21,-19,-16,-12, -8, -4, -1, 1, 4, 4, 6, 5, 4, 2, -6,-15,-24,-33,-40,-48,-50,-53,-52,-53, - /* 70S */ -61,-60,-61,-55,-49,-44,-38,-31,-25,-16, -6, 1, 4, 5, 4, 2, 6, 12, 16, 16, 17, 21, 20, 26, 26, 22, 16, 10, -1,-16,-29,-36,-46,-55,-54,-59,-61, - /* 60S */ -45,-43,-37,-32,-30,-26,-23,-22,-16,-10, -2, 10, 20, 20, 21, 24, 22, 17, 16, 19, 25, 30, 35, 35, 33, 30, 27, 10, -2,-14,-23,-30,-33,-29,-35,-43,-45, - /* 50S */ -15,-18,-18,-16,-17,-15,-10,-10, -8, -2, 6, 14, 13, 3, 3, 10, 20, 27, 25, 26, 34, 39, 45, 45, 38, 39, 28, 13, -1,-15,-22,-22,-18,-15,-14,-10,-15, - /* 40S */ 21, 6, 1, -7,-12,-12,-12,-10, -7, -1, 8, 23, 15, -2, -6, 6, 21, 24, 18, 26, 31, 33, 39, 41, 30, 24, 13, -2,-20,-32,-33,-27,-14, -2, 5, 20, 21, - /* 30S */ 46, 22, 5, -2, -8,-13,-10, -7, -4, 1, 9, 32, 16, 4, -8, 4, 12, 15, 22, 27, 34, 29, 14, 15, 15, 7, -9,-25,-37,-39,-23,-14, 15, 33, 34, 45, 46, - /* 20S */ 51, 27, 10, 0, -9,-11, -5, -2, -3, -1, 9, 35, 20, -5, -6, -5, 0, 13, 17, 23, 21, 8, -9,-10,-11,-20, -40,-47,-45,-25, 5, 23, 45, 58, 57, 63, 51, - /* 10S */ 36, 22, 11, 6, -1, -8,-10, -8,-11, -9, 1, 32, 4,-18,-13, -9, 4, 14, 12, 13, -2,-14,-25,-32,-38,-60, -75,-63,-26, 0, 35, 52, 68, 76, 64, 52, 36, - /* 00N */ 22, 16, 17, 13, 1,-12,-23,-20,-14, -3, 14, 10,-15,-27,-18, 3, 12, 20, 18, 12,-13, -9,-28,-49,-62,-89,-102,-63, -9, 33, 58, 73, 74, 63, 50, 32, 22, - /* 10N */ 13, 12, 11, 2,-11,-28,-38,-29,-10, 3, 1,-11,-41,-42,-16, 3, 17, 33, 22, 23, 2, -3, -7,-36,-59,-90, -95,-63,-24, 12, 53, 60, 58, 46, 36, 26, 13, - /* 20N */ 5, 10, 7, -7,-23,-39,-47,-34, -9,-10,-20,-45,-48,-32, -9, 17, 25, 31, 31, 26, 15, 6, 1,-29,-44,-61, -67,-59,-36,-11, 21, 39, 49, 39, 22, 10, 5, - /* 30N */ -7, -5, -8,-15,-28,-40,-42,-29,-22,-26,-32,-51,-40,-17, 17, 31, 34, 44, 36, 28, 29, 17, 12,-20,-15,-40, -33,-34,-34,-28, 7, 29, 43, 20, 4, -6, -7, - /* 40N */ -12,-10,-13,-20,-31,-34,-21,-16,-26,-34,-33,-35,-26, 2, 33, 59, 52, 51, 52, 48, 35, 40, 33, -9,-28,-39, -48,-59,-50,-28, 3, 23, 37, 18, -1,-11,-12, - /* 50N */ -8, 8, 8, 1,-11,-19,-16,-18,-22,-35,-40,-26,-12, 24, 45, 63, 62, 59, 47, 48, 42, 28, 12,-10,-19,-33, -43,-42,-43,-29, -2, 17, 23, 22, 6, 2, -8, - /* 60N */ 2, 9, 17, 10, 13, 1,-14,-30,-39,-46,-42,-21, 6, 29, 49, 65, 60, 57, 47, 41, 21, 18, 14, 7, -3,-22, -29,-32,-32,-26,-15, -2, 13, 17, 19, 6, 2, - /* 70N */ 2, 2, 1, -1, -3, -7,-14,-24,-27,-25,-19, 3, 24, 37, 47, 60, 61, 58, 51, 43, 29, 20, 12, 5, -2,-10, -14,-12,-10,-14,-12, -6, -2, 3, 6, 4, 2, - /* 80N */ 3, 1, -2, -3, -3, -3, -1, 3, 1, 5, 9, 11, 19, 27, 31, 34, 33, 34, 33, 34, 28, 23, 17, 13, 9, 4, 4, 1, -2, -2, 0, 2, 3, 2, 1, 1, 3, - /* 90N */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}; - int ilat, ilon; - int ilat1, ilat2, ilon1, ilon2; - - /* sanity checks to prevent segfault on bad data */ - if ((lat > 90) || (lat < -90)) { - fatal(MYNAME ": Invalid latitude value (%f)\n", lat); - } - if (( lon > 180) || (lon < -180)) { - fatal(MYNAME ": Invalid longitude value (%f)\n", lon);; - } - - ilat=(int)floor(( 90.+lat)/10); - ilon=(int)floor((180.+lon)/10); - - ilat1=ilat; - ilon1=ilon; - ilat2=(ilat < GEOID_ROW-1)? ilat+1:ilat; - ilon2=(ilon < GEOID_COL-1)? ilon+1:ilon; - - return bilinear( - ilon1*10.-180.,ilat1*10.-90., - ilon2*10.-180.,ilat2*10.-90., - lon, lat, - (double)geoid_delta[ilon1+ilat1*GEOID_COL], - (double)geoid_delta[ilon2+ilat1*GEOID_COL], - (double)geoid_delta[ilon1+ilat2*GEOID_COL], - (double)geoid_delta[ilon2+ilat2*GEOID_COL] - ); + static const char geoid_delta[GEOID_COL*GEOID_ROW]= { + /* 90S */ -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, + /* 80S */ -53,-54,-55,-52,-48,-42,-38,-38,-29,-26,-26,-24,-23,-21,-19,-16,-12, -8, -4, -1, 1, 4, 4, 6, 5, 4, 2, -6,-15,-24,-33,-40,-48,-50,-53,-52,-53, + /* 70S */ -61,-60,-61,-55,-49,-44,-38,-31,-25,-16, -6, 1, 4, 5, 4, 2, 6, 12, 16, 16, 17, 21, 20, 26, 26, 22, 16, 10, -1,-16,-29,-36,-46,-55,-54,-59,-61, + /* 60S */ -45,-43,-37,-32,-30,-26,-23,-22,-16,-10, -2, 10, 20, 20, 21, 24, 22, 17, 16, 19, 25, 30, 35, 35, 33, 30, 27, 10, -2,-14,-23,-30,-33,-29,-35,-43,-45, + /* 50S */ -15,-18,-18,-16,-17,-15,-10,-10, -8, -2, 6, 14, 13, 3, 3, 10, 20, 27, 25, 26, 34, 39, 45, 45, 38, 39, 28, 13, -1,-15,-22,-22,-18,-15,-14,-10,-15, + /* 40S */ 21, 6, 1, -7,-12,-12,-12,-10, -7, -1, 8, 23, 15, -2, -6, 6, 21, 24, 18, 26, 31, 33, 39, 41, 30, 24, 13, -2,-20,-32,-33,-27,-14, -2, 5, 20, 21, + /* 30S */ 46, 22, 5, -2, -8,-13,-10, -7, -4, 1, 9, 32, 16, 4, -8, 4, 12, 15, 22, 27, 34, 29, 14, 15, 15, 7, -9,-25,-37,-39,-23,-14, 15, 33, 34, 45, 46, + /* 20S */ 51, 27, 10, 0, -9,-11, -5, -2, -3, -1, 9, 35, 20, -5, -6, -5, 0, 13, 17, 23, 21, 8, -9,-10,-11,-20, -40,-47,-45,-25, 5, 23, 45, 58, 57, 63, 51, + /* 10S */ 36, 22, 11, 6, -1, -8,-10, -8,-11, -9, 1, 32, 4,-18,-13, -9, 4, 14, 12, 13, -2,-14,-25,-32,-38,-60, -75,-63,-26, 0, 35, 52, 68, 76, 64, 52, 36, + /* 00N */ 22, 16, 17, 13, 1,-12,-23,-20,-14, -3, 14, 10,-15,-27,-18, 3, 12, 20, 18, 12,-13, -9,-28,-49,-62,-89,-102,-63, -9, 33, 58, 73, 74, 63, 50, 32, 22, + /* 10N */ 13, 12, 11, 2,-11,-28,-38,-29,-10, 3, 1,-11,-41,-42,-16, 3, 17, 33, 22, 23, 2, -3, -7,-36,-59,-90, -95,-63,-24, 12, 53, 60, 58, 46, 36, 26, 13, + /* 20N */ 5, 10, 7, -7,-23,-39,-47,-34, -9,-10,-20,-45,-48,-32, -9, 17, 25, 31, 31, 26, 15, 6, 1,-29,-44,-61, -67,-59,-36,-11, 21, 39, 49, 39, 22, 10, 5, + /* 30N */ -7, -5, -8,-15,-28,-40,-42,-29,-22,-26,-32,-51,-40,-17, 17, 31, 34, 44, 36, 28, 29, 17, 12,-20,-15,-40, -33,-34,-34,-28, 7, 29, 43, 20, 4, -6, -7, + /* 40N */ -12,-10,-13,-20,-31,-34,-21,-16,-26,-34,-33,-35,-26, 2, 33, 59, 52, 51, 52, 48, 35, 40, 33, -9,-28,-39, -48,-59,-50,-28, 3, 23, 37, 18, -1,-11,-12, + /* 50N */ -8, 8, 8, 1,-11,-19,-16,-18,-22,-35,-40,-26,-12, 24, 45, 63, 62, 59, 47, 48, 42, 28, 12,-10,-19,-33, -43,-42,-43,-29, -2, 17, 23, 22, 6, 2, -8, + /* 60N */ 2, 9, 17, 10, 13, 1,-14,-30,-39,-46,-42,-21, 6, 29, 49, 65, 60, 57, 47, 41, 21, 18, 14, 7, -3,-22, -29,-32,-32,-26,-15, -2, 13, 17, 19, 6, 2, + /* 70N */ 2, 2, 1, -1, -3, -7,-14,-24,-27,-25,-19, 3, 24, 37, 47, 60, 61, 58, 51, 43, 29, 20, 12, 5, -2,-10, -14,-12,-10,-14,-12, -6, -2, 3, 6, 4, 2, + /* 80N */ 3, 1, -2, -3, -3, -3, -1, 3, 1, 5, 9, 11, 19, 27, 31, 34, 33, 34, 33, 34, 28, 23, 17, 13, 9, 4, 4, 1, -2, -2, 0, 2, 3, 2, 1, 1, 3, + /* 90N */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 + }; + int ilat, ilon; + int ilat1, ilat2, ilon1, ilon2; + + /* sanity checks to prevent segfault on bad data */ + if ((lat > 90) || (lat < -90)) { + fatal(MYNAME ": Invalid latitude value (%f)\n", lat); + } + if ((lon > 180) || (lon < -180)) { + fatal(MYNAME ": Invalid longitude value (%f)\n", lon);; + } + + ilat=(int)floor((90.+lat)/10); + ilon=(int)floor((180.+lon)/10); + + ilat1=ilat; + ilon1=ilon; + ilat2=(ilat < GEOID_ROW-1)? ilat+1:ilat; + ilon2=(ilon < GEOID_COL-1)? ilon+1:ilon; + + return bilinear( + ilon1*10.-180.,ilat1*10.-90., + ilon2*10.-180.,ilat2*10.-90., + lon, lat, + (double)geoid_delta[ilon1+ilat1*GEOID_COL], + (double)geoid_delta[ilon2+ilat1*GEOID_COL], + (double)geoid_delta[ilon1+ilat2*GEOID_COL], + (double)geoid_delta[ilon2+ilat2*GEOID_COL] + ); } static void -correct_height(const waypoint *wpt) +correct_height(const waypoint* wpt) { - waypoint *waypointp = (waypoint *) wpt; + waypoint* waypointp = (waypoint*) wpt; - if (addopt) - waypointp->altitude += addf; + if (addopt) { + waypointp->altitude += addf; + } - if (wgs84tomslopt) - waypointp->altitude -= wgs84_separation(waypointp->latitude, waypointp->longitude); + if (wgs84tomslopt) { + waypointp->altitude -= wgs84_separation(waypointp->latitude, waypointp->longitude); + } } static void -height_init(const char *args) +height_init(const char* args) { - char *unit; - - if (addopt) { - addf = strtod(addopt, &unit); - - if (*unit == 'f' || *unit== 'F') { - addf = FEET_TO_METERS(addf); - } - else if ((*unit != 'm') && (*unit != 'M') && (*unit != '\0')) { - fatal(MYNAME ": Invalid unit (\"%c\")! Please use \"m\" for meter or \"f\" for feet.\n", *unit); - } - } - else { - addf = 0.0; - } + char* unit; + + if (addopt) { + addf = strtod(addopt, &unit); + + if (*unit == 'f' || *unit== 'F') { + addf = FEET_TO_METERS(addf); + } else if ((*unit != 'm') && (*unit != 'M') && (*unit != '\0')) { + fatal(MYNAME ": Invalid unit (\"%c\")! Please use \"m\" for meter or \"f\" for feet.\n", *unit); + } + } else { + addf = 0.0; + } } -static void +static void height_process(void) /* this procedure must be present in vecs */ { - waypt_disp_all(correct_height); - route_disp_all(NULL, NULL, correct_height); - track_disp_all(NULL, NULL, correct_height); + waypt_disp_all(correct_height); + route_disp_all(NULL, NULL, correct_height); + track_disp_all(NULL, NULL, correct_height); } filter_vecs_t height_vecs = { - height_init, - height_process, - NULL, - NULL, - height_args + height_init, + height_process, + NULL, + NULL, + height_args }; diff --git a/gpsbabel/hiketech.c b/gpsbabel/hiketech.c index c5f35b08d..cdde9a520 100644 --- a/gpsbabel/hiketech.c +++ b/gpsbabel/hiketech.c @@ -22,16 +22,16 @@ #include "defs.h" #include "xmlgeneric.h" -static gbfile *ofd; -static waypoint *wpt_tmp; -static route_head *trk_head; +static gbfile* ofd; +static waypoint* wpt_tmp; +static route_head* trk_head; #define MYNAME "hiketech" static arglist_t hiketech_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /* Waypoints */ @@ -53,247 +53,247 @@ static xg_callback ht_trk_long; static xg_callback ht_trk_alt; static xg_tag_mapping ht_map[] = { - { ht_wpt_s, cb_start, "/hiketech/gpsdata/wpt" }, - { ht_wpt_e, cb_end, "/hiketech/gpsdata/wpt" }, - { ht_ident, cb_cdata, "/hiketech/gpsdata/wpt/ident" }, - { ht_sym, cb_cdata, "/hiketech/gpsdata/wpt/sym" }, - { ht_lat, cb_cdata, "/hiketech/gpsdata/wpt/lat" }, - { ht_long, cb_cdata, "/hiketech/gpsdata/wpt/long" }, - { ht_alt, cb_cdata, "/hiketech/gpsdata/wpt/alt" }, - - { ht_trk_s, cb_start, "/hiketech/gpsdata/trk" }, - { ht_trk_e, cb_end, "/hiketech/gpsdata/trk" }, - { ht_trk_ident, cb_cdata, "/hiketech/gpsdata/trk/ident" }, - { ht_trk_pnt_s, cb_start, "/hiketech/gpsdata/trk/pnt" }, - { ht_trk_pnt_e, cb_end, "/hiketech/gpsdata/trk/pnt" }, - { ht_trk_utc, cb_cdata, "/hiketech/gpsdata/trk/pnt/utc" }, - { ht_trk_lat, cb_cdata, "/hiketech/gpsdata/trk/pnt/lat" }, - { ht_trk_long, cb_cdata, "/hiketech/gpsdata/trk/pnt/long" }, - { ht_trk_alt, cb_cdata, "/hiketech/gpsdata/trk/pnt/alt" }, - { NULL, 0, NULL} + { ht_wpt_s, cb_start, "/hiketech/gpsdata/wpt" }, + { ht_wpt_e, cb_end, "/hiketech/gpsdata/wpt" }, + { ht_ident, cb_cdata, "/hiketech/gpsdata/wpt/ident" }, + { ht_sym, cb_cdata, "/hiketech/gpsdata/wpt/sym" }, + { ht_lat, cb_cdata, "/hiketech/gpsdata/wpt/lat" }, + { ht_long, cb_cdata, "/hiketech/gpsdata/wpt/long" }, + { ht_alt, cb_cdata, "/hiketech/gpsdata/wpt/alt" }, + + { ht_trk_s, cb_start, "/hiketech/gpsdata/trk" }, + { ht_trk_e, cb_end, "/hiketech/gpsdata/trk" }, + { ht_trk_ident, cb_cdata, "/hiketech/gpsdata/trk/ident" }, + { ht_trk_pnt_s, cb_start, "/hiketech/gpsdata/trk/pnt" }, + { ht_trk_pnt_e, cb_end, "/hiketech/gpsdata/trk/pnt" }, + { ht_trk_utc, cb_cdata, "/hiketech/gpsdata/trk/pnt/utc" }, + { ht_trk_lat, cb_cdata, "/hiketech/gpsdata/trk/pnt/lat" }, + { ht_trk_long, cb_cdata, "/hiketech/gpsdata/trk/pnt/long" }, + { ht_trk_alt, cb_cdata, "/hiketech/gpsdata/trk/pnt/alt" }, + { NULL, (xg_cb_type)0, NULL} }; static void -hiketech_rd_init(const char *fname) +hiketech_rd_init(const char* fname) { - xml_init(fname, ht_map, NULL); + xml_init(fname, ht_map, NULL); } static void hiketech_read(void) { - xml_read(); + xml_read(); } static void hiketech_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void -hiketech_wr_init(const char *fname) +hiketech_wr_init(const char* fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void hiketech_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static void -hiketech_trk_hdr(const route_head *rte) +hiketech_trk_hdr(const route_head* rte) { - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "ident", rte->rte_name); + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "ident", rte->rte_name); } static void -hiketech_trk_tlr(const route_head *rte) +hiketech_trk_tlr(const route_head* rte) { - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void -hiketech_print_utc(time_t tm, const char *indent, const char *tag) +hiketech_print_utc(time_t tm, const char* indent, const char* tag) { - char tbuf[80]; - strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %I:%M:%S", gmtime(&tm)); - gbfprintf(ofd, "%s<%s>%s\n",indent,tag,tbuf,tag); + char tbuf[80]; + strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %I:%M:%S", gmtime(&tm)); + gbfprintf(ofd, "%s<%s>%s\n",indent,tag,tbuf,tag); } static void -hiketech_trkpt_pr(const waypoint *waypointp) +hiketech_trkpt_pr(const waypoint* waypointp) { - gbfprintf(ofd, " \n"); - if (waypointp->creation_time) { - hiketech_print_utc(waypointp->creation_time, " ", "utc"); - } - gbfprintf(ofd, " %f\n", waypointp->latitude); - gbfprintf(ofd, " %f\n", waypointp->longitude); - if (waypointp->altitude != unknown_alt) { - gbfprintf(ofd, " %f\n", - waypointp->altitude); - } - gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); + if (waypointp->creation_time) { + hiketech_print_utc(waypointp->creation_time, " ", "utc"); + } + gbfprintf(ofd, " %f\n", waypointp->latitude); + gbfprintf(ofd, " %f\n", waypointp->longitude); + if (waypointp->altitude != unknown_alt) { + gbfprintf(ofd, " %f\n", + waypointp->altitude); + } + gbfprintf(ofd, " \n"); } static void -hiketech_waypt_pr(const waypoint *wpt) -{ - gbfprintf(ofd, "\n"); - write_xml_entity(ofd, "\t", "ident", wpt->shortname); - write_optional_xml_entity(ofd, "\t", "sym", wpt->icon_descr); - gbfprintf(ofd, "\t%f\n", wpt->latitude); - gbfprintf(ofd, "\t%f\n", wpt->longitude); - - /* - * These probably aren't technicallyconstants, but it's all - * we can do for now. - */ - gbfprintf(ofd, "\t\n\t\tFAFFB4\n\t\tFF8000\n\t\n"); - gbfprintf(ofd, "\n"); +hiketech_waypt_pr(const waypoint* wpt) +{ + gbfprintf(ofd, "\n"); + write_xml_entity(ofd, "\t", "ident", wpt->shortname); + write_optional_xml_entity(ofd, "\t", "sym", wpt->icon_descr); + gbfprintf(ofd, "\t%f\n", wpt->latitude); + gbfprintf(ofd, "\t%f\n", wpt->longitude); + + /* + * These probably aren't technicallyconstants, but it's all + * we can do for now. + */ + gbfprintf(ofd, "\t\n\t\tFAFFB4\n\t\tFF8000\n\t\n"); + gbfprintf(ofd, "\n"); } static void hiketech_write(void) { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); - track_disp_all(hiketech_trk_hdr, hiketech_trk_tlr, hiketech_trkpt_pr); - track_disp_all(NULL, NULL, hiketech_trkpt_pr); - waypt_disp_all(hiketech_waypt_pr); - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + track_disp_all(hiketech_trk_hdr, hiketech_trk_tlr, hiketech_trkpt_pr); + track_disp_all(NULL, NULL, hiketech_trkpt_pr); + waypt_disp_all(hiketech_waypt_pr); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static -void ht_wpt_s(const char *args, const char **unused) +void ht_wpt_s(const char* args, const char** unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } static -void ht_ident(const char *args, const char **unused) +void ht_ident(const char* args, const char** unused) { - wpt_tmp->shortname = xstrdup(args); + wpt_tmp->shortname = xstrdup(args); } static -void ht_sym(const char *args, const char **unused) +void ht_sym(const char* args, const char** unused) { - wpt_tmp->icon_descr = xstrdup(args); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; } static -void ht_lat(const char *args, const char **unused) +void ht_lat(const char* args, const char** unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } static -void ht_long(const char *args, const char **unused) +void ht_long(const char* args, const char** unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } static -void ht_alt(const char *args, const char **unused) +void ht_alt(const char* args, const char** unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } static -void ht_wpt_e(const char *args, const char **unused) +void ht_wpt_e(const char* args, const char** unused) { - waypt_add(wpt_tmp); - wpt_tmp = NULL; + waypt_add(wpt_tmp); + wpt_tmp = NULL; } static -void ht_trk_s(const char *args, const char **unused) +void ht_trk_s(const char* args, const char** unused) { - trk_head = route_head_alloc(); - track_add_head(trk_head); + trk_head = route_head_alloc(); + track_add_head(trk_head); } static -void ht_trk_e(const char *args, const char **unused) +void ht_trk_e(const char* args, const char** unused) { } static -void ht_trk_ident(const char *args, const char **unused) +void ht_trk_ident(const char* args, const char** unused) { - trk_head->rte_name = xstrdup(args); + trk_head->rte_name = xstrdup(args); } static -void ht_trk_pnt_s(const char *args, const char **unused) +void ht_trk_pnt_s(const char* args, const char** unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } static -void ht_trk_pnt_e(const char *args, const char **unused) +void ht_trk_pnt_e(const char* args, const char** unused) { - track_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); } static -void ht_trk_utc(const char *args, const char **unused) +void ht_trk_utc(const char* args, const char** unused) { - struct tm tm; - time_t utc; + struct tm tm; + time_t utc; - sscanf(args, "%d-%d-%d %d:%d:%d", - &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, - &tm.tm_min, &tm.tm_sec); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; + sscanf(args, "%d-%d-%d %d:%d:%d", + &tm.tm_year, &tm.tm_mon, + &tm.tm_mday, &tm.tm_hour, + &tm.tm_min, &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; - utc = mkgmtime(&tm); + utc = mkgmtime(&tm); - wpt_tmp->creation_time = utc; + wpt_tmp->creation_time = utc; } static -void ht_trk_lat(const char *args, const char **unused) +void ht_trk_lat(const char* args, const char** unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } static -void ht_trk_long(const char *args, const char **unused) +void ht_trk_long(const char* args, const char** unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } static -void ht_trk_alt(const char *args, const char **unused) +void ht_trk_alt(const char* args, const char** unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } ff_vecs_t hiketech_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }, - hiketech_rd_init, - hiketech_wr_init, - hiketech_rd_deinit, - hiketech_wr_deinit, - hiketech_read, - hiketech_write, - NULL, - hiketech_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { (ff_cap)(ff_cap_read | ff_cap_write), (ff_cap)(ff_cap_read | ff_cap_write) }, + hiketech_rd_init, + hiketech_wr_init, + hiketech_rd_deinit, + hiketech_wr_deinit, + hiketech_read, + hiketech_write, + NULL, + hiketech_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/holux.c b/gpsbabel/holux.c index ba1010c0c..5432c6864 100644 --- a/gpsbabel/holux.c +++ b/gpsbabel/holux.c @@ -19,7 +19,7 @@ History: - 2002-09-15 J. Becker start programming + 2002-09-15 J. Becker start programming */ @@ -32,22 +32,22 @@ History: #include "holux.h" -static gbfile *file_in, *file_out; -static unsigned char *HxWFile; +static gbfile* file_in, *file_out; +static unsigned char* HxWFile; static short_handle mkshort_handle; #define MYNAME "Holux" -static void rd_init(const char *fname) +static void rd_init(const char* fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } @@ -55,13 +55,13 @@ static void rd_deinit(void) static void -wr_init(const char *fname) +wr_init(const char* fname) { - mkshort_handle = mkshort_new_handle(); + mkshort_handle = mkshort_new_handle(); - HxWFile = xcalloc(GM100_WPO_FILE_SIZE, 1); + HxWFile = (unsigned char*) xcalloc(GM100_WPO_FILE_SIZE, 1); - file_out = gbfopen_le(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); } @@ -69,182 +69,184 @@ wr_init(const char *fname) static void wr_deinit(void) -{ - mkshort_del_handle(&mkshort_handle); - gbfclose(file_out); +{ + mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); } static void data_read(void) { - char name[9], desc[90]; - double lat,lon; - unsigned char *HxWpt; - waypoint *wpt_tmp; - int iCount; - int iDataRead; - int iWptNum; - int iWptIndex; - WPT *pWptHxTmp; - struct tm tm; - struct tm *ptm; - - memset(&tm, 0, sizeof(tm)); - - HxWpt = xcalloc(GM100_WPO_FILE_SIZE, 1); - - /* read the wpo file to the data-array */ - iDataRead = gbfread( HxWpt, 1, GM100_WPO_FILE_SIZE, file_in ); - - if (iDataRead == 0) - { - fatal(MYNAME ": Error reading data from %s.\n", file_in->name); - } + char name[9], desc[90]; + double lat,lon; + unsigned char* HxWpt; + waypoint* wpt_tmp; + int iCount; + int iDataRead; + int iWptNum; + int iWptIndex; + WPT* pWptHxTmp; + struct tm tm; + struct tm* ptm; + + memset(&tm, 0, sizeof(tm)); + + HxWpt = (unsigned char*) xcalloc(GM100_WPO_FILE_SIZE, 1); + + /* read the wpo file to the data-array */ + iDataRead = gbfread(HxWpt, 1, GM100_WPO_FILE_SIZE, file_in); + + if (iDataRead == 0) { + fatal(MYNAME ": Error reading data from %s.\n", file_in->name); + } + + iWptNum = le_read16(&((WPTHDR*)HxWpt)->num); + + /* Get the waypoints */ + for (iCount = 0; iCount < iWptNum ; iCount ++) { + wpt_tmp = waypt_new(); + + iWptIndex = le_read16(&((WPTHDR*)HxWpt)->idx[iCount]); + pWptHxTmp = (WPT*)&HxWpt[OFFS_WPT + (sizeof(WPT) * iWptIndex)]; + + wpt_tmp->altitude = 0; + strncpy(name,pWptHxTmp->name,sizeof(pWptHxTmp->name)); + name[sizeof(pWptHxTmp->name)]=0; + + strncpy(desc,pWptHxTmp->comment,sizeof(pWptHxTmp->comment)); + desc[sizeof(pWptHxTmp->comment)]=0; + + wpt_tmp->shortname = xstrdup(name); + wpt_tmp->description = xstrdup(desc); - iWptNum = le_read16(&((WPTHDR *)HxWpt)->num); - - /* Get the waypoints */ - for (iCount = 0; iCount < iWptNum ; iCount ++) - { - wpt_tmp = waypt_new(); - - iWptIndex = le_read16(&((WPTHDR *)HxWpt)->idx[iCount]); - pWptHxTmp = (WPT *)&HxWpt[OFFS_WPT + (sizeof(WPT) * iWptIndex)]; - - wpt_tmp->altitude = 0; - strncpy(name,pWptHxTmp->name,sizeof(pWptHxTmp->name)); - name[sizeof(pWptHxTmp->name)]=0; - - strncpy(desc,pWptHxTmp->comment,sizeof(pWptHxTmp->comment)); - desc[sizeof(pWptHxTmp->comment)]=0; - - wpt_tmp->shortname = xstrdup(name); - wpt_tmp->description = xstrdup(desc); - - wpt_tmp->creation_time = 0; - if (pWptHxTmp->date.year) - { + wpt_tmp->creation_time = 0; + if (pWptHxTmp->date.year) { #if 0 - /* Unless there's some endian swapping that I don't see, - * this can't be right. Then again, the definition of the - * the structure itself has a pretty serious disregard for - * host word size issues... - rjl - */ - ptm = gmtime((time_t*)&pWptHxTmp->time); + /* Unless there's some endian swapping that I don't see, + * this can't be right. Then again, the definition of the + * the structure itself has a pretty serious disregard for + * host word size issues... - rjl + */ + ptm = gmtime((time_t*)&pWptHxTmp->time); #else - time_t wt = le_read32(&pWptHxTmp->time); - ptm = gmtime(&wt); + time_t wt = le_read32(&pWptHxTmp->time); + ptm = gmtime(&wt); #endif - tm.tm_hour = ptm->tm_hour; - tm.tm_min = ptm->tm_min; - tm.tm_sec = ptm->tm_sec; - - tm.tm_mday = pWptHxTmp->date.day; - tm.tm_mon = pWptHxTmp->date.month - 1; - tm.tm_year = pWptHxTmp->date.year - 1900; - wpt_tmp->creation_time = mktime(&tm); - } - - lon = le_read32(&pWptHxTmp->pt.iLongitude) / 36000.0; - lat = (le_read32(&pWptHxTmp->pt.iLatitude) / 36000.0) * -1.0; - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - waypt_add(wpt_tmp); - } - xfree(HxWpt); + tm.tm_hour = ptm->tm_hour; + tm.tm_min = ptm->tm_min; + tm.tm_sec = ptm->tm_sec; + + tm.tm_mday = pWptHxTmp->date.day; + tm.tm_mon = pWptHxTmp->date.month - 1; + tm.tm_year = pWptHxTmp->date.year - 1900; + wpt_tmp->creation_time = mktime(&tm); + } + + lon = le_read32(&pWptHxTmp->pt.iLongitude) / 36000.0; + lat = (le_read32(&pWptHxTmp->pt.iLatitude) / 36000.0) * -1.0; + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + waypt_add(wpt_tmp); + } + xfree(HxWpt); } -char *mknshort (char *stIn,unsigned int sLen) +char* mknshort(char* stIn,unsigned int sLen) { - #define MAX_STRINGLEN 255 - static char strOut[MAX_STRINGLEN]; - char strTmp[MAX_STRINGLEN]; - char *shortstr = NULL; - - if (sLen > MAX_STRINGLEN) - return (stIn); - - if (stIn == NULL) - return NULL; - - setshort_length(mkshort_handle, sLen); - setshort_mustuniq(mkshort_handle, 0); - - shortstr = mkshort(mkshort_handle, stIn); - strcpy(strTmp,shortstr); - xfree(shortstr); - - memset(strOut,' ', MAX_STRINGLEN); - strncpy (strOut,strTmp,strlen(strTmp)); - return (strOut); -} +#define MAX_STRINGLEN 255 + static char strOut[MAX_STRINGLEN]; + char strTmp[MAX_STRINGLEN]; + char* shortstr = NULL; + if (sLen > MAX_STRINGLEN) { + return (stIn); + } + if (stIn == NULL) { + return NULL; + } + setshort_length(mkshort_handle, sLen); + setshort_mustuniq(mkshort_handle, 0); + + shortstr = mkshort(mkshort_handle, stIn); + strcpy(strTmp,shortstr); + xfree(shortstr); + + memset(strOut,' ', MAX_STRINGLEN); + strncpy(strOut,strTmp,strlen(strTmp)); + return (strOut); +} -static void holux_disp(const waypoint *wpt) -{ - double lon,lat; - struct tm *tm; - short sIndex; - WPT *pWptHxTmp; - - lon =(double)wpt->longitude * 36000; - lat =(double)wpt->latitude * -36000; - - - /* round it to increase the accuracy */ - if (lon != 0) lon += (double)((int)lon/abs((int)lon)) * .5; - if (lat != 0) lat += (double)((int)lat/abs((int)lat)) * .5; - - sIndex = le_read16(&((WPTHDR *)HxWFile)->num); - ((WPTHDR *)HxWFile)->idx[sIndex] = sIndex; /* set the waypoint index */ - le_write16(&((WPTHDR *)HxWFile)->idx[sIndex], sIndex); /* set the waypoint index */ - ((WPTHDR *)HxWFile)->used[sIndex] = 0xff; /* Waypoint used */ - - - /* set Waypoint */ - pWptHxTmp = (WPT *)&HxWFile[OFFS_WPT + (sizeof(WPT) * sIndex)]; - - memset (pWptHxTmp->name,0x20,sizeof(pWptHxTmp->name)); - if (wpt->shortname != NULL) - strncpy(pWptHxTmp->name, mknshort(wpt->shortname,sizeof(pWptHxTmp->name)),sizeof(pWptHxTmp->name)); - else - sprintf(pWptHxTmp->name,"W%d",sIndex); - - memset (pWptHxTmp->comment,0x20,sizeof(pWptHxTmp->comment)); - if (wpt->description != NULL) - strncpy(pWptHxTmp->comment, mknshort(wpt->description,sizeof(pWptHxTmp->comment)),sizeof(pWptHxTmp->comment)); - - /*set the time */ - if (wpt->creation_time) - { - /* tm = gmtime(&wpt->creation_time);*/ /* I get the wrong result with gmtime ??? */ - tm = localtime(&wpt->creation_time); - pWptHxTmp->time = (tm->tm_hour * 3600) + (tm->tm_min * 60) +tm->tm_sec; - pWptHxTmp->date.day = tm->tm_mday; - pWptHxTmp->date.month = tm->tm_mon + 1; - pWptHxTmp->date.year = tm->tm_year + 1900; - } - else - { - pWptHxTmp->time = 0; - pWptHxTmp->date.day = 0; - pWptHxTmp->date.month = 0; - pWptHxTmp->date.year = 0; - } - le_write32(&pWptHxTmp->pt.iLatitude,(unsigned int) lat); - le_write32(&pWptHxTmp->pt.iLongitude,(unsigned int) lon); - pWptHxTmp->checked = 01; - pWptHxTmp->vocidx = (short)0xffff; - le_write16(&((WPTHDR *)HxWFile)->num, ++sIndex); - le_write16(&((WPTHDR *)HxWFile)->next, ++sIndex); + +static void holux_disp(const waypoint* wpt) +{ + double lon,lat; + struct tm* tm; + short sIndex; + WPT* pWptHxTmp; + + lon =(double)wpt->longitude * 36000; + lat =(double)wpt->latitude * -36000; + + + /* round it to increase the accuracy */ + if (lon != 0) { + lon += (double)((int)lon/abs((int)lon)) * .5; + } + if (lat != 0) { + lat += (double)((int)lat/abs((int)lat)) * .5; + } + + sIndex = le_read16(&((WPTHDR*)HxWFile)->num); + ((WPTHDR*)HxWFile)->idx[sIndex] = sIndex; /* set the waypoint index */ + le_write16(&((WPTHDR*)HxWFile)->idx[sIndex], sIndex); /* set the waypoint index */ + ((WPTHDR*)HxWFile)->used[sIndex] = 0xff; /* Waypoint used */ + + + /* set Waypoint */ + pWptHxTmp = (WPT*)&HxWFile[OFFS_WPT + (sizeof(WPT) * sIndex)]; + + memset(pWptHxTmp->name,0x20,sizeof(pWptHxTmp->name)); + if (wpt->shortname != NULL) { + strncpy(pWptHxTmp->name, mknshort(wpt->shortname,sizeof(pWptHxTmp->name)),sizeof(pWptHxTmp->name)); + } else { + sprintf(pWptHxTmp->name,"W%d",sIndex); + } + + memset(pWptHxTmp->comment,0x20,sizeof(pWptHxTmp->comment)); + if (wpt->description != NULL) { + strncpy(pWptHxTmp->comment, mknshort(wpt->description,sizeof(pWptHxTmp->comment)),sizeof(pWptHxTmp->comment)); + } + + /*set the time */ + if (wpt->creation_time) { + /* tm = gmtime(&wpt->creation_time);*/ /* I get the wrong result with gmtime ??? */ + tm = localtime(&wpt->creation_time); + pWptHxTmp->time = (tm->tm_hour * 3600) + (tm->tm_min * 60) +tm->tm_sec; + pWptHxTmp->date.day = tm->tm_mday; + pWptHxTmp->date.month = tm->tm_mon + 1; + pWptHxTmp->date.year = tm->tm_year + 1900; + } else { + pWptHxTmp->time = 0; + pWptHxTmp->date.day = 0; + pWptHxTmp->date.month = 0; + pWptHxTmp->date.year = 0; + } + + + le_write32(&pWptHxTmp->pt.iLatitude,(unsigned int) lat); + le_write32(&pWptHxTmp->pt.iLongitude,(unsigned int) lon); + pWptHxTmp->checked = 01; + pWptHxTmp->vocidx = (short)0xffff; + le_write16(&((WPTHDR*)HxWFile)->num, ++sIndex); + le_write16(&((WPTHDR*)HxWFile)->next, ++sIndex); } @@ -254,55 +256,58 @@ static void holux_disp(const waypoint *wpt) static void data_write(void) { - int iWritten; - short sCount; - - /* init the waypoint area*/ - le_write32(&((WPTHDR *)HxWFile)->id, WPT_HDR_ID); - ((WPTHDR *)HxWFile)->num = 0; - ((WPTHDR *)HxWFile)->next = 0; - - /* clear index list */ - for (sCount = 0; sCount < MAXWPT; sCount++) - ((WPTHDR *)HxWFile)->idx[sCount] = (signed short)-1; - for (sCount = 0; sCount < MAXWPT; sCount++) - ((WPTHDR *)HxWFile)->used[sCount] = 0; - - /* init the route area */ - le_write32(&((RTEHDR *)&HxWFile[ROUTESTART])->id, RTE_HDR_ID); - ((RTEHDR *)&HxWFile[ROUTESTART])->num = 0; - le_write16(&((RTEHDR *)&HxWFile[ROUTESTART])->next, 1); - ((RTEHDR *)&HxWFile[ROUTESTART])->rteno = (signed short)-1; - - /* clear index list */ - for (sCount = 0; sCount < MAXRTE; sCount++) - ((RTEHDR *)&HxWFile[ROUTESTART])->idx[sCount] = (signed short)-1; - for (sCount = 0; sCount < MAXRTE; sCount++) - ((RTEHDR *)&HxWFile[ROUTESTART])->used[sCount] = 0; - - waypt_disp_all(holux_disp); - - iWritten = gbfwrite (HxWFile, 1, GM100_WPO_FILE_SIZE,file_out); - if (iWritten == 0) - { - fatal(MYNAME ": Error writing data to %s.\n", file_out->name); - } - xfree(HxWFile); + int iWritten; + short sCount; + + /* init the waypoint area*/ + le_write32(&((WPTHDR*)HxWFile)->id, WPT_HDR_ID); + ((WPTHDR*)HxWFile)->num = 0; + ((WPTHDR*)HxWFile)->next = 0; + + /* clear index list */ + for (sCount = 0; sCount < MAXWPT; sCount++) { + ((WPTHDR*)HxWFile)->idx[sCount] = (signed short)-1; + } + for (sCount = 0; sCount < MAXWPT; sCount++) { + ((WPTHDR*)HxWFile)->used[sCount] = 0; + } + + /* init the route area */ + le_write32(&((RTEHDR*)&HxWFile[ROUTESTART])->id, RTE_HDR_ID); + ((RTEHDR*)&HxWFile[ROUTESTART])->num = 0; + le_write16(&((RTEHDR*)&HxWFile[ROUTESTART])->next, 1); + ((RTEHDR*)&HxWFile[ROUTESTART])->rteno = (signed short)-1; + + /* clear index list */ + for (sCount = 0; sCount < MAXRTE; sCount++) { + ((RTEHDR*)&HxWFile[ROUTESTART])->idx[sCount] = (signed short)-1; + } + for (sCount = 0; sCount < MAXRTE; sCount++) { + ((RTEHDR*)&HxWFile[ROUTESTART])->used[sCount] = 0; + } + + waypt_disp_all(holux_disp); + + iWritten = gbfwrite(HxWFile, 1, GM100_WPO_FILE_SIZE,file_out); + if (iWritten == 0) { + fatal(MYNAME ": Error writing data to %s.\n", file_out->name); + } + xfree(HxWFile); } ff_vecs_t holux_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/holux.h b/gpsbabel/holux.h index cab9e077c..8647566e2 100644 --- a/gpsbabel/holux.h +++ b/gpsbabel/holux.h @@ -18,8 +18,8 @@ */ - /* header file for the holux gm-100 wpo format */ - +/* header file for the holux gm-100 wpo format */ + #ifndef BYTE #define BYTE unsigned char #endif @@ -33,8 +33,8 @@ #endif -/* #define GM100_WPO_FILE_SIZE 25512 */ /* size of a holux gm-100 wpo file used by mapShow 1.4*/ -#define GM100_WPO_FILE_SIZE 25600 /* size of a holux gm-100 wpo file used by the GM-100*/ +/* #define GM100_WPO_FILE_SIZE 25512 */ /* size of a holux gm-100 wpo file used by mapShow 1.4*/ +#define GM100_WPO_FILE_SIZE 25600 /* size of a holux gm-100 wpo file used by the GM-100*/ #define ROUTESTART 23600 /* Offset for start of route */ #define MAXWPT 500 /* max number of waypoint */ @@ -45,73 +45,67 @@ #define RTE_HDR_ID 0xD87F59F0 /* route header */ - /* Offsets */ -#define OFFS_WPT 0x05E4 /* offet for waypoint table */ +/* Offsets */ +#define OFFS_WPT 0x05E4 /* offet for waypoint table */ -typedef struct tagWPTHDR -{ - DWORD id; /* WPT_HDR_ID */ - short num; /* Current wpt number */ - short next; /* next wpt number */ - short idx[MAXWPT]; /* saving wpt index here for each wpt, default was -1*/ - BYTE used[MAXWPT]; /* Have the match wpt been used (0xFF), Default was 0 */ -}WPTHDR; +typedef struct tagWPTHDR { + DWORD id; /* WPT_HDR_ID */ + short num; /* Current wpt number */ + short next; /* next wpt number */ + short idx[MAXWPT]; /* saving wpt index here for each wpt, default was -1*/ + BYTE used[MAXWPT]; /* Have the match wpt been used (0xFF), Default was 0 */ +} WPTHDR; -typedef struct tagPOINT -{ - signed int iLongitude; - signed int iLatitude; -}POINT; +typedef struct tagPOINT { + signed int iLongitude; + signed int iLatitude; +} POINT; -typedef struct tagDATE -{ - BYTE day; - BYTE month; - short year; -}HX_DATE; +typedef struct tagDATE { + BYTE day; + BYTE month; + short year; +} HX_DATE; -typedef struct tagWPT -{ - char name[8]; /* wpt name */ - char comment[12]; /* comment string */ - POINT pt; /* waypoint location */ - short vocidx; /* voice index, not used */ - short usecount; /* counter: times used by routes */ - HX_DATE date; /* date */ - unsigned time; /* time */ - char checked; /* Active or not */ - BYTE dummy[3]; /* fill bytes */ -}WPT; +typedef struct tagWPT { + char name[8]; /* wpt name */ + char comment[12]; /* comment string */ + POINT pt; /* waypoint location */ + short vocidx; /* voice index, not used */ + short usecount; /* counter: times used by routes */ + HX_DATE date; /* date */ + unsigned time; /* time */ + char checked; /* Active or not */ + BYTE dummy[3]; /* fill bytes */ +} WPT; -typedef struct tagRTEHDR -{ - DWORD id; /* RTE_HDR_ID */ - short num; /* Current route number */ - short next; /* next route number */ - signed short idx[MAXRTE]; /* saving route index here for each route, default was -1 */ - BYTE used[MAXRTE]; /* Have the wpt been used (0xFF), Default was 0 */ - signed short rteno; /* Saving navigationroute number here */ -}RTEHDR; +typedef struct tagRTEHDR { + DWORD id; /* RTE_HDR_ID */ + short num; /* Current route number */ + short next; /* next route number */ + signed short idx[MAXRTE]; /* saving route index here for each route, default was -1 */ + BYTE used[MAXRTE]; /* Have the wpt been used (0xFF), Default was 0 */ + signed short rteno; /* Saving navigationroute number here */ +} RTEHDR; -typedef struct tagRTE -{ - char name[8]; /* route name */ - char comment[12]; /* comment string */ - short wptnum; /* the total waypoint number */ - short wptidx[MAXWPTINRTE]; /* the waypoint index in this route */ - short reserved; - int date; /* date */ - int time; /* time */ -}RTE; +typedef struct tagRTE { + char name[8]; /* route name */ + char comment[12]; /* comment string */ + short wptnum; /* the total waypoint number */ + short wptidx[MAXWPTINRTE]; /* the waypoint index in this route */ + short reserved; + int date; /* date */ + int time; /* time */ +} RTE; diff --git a/gpsbabel/hsa_ndv.c b/gpsbabel/hsa_ndv.c index 867062280..9eec3bf6f 100644 --- a/gpsbabel/hsa_ndv.c +++ b/gpsbabel/hsa_ndv.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2004 HSA Systems, Sven Dowideit This program is free software; you can redistribute it and/or modify @@ -23,13 +23,13 @@ static XML_Parser psr; #endif -static char *cdatastr; +static char* cdatastr; static int in_Route = 0; static int in_ChartWork = 0; static int in_Object = 0; -static waypoint *wpt_tmp; -static char *routeName = "ROUTENAME"; +static waypoint* wpt_tmp; +static char* routeName = "ROUTENAME"; #define REPLACEMENT_SIRIUS_ATTR_SEPARATOR ';' #define ATTR_USRMRK "usrmrk" @@ -37,14 +37,14 @@ static char *routeName = "ROUTENAME"; #define ATTR_SHIPNAME "shpnam" static void readVersion4(gbfile* pFile); -static void getAttr(const char *data, const char *attr, char **val, char seperator); +static void getAttr(const char* data, const char* attr, char** val, char seperator); -static gbfile *fd; -static gbfile *ofd; +static gbfile* fd; +static gbfile* ofd; static arglist_t hsa_ndv_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; #define MYNAME "HsaNdv" @@ -53,9 +53,9 @@ arglist_t hsa_ndv_args[] = { #if ! HAVE_LIBEXPAT static void -hsa_ndv_rd_init(const char *fname) +hsa_ndv_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded HSA Endeavour support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded HSA Endeavour support because expat was not installed.\n"); } static void @@ -65,277 +65,228 @@ hsa_ndv_read(void) #else static void -hsa_ndv_start(void *data, const XML_Char *xml_el, const XML_Char **attr) +hsa_ndv_start(void* data, const XML_Char* xml_el, const XML_Char** attr) { - const char *el = xml_convert_to_char_string(xml_el); - + const char* el = xml_convert_to_char_string(xml_el); + // printf("<%s>\n", el); - if (strcmp(el, "Export") == 0) - {//should only be one - } - else if (strcmp(el, "Route") == 0) - { - in_Route++; - } - else if (strcmp(el, "Chartwork") == 0) - { - in_ChartWork++; - } - else if (strcmp(el, "Object") == 0) - { - wpt_tmp = waypt_new(); - wpt_tmp->altitude = unknown_alt; - in_Object++; - } - //reset data :) - memset(cdatastr,0, MY_CBUF); - xml_free_converted_string(el); + if (strcmp(el, "Export") == 0) { + //should only be one + } else if (strcmp(el, "Route") == 0) { + in_Route++; + } else if (strcmp(el, "Chartwork") == 0) { + in_ChartWork++; + } else if (strcmp(el, "Object") == 0) { + wpt_tmp = waypt_new(); + wpt_tmp->altitude = unknown_alt; + in_Object++; + } + //reset data :) + memset(cdatastr,0, MY_CBUF); + xml_free_converted_string(el); } static void -hsa_ndv_end(void *data, const XML_Char *xml_el) +hsa_ndv_end(void* data, const XML_Char* xml_el) { - const char *el = xml_convert_to_char_string(xml_el); - if (in_Route) - { - if (strcmp(el, "Version") == 0) - {//don't really care - } - else if (strcmp(el, "Name") == 0) - { - routeName = xstrdup(cdatastr); - } - else if (strcmp(el, "LastModified") == 0) - {//don't really care - } - if (in_Object) - { - if (strcmp(el, "ClassName") == 0) - { - } - else if (strcmp(el, "Attr") == 0) - { - getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); - getAttr(cdatastr, ATTR_USRMRK, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); - } - else if (strcmp(el, "LegAttr") == 0) - { - } - else if (strcmp(el, "NumberOfVertexs") == 0) - { - } - else if (strcmp(el, "Latitude") == 0) - { - wpt_tmp->latitude = atof(cdatastr); - } - else if (strcmp(el, "Longitude") == 0) - { - wpt_tmp->longitude = atof(cdatastr); - } - } - } - - if (in_ChartWork) - { - if (strcmp(el, "Version") == 0) - {//don't really care - } - if (in_Object) - { - if (strcmp(el, "ClassName") == 0) - { + const char* el = xml_convert_to_char_string(xml_el); + if (in_Route) { + if (strcmp(el, "Version") == 0) { + //don't really care + } else if (strcmp(el, "Name") == 0) { + routeName = xstrdup(cdatastr); + } else if (strcmp(el, "LastModified") == 0) { + //don't really care + } + if (in_Object) { + if (strcmp(el, "ClassName") == 0) { + } else if (strcmp(el, "Attr") == 0) { + getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + getAttr(cdatastr, ATTR_USRMRK, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + } else if (strcmp(el, "LegAttr") == 0) { + } else if (strcmp(el, "NumberOfVertexs") == 0) { + } else if (strcmp(el, "Latitude") == 0) { + wpt_tmp->latitude = atof(cdatastr); + } else if (strcmp(el, "Longitude") == 0) { + wpt_tmp->longitude = atof(cdatastr); + } + } + } + + if (in_ChartWork) { + if (strcmp(el, "Version") == 0) { + //don't really care + } + if (in_Object) { + if (strcmp(el, "ClassName") == 0) { // className = xstrdup(cdatastr); - } - else if (strcmp(el, "Attr") == 0) - { - //getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); - //getAttr(cdatastr, ATTR_SHIPNAME, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); - } - else if (strcmp(el, "NumberOfVertexs") == 0) - { - } - else if (strcmp(el, "Latitude") == 0) - { - wpt_tmp->latitude = atof(cdatastr); - } - else if (strcmp(el, "Longitude") == 0) - { - wpt_tmp->longitude = atof(cdatastr); - } - else if (strcmp(el, "Time") == 0) - { - wpt_tmp->creation_time = atoi(cdatastr); - } - } - } - - //ignore everything else for now.. - memset(cdatastr,0, MY_CBUF); - - if (strcmp(el, "Object") == 0) - { - if (in_Route) - { - waypt_add(wpt_tmp); - } - else if (in_ChartWork) - { - //TODO: not sure how i want to handle this.. - } - in_Object--; - } - else if (strcmp(el, "Route") == 0) - { - in_Route--; - } - else if (strcmp(el, "Chartwork") == 0) - { - in_ChartWork--; - } - xml_free_converted_string(el); + } else if (strcmp(el, "Attr") == 0) { + //getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + //getAttr(cdatastr, ATTR_SHIPNAME, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + } else if (strcmp(el, "NumberOfVertexs") == 0) { + } else if (strcmp(el, "Latitude") == 0) { + wpt_tmp->latitude = atof(cdatastr); + } else if (strcmp(el, "Longitude") == 0) { + wpt_tmp->longitude = atof(cdatastr); + } else if (strcmp(el, "Time") == 0) { + wpt_tmp->creation_time = atoi(cdatastr); + } + } + } + + //ignore everything else for now.. + memset(cdatastr,0, MY_CBUF); + + if (strcmp(el, "Object") == 0) { + if (in_Route) { + waypt_add(wpt_tmp); + } else if (in_ChartWork) { + //TODO: not sure how i want to handle this.. + } + in_Object--; + } else if (strcmp(el, "Route") == 0) { + in_Route--; + } else if (strcmp(el, "Chartwork") == 0) { + in_ChartWork--; + } + xml_free_converted_string(el); } static void -hsa_ndv_cdata(void *dta, const XML_Char *s, int len) +hsa_ndv_cdata(void* dta, const XML_Char* s, int len) { - char *estr; - estr = cdatastr + strlen(cdatastr); - memcpy(estr, s, len); + char* estr; + estr = cdatastr + strlen(cdatastr); + memcpy(estr, s, len); } static void -hsa_ndv_rd_init(const char *fname) +hsa_ndv_rd_init(const char* fname) { - fd = gbfopen(fname, "r", MYNAME); + fd = gbfopen(fname, "r", MYNAME); - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ":Cannot create XML parser\n"); - } + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - XML_SetElementHandler(psr, hsa_ndv_start, hsa_ndv_end); - cdatastr = xcalloc(MY_CBUF,1); - XML_SetCharacterDataHandler(psr, hsa_ndv_cdata); + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, hsa_ndv_start, hsa_ndv_end); + cdatastr = (char*) xcalloc(MY_CBUF,1); + XML_SetCharacterDataHandler(psr, hsa_ndv_cdata); } static void hsa_ndv_read(void) { - int len; - char buf[MY_CBUF + 1]; - - while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) - { - char *bad; - - buf[len] = '\0'; - if (NULL != strstr(buf, "nver=1")) - {//its the older format, not xml - gbfseek(fd, 0, SEEK_SET); - readVersion4(fd); - break; - } - //grumble - have to remove \x1f's from sirius attributes - bad = buf; - while (NULL != (bad = strchr(bad, '\x1f'))) - { - *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; - } - if (!XML_Parse(psr, buf, len, gbfeof(fd))) { - fatal(MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - } - - XML_ParserFree(psr); + int len; + char buf[MY_CBUF + 1]; + + while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { + char* bad; + + buf[len] = '\0'; + if (NULL != strstr(buf, "nver=1")) { + //its the older format, not xml + gbfseek(fd, 0, SEEK_SET); + readVersion4(fd); + break; + } + //grumble - have to remove \x1f's from sirius attributes + bad = buf; + while (NULL != (bad = strchr(bad, '\x1f'))) { + *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; + } + if (!XML_Parse(psr, buf, len, gbfeof(fd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + + XML_ParserFree(psr); } #endif -static void getAttr(const char *data, const char *attr, char **val, char seperator) +static void getAttr(const char* data, const char* attr, char** val, char seperator) { - char *start; - if ((start = strstr(data, attr)) != NULL) - { - char *end; - int len; - - end = strchr(start, seperator); - if (end == NULL) - { - end = start + strlen(start);//assume we are teh last attr - } - - len = end-start - strlen(attr); - - *val = xcalloc(len+1, 1); - memcpy(*val, start+strlen(attr), len); - (*val)[len] = '\0'; - } - else - { - *val = xcalloc(1, 1); - (*val)[0] = '\0'; - } + char* start; + if ((start = strstr(data, attr)) != NULL) { + char* end; + int len; + + end = strchr(start, seperator); + if (end == NULL) { + end = start + strlen(start);//assume we are teh last attr + } + + len = end-start - strlen(attr); + + *val = (char*) xcalloc(len+1, 1); + memcpy(*val, start+strlen(attr), len); + (*val)[len] = '\0'; + } else { + *val = (char*) xcalloc(1, 1); + (*val)[0] = '\0'; + } } static void hsa_ndv_rd_deinit(void) { - if ( cdatastr ) { - xfree(cdatastr); - } - gbfclose(fd); + if (cdatastr) { + xfree(cdatastr); + } + gbfclose(fd); } static void -hsa_ndv_wr_init(const char *fname) +hsa_ndv_wr_init(const char* fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void hsa_ndv_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static int legNum = 0; static void -hsa_ndv_waypt_pr(const waypoint *waypointp) +hsa_ndv_waypt_pr(const waypoint* waypointp) { - gbfprintf(ofd, "\t\t\n"); + gbfprintf(ofd, "\t\t\n"); - gbfprintf(ofd, "\t\t\twaypnt\n"); + gbfprintf(ofd, "\t\t\twaypnt\n"); //ignore these for now, they are s57 specific // fprintf(ofd, "\t\t\t0\n"); // fprintf(ofd, "\t\t\t1\n"); // fprintf(ofd, "\t\t\t1089009023\n"); - gbfprintf(ofd, "\t\t\t\n", routeName, waypointp->shortname, legNum, waypointp->description); - gbfprintf(ofd, "\t\t\t\n", routeName); - gbfprintf(ofd, "\t\t\t1\n"); - gbfprintf(ofd, "\t\t\t%lf\n", waypointp->latitude); - gbfprintf(ofd, "\t\t\t%lf\n", waypointp->longitude); + gbfprintf(ofd, "\t\t\t\n", routeName, waypointp->shortname, legNum, waypointp->description); + gbfprintf(ofd, "\t\t\t\n", routeName); + gbfprintf(ofd, "\t\t\t1\n"); + gbfprintf(ofd, "\t\t\t%lf\n", waypointp->latitude); + gbfprintf(ofd, "\t\t\t%lf\n", waypointp->longitude); - gbfprintf(ofd, "\t\t\n"); + gbfprintf(ofd, "\t\t\n"); - legNum++; + legNum++; } static void hsa_ndv_write(void) { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\t\n"); - gbfprintf(ofd, "\t\t1.0000000\n"); - gbfprintf(ofd, "\t\tROUTENAME\n"); /*TODO: used filename? */ - gbfprintf(ofd, "\t\t0\n"); - waypt_disp_all(hsa_ndv_waypt_pr); - gbfprintf(ofd, "\t\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\t\n"); + gbfprintf(ofd, "\t\t1.0000000\n"); + gbfprintf(ofd, "\t\tROUTENAME\n"); /*TODO: used filename? */ + gbfprintf(ofd, "\t\t0\n"); + waypt_disp_all(hsa_ndv_waypt_pr); + gbfprintf(ofd, "\t\n"); //later we'll import past tracks and chart objects? // fprintf(ofd, "\t\n"); @@ -344,21 +295,21 @@ hsa_ndv_write(void) // fprintf(ofd, "\t\n"); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } ff_vecs_t HsaEndeavourNavigator_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - hsa_ndv_rd_init, - hsa_ndv_wr_init, - hsa_ndv_rd_deinit, - hsa_ndv_wr_deinit, - hsa_ndv_read, - hsa_ndv_write, - NULL, - hsa_ndv_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + hsa_ndv_rd_init, + hsa_ndv_wr_init, + hsa_ndv_rd_deinit, + hsa_ndv_wr_deinit, + hsa_ndv_read, + hsa_ndv_write, + NULL, + hsa_ndv_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; ////////////////////////////////////////////////////////////////////////// @@ -376,184 +327,186 @@ ff_vecs_t HsaEndeavourNavigator_vecs = { #define INVALID_TIME -1L #define SOUNDARRAY_CHAR 'S' -static int readRecord(gbfile* pFile, const char* pRecName, char *recData); +static int readRecord(gbfile* pFile, const char* pRecName, char* recData); static int readPositionRecord(gbfile* pFile, double* lat, double* lng, long* timeStamp); static void readVersion4(gbfile* pFile) { - while( TRUE ) - { - char recData[256] = {0}; - // get the position - double lat2, lng2 = 0; - - // set the pointer to the time stamp depending - // on whether we have a sounding array or not - long ts1, ts2; - long* pts1 = 0; - long* pts2 = 0; - - int soundArray = FALSE; - int numberOfVerticies = 0; - char className[256]; - char attr[1024]; - int Vertex; - - memset(attr, 0, sizeof(attr)); - - wpt_tmp = waypt_new(); - - // read the first record - if( !readRecord( pFile, EF_NVER_REC, recData) ) - // no first record then finished - break; - - // get the type - sscanf( (const char*)recData, "%d", &numberOfVerticies); - - // do we have a sounding array - if( *((const char *)recData + strlen(recData) - 1) == SOUNDARRAY_CHAR ) - { - soundArray = TRUE; - } - - if( soundArray ) - { - pts1 = &ts1; - pts2 = &ts2; - } - - // go through the vertices - for( Vertex = 0; Vertex < numberOfVerticies; Vertex++) - { - // read vertex position - if( !readPositionRecord( pFile, &lat2, &lng2, pts2) ) { - xfree(wpt_tmp); - return; - } - - wpt_tmp->longitude = lng2; - wpt_tmp->latitude = lat2; - break;//TODO: ignore more points for now - } - - - // read the class name - if( !readRecord( pFile, EF_CLNM_REC, className) ) { - xfree( wpt_tmp ); - return; - } - - // read the attributes name - if( !readRecord( pFile, EF_ATTR_REC, attr) ) { - xfree( wpt_tmp ); - return; - } - getAttr(attr, ATTR_OBJECTNAME, &wpt_tmp->shortname, '\x1f'); - getAttr(attr, ATTR_USRMRK, &wpt_tmp->description, '\x1f'); - - { - char *bad; - //remove \n and \x1f from description data - while (NULL != (bad = strchr(wpt_tmp->description, '\x1f'))) - { - *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; - } - while (NULL != (bad = strchr(wpt_tmp->description, '\n'))) - { - *bad = ' '; - } - while (NULL != (bad = strchr(wpt_tmp->description, '\r'))) - { - *bad = ' '; - } - } - - waypt_add(wpt_tmp); - } - - gbfclose(pFile); - return; + while (TRUE) { + char recData[256] = {0}; + // get the position + double lat2, lng2 = 0; + + // set the pointer to the time stamp depending + // on whether we have a sounding array or not + long ts1, ts2; + long* pts1 = 0; + long* pts2 = 0; + + int soundArray = FALSE; + int numberOfVerticies = 0; + char className[256]; + char attr[1024]; + int Vertex; + + memset(attr, 0, sizeof(attr)); + + wpt_tmp = waypt_new(); + + // read the first record + if (!readRecord(pFile, EF_NVER_REC, recData)) + // no first record then finished + { + break; + } + + // get the type + sscanf((const char*)recData, "%d", &numberOfVerticies); + + // do we have a sounding array + if (*((const char*)recData + strlen(recData) - 1) == SOUNDARRAY_CHAR) { + soundArray = TRUE; + } + + if (soundArray) { + pts1 = &ts1; + pts2 = &ts2; + } + + // go through the vertices + for (Vertex = 0; Vertex < numberOfVerticies; Vertex++) { + // read vertex position + if (!readPositionRecord(pFile, &lat2, &lng2, pts2)) { + xfree(wpt_tmp); + return; + } + + wpt_tmp->longitude = lng2; + wpt_tmp->latitude = lat2; + break;//TODO: ignore more points for now + } + + + // read the class name + if (!readRecord(pFile, EF_CLNM_REC, className)) { + xfree(wpt_tmp); + return; + } + + // read the attributes name + if (!readRecord(pFile, EF_ATTR_REC, attr)) { + xfree(wpt_tmp); + return; + } + getAttr(attr, ATTR_OBJECTNAME, &wpt_tmp->shortname, '\x1f'); + getAttr(attr, ATTR_USRMRK, &wpt_tmp->description, '\x1f'); + + { + char* bad; + //remove \n and \x1f from description data + while (NULL != (bad = strchr(wpt_tmp->description, '\x1f'))) { + *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; + } + while (NULL != (bad = strchr(wpt_tmp->description, '\n'))) { + *bad = ' '; + } + while (NULL != (bad = strchr(wpt_tmp->description, '\r'))) { + *bad = ' '; + } + } + + waypt_add(wpt_tmp); + } + + gbfclose(pFile); + return; } // read a record to a file -static int readRecord(gbfile* pFile, const char* pRecName, char *recData) +static int readRecord(gbfile* pFile, const char* pRecName, char* recData) { - // get the rec name - int len; - char recName[ED_REC_NAME_SIZE+1]; - char arrRecData[256]; + // get the rec name + int len; + char recName[ED_REC_NAME_SIZE+1]; + char arrRecData[256]; - for( len = 0; len < ED_REC_NAME_SIZE; len++) - { - int c = gbfgetc(pFile); + for (len = 0; len < ED_REC_NAME_SIZE; len++) { + int c = gbfgetc(pFile); - // if we hit EOF failed - if( c == EOF ) - return FALSE; + // if we hit EOF failed + if (c == EOF) { + return FALSE; + } - recName[len] = c; - } + recName[len] = c; + } - // if the record name is not the reqiured type then error - if( strncmp( recName, pRecName, ED_REC_NAME_SIZE) != 0 ) - return FALSE; + // if the record name is not the reqiured type then error + if (strncmp(recName, pRecName, ED_REC_NAME_SIZE) != 0) { + return FALSE; + } - // get the rec data - for( len = 0; TRUE; len++) - { - int c = gbfgetc( pFile); + // get the rec data + for (len = 0; TRUE; len++) { + int c = gbfgetc(pFile); - // if we hit EOF failed - if( c == EOF ) - return FALSE; + // if we hit EOF failed + if (c == EOF) { + return FALSE; + } - // hit end of line - if( c == EF_RECORD_DELIMTER ) - break; + // hit end of line + if (c == EF_RECORD_DELIMTER) { + break; + } - arrRecData[len] = c; - } + arrRecData[len] = c; + } - // get the rec data to a string - strncpy(recData, arrRecData, len); + // get the rec data to a string + strncpy(recData, arrRecData, len); - return TRUE; + return TRUE; } // read position -static int readPositionRecord(gbfile* pFile, double* lat, double* lng, - long* timeStamp) +static int readPositionRecord(gbfile* pFile, double* lat, double* lng, + long* timeStamp) { - // read the lat record - char recData[256] = {0}; - - if( !readRecord( pFile, EF_LAT_REC, recData) ) - // no lat record then finished - return FALSE; - - // read the latitude - sscanf( (const char*)recData, "%lf", lat); - - // read the lng record - if( !readRecord( pFile, EF_LONG_REC, recData) ) - // no first record then finished - return FALSE; - - // read the latitude - sscanf( (const char*)recData, "%lf", lng); - - // if we are to read a time record - if( timeStamp ) - { - // read the lng record - if( !readRecord( pFile, EF_TIME_REC, recData) ) - // no first record then finished - return FALSE; - - // read the latitude - sscanf( (const char*)recData, "%ld", timeStamp); - } - - return TRUE; + // read the lat record + char recData[256] = {0}; + + if (!readRecord(pFile, EF_LAT_REC, recData)) + // no lat record then finished + { + return FALSE; + } + + // read the latitude + sscanf((const char*)recData, "%lf", lat); + + // read the lng record + if (!readRecord(pFile, EF_LONG_REC, recData)) + // no first record then finished + { + return FALSE; + } + + // read the latitude + sscanf((const char*)recData, "%lf", lng); + + // if we are to read a time record + if (timeStamp) { + // read the lng record + if (!readRecord(pFile, EF_TIME_REC, recData)) + // no first record then finished + { + return FALSE; + } + + // read the latitude + sscanf((const char*)recData, "%ld", timeStamp); + } + + return TRUE; } diff --git a/gpsbabel/html.c b/gpsbabel/html.c index ee1cc53be..9e21da9aa 100644 --- a/gpsbabel/html.c +++ b/gpsbabel/html.c @@ -24,272 +24,282 @@ #include "jeeps/gpsmath.h" #include -static gbfile *file_out; +static gbfile* file_out; static short_handle mkshort_handle; -static char *stylesheet = NULL; -static char *html_encrypt = NULL; -static char *includelogs = NULL; -static char *degformat = NULL; -static char *altunits = NULL; +static char* stylesheet = NULL; +static char* html_encrypt = NULL; +static char* includelogs = NULL; +static char* degformat = NULL; +static char* altunits = NULL; #define MYNAME "HTML" static arglist_t html_args[] = { - { "stylesheet", &stylesheet, - "Path to HTML style sheet", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "encrypt", &html_encrypt, - "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logs", &includelogs, - "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "degformat", °format, - "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX }, - { "altunits", &altunits, - "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "stylesheet", &stylesheet, + "Path to HTML style sheet", NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "encrypt", &html_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logs", &includelogs, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "degformat", °format, + "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "altunits", &altunits, + "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = gbfopen(fname, "w", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void -html_disp(const waypoint *wpt) +html_disp(const waypoint* wpt) { - char tbuf[1024]; - char *cout; - time_t tm = wpt->creation_time; - gbint32 utmz; - double utme, utmn; - char utmzc; - fs_xml *fs_gpx = NULL; - - - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - - if (tm == 0) - tm = time(NULL); - strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); - - - gbfprintf(file_out, "\n
\n", wpt->shortname); - gbfprintf(file_out, "\n"); - gbfprintf(file_out, "\n"); - - gbfprintf (file_out, "\n"); - - - gbfprintf(file_out, "

%s - ",(global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname); - cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 1); - gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn); - xfree (cout); - if (wpt->altitude != unknown_alt) - gbfprintf (file_out, " alt:%d", (int) ( (altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude) ); - gbfprintf (file_out, "
\n"); - if (strcmp(wpt->description, wpt->shortname)) { - if (wpt->url) { - char *d = html_entitize(wpt->description); - gbfprintf(file_out, "%s", wpt->url, d); - xfree(d); - } - else { - gbfprintf(file_out, "%s", wpt->description); - } - if (wpt->gc_data->placer) { - gbfprintf(file_out, " by %s", wpt->gc_data->placer); - } - } - gbfprintf(file_out, "

"); - if (wpt->gc_data->terr) { - gbfprintf (file_out, "

%d%s / %d%s
\n", - (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?"½":"", - (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?"½":"" ); - gbfprintf(file_out, "%s / %s

", - gs_get_cachetype(wpt->gc_data->type), - gs_get_container(wpt->gc_data->container)); - } - gbfprintf(file_out, "
"); - if (wpt->gc_data->desc_short.utfstring) { - char *tmpstr = strip_nastyhtml(wpt->gc_data->desc_short.utfstring); - gbfprintf (file_out, "

%s

\n", tmpstr ); - xfree( tmpstr ); - } - if (wpt->gc_data->desc_long.utfstring) { - char *tmpstr = strip_nastyhtml(wpt->gc_data->desc_long.utfstring); - gbfprintf (file_out, "

%s

\n", tmpstr ); - xfree( tmpstr ); - } - if (wpt->gc_data->hint) { - char *hint = NULL; - if ( html_encrypt ) - hint = rot13( wpt->gc_data->hint ); - else - hint = xstrdup( wpt->gc_data->hint ); - gbfprintf (file_out, "

Hint: %s

\n", hint); - xfree( hint ); - } - else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { - gbfprintf (file_out, "

%s

\n", wpt->notes); - } - - fs_gpx = NULL; - if ( includelogs ) { - fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX); - } - - if ( fs_gpx && fs_gpx->tag ) { - xml_tag *root = fs_gpx->tag; - xml_tag *curlog = NULL; - xml_tag *logpart = NULL; - curlog = xml_findfirst( root, "groundspeak:log" ); - while ( curlog ) { - time_t logtime = 0; - struct tm *logtm = NULL; - gbfprintf( file_out, "

\n" ); - - logpart = xml_findfirst( curlog, "groundspeak:type" ); - if ( logpart ) { - gbfprintf( file_out, "%s by ", logpart->cdata ); - } - - logpart = xml_findfirst( curlog, "groundspeak:finder" ); - if ( logpart ) { - char *f = html_entitize( logpart->cdata ); - gbfprintf( file_out, "%s on ", f ); - xfree( f ); - } - - logpart = xml_findfirst( curlog, "groundspeak:date" ); - if ( logpart ) { - logtime = xml_parse_time( logpart->cdata, NULL); - logtm = localtime( &logtime ); - if ( logtm ) { - gbfprintf( file_out, - "%04d-%02d-%02d
\n", - logtm->tm_year+1900, - logtm->tm_mon+1, - logtm->tm_mday ); - } - } - - logpart = xml_findfirst( curlog, "groundspeak:log_wpt" ); - if ( logpart ) { - char *coordstr = NULL; - float lat = 0; - float lon = 0; - coordstr = xml_attribute( logpart, "lat" ); - if ( coordstr ) { - lat = atof( coordstr ); - } - coordstr = xml_attribute( logpart, "lon" ); - if ( coordstr ) { - lon = atof( coordstr ); - } - coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1); - gbfprintf( file_out, - "%s
\n", - coordstr ); - xfree(coordstr); - } - - logpart = xml_findfirst( curlog, "groundspeak:text" ); - if ( logpart ) { - char *encstr = NULL; - char *s = NULL; - char *t = NULL; - int encoded = 0; - encstr = xml_attribute( logpart, "encoded" ); - encoded = (encstr[0] != 'F'); - - if ( html_encrypt && encoded ) { - s = rot13( logpart->cdata ); - } - else { - s = xstrdup( logpart->cdata ); - } - - t = html_entitize( s ); - gbfprintf( file_out, "%s", t ); - xfree( t ); - xfree( s ); - } - - gbfprintf( file_out, "

\n" ); - curlog = xml_findnext( root, curlog, "groundspeak:log" ); - } - } - gbfprintf(file_out, "
\n"); + char tbuf[1024]; + char* cout; + time_t tm = wpt->creation_time; + gbint32 utmz; + double utme, utmn; + char utmzc; + fs_xml* fs_gpx = NULL; + + + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + + if (tm == 0) { + tm = time(NULL); + } + strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); + + + gbfprintf(file_out, "\n
\n", wpt->shortname); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + + gbfprintf(file_out, "\n"); + + + gbfprintf(file_out, "

%s - ",(global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname); + cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 1); + gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn); + xfree(cout); + if (wpt->altitude != unknown_alt) { + gbfprintf(file_out, " alt:%d", (int)((altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude)); + } + gbfprintf(file_out, "
\n"); + if (strcmp(wpt->description, wpt->shortname)) { + if (wpt->url) { + char* d = html_entitize(wpt->description); + gbfprintf(file_out, "%s", wpt->url, d); + xfree(d); + } else { + gbfprintf(file_out, "%s", wpt->description); + } + if (wpt->gc_data->placer) { + gbfprintf(file_out, " by %s", wpt->gc_data->placer); + } + } + gbfprintf(file_out, "

"); + if (wpt->gc_data->terr) { + gbfprintf(file_out, "

%d%s / %d%s
\n", + (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?"½":"", + (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?"½":""); + gbfprintf(file_out, "%s / %s

", + gs_get_cachetype(wpt->gc_data->type), + gs_get_container(wpt->gc_data->container)); + } + gbfprintf(file_out, "
"); + if (wpt->gc_data->desc_short.utfstring) { + char* tmpstr = strip_nastyhtml(wpt->gc_data->desc_short.utfstring); + gbfprintf(file_out, "

%s

\n", tmpstr); + xfree(tmpstr); + } + if (wpt->gc_data->desc_long.utfstring) { + char* tmpstr = strip_nastyhtml(wpt->gc_data->desc_long.utfstring); + gbfprintf(file_out, "

%s

\n", tmpstr); + xfree(tmpstr); + } + if (wpt->gc_data->hint) { + char* hint = NULL; + if (html_encrypt) { + hint = rot13(wpt->gc_data->hint); + } else { + hint = xstrdup(wpt->gc_data->hint); + } + gbfprintf(file_out, "

Hint: %s

\n", hint); + xfree(hint); + } else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { + gbfprintf(file_out, "

%s

\n", wpt->notes); + } + + fs_gpx = NULL; + if (includelogs) { + fs_gpx = (fs_xml*)fs_chain_find(wpt->fs, FS_GPX); + } + + if (fs_gpx && fs_gpx->tag) { + xml_tag* root = fs_gpx->tag; + xml_tag* curlog = NULL; + xml_tag* logpart = NULL; + curlog = xml_findfirst(root, "groundspeak:log"); + while (curlog) { + time_t logtime = 0; + struct tm* logtm = NULL; + gbfprintf(file_out, "

\n"); + + logpart = xml_findfirst(curlog, "groundspeak:type"); + if (logpart) { + gbfprintf(file_out, "%s by ", logpart->cdata); + } + + logpart = xml_findfirst(curlog, "groundspeak:finder"); + if (logpart) { + char* f = html_entitize(logpart->cdata); + gbfprintf(file_out, "%s on ", f); + xfree(f); + } + + logpart = xml_findfirst(curlog, "groundspeak:date"); + if (logpart) { + logtime = xml_parse_time(logpart->cdata, NULL); + logtm = localtime(&logtime); + if (logtm) { + gbfprintf(file_out, + "%04d-%02d-%02d
\n", + logtm->tm_year+1900, + logtm->tm_mon+1, + logtm->tm_mday); + } + } + + logpart = xml_findfirst(curlog, "groundspeak:log_wpt"); + if (logpart) { + char* coordstr = NULL; + float lat = 0; + float lon = 0; + coordstr = xml_attribute(logpart, "lat"); + if (coordstr) { + lat = atof(coordstr); + } + coordstr = xml_attribute(logpart, "lon"); + if (coordstr) { + lon = atof(coordstr); + } + coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1); + gbfprintf(file_out, + "%s
\n", + coordstr); + xfree(coordstr); + } + + logpart = xml_findfirst(curlog, "groundspeak:text"); + if (logpart) { + char* encstr = NULL; + char* s = NULL; + char* t = NULL; + int encoded = 0; + encstr = xml_attribute(logpart, "encoded"); + encoded = (toupper(encstr[0]) != 'F'); + + if (html_encrypt && encoded) { + s = rot13(logpart->cdata); + } else { + s = xstrdup(logpart->cdata); + } + + t = html_entitize(s); + gbfprintf(file_out, "%s", t); + xfree(t); + xfree(s); + } + + gbfprintf(file_out, "

\n"); + curlog = xml_findnext(root, curlog, "groundspeak:log"); + } + } + gbfprintf(file_out, "
\n"); } static void -html_index(const waypoint *wpt) +html_index(const waypoint* wpt) { - char *sn = html_entitize(wpt->shortname); - char *d = html_entitize(wpt->description); + char* sn = html_entitize(wpt->shortname); + char* d = html_entitize(wpt->description); - gbfprintf(file_out, "%s - %s
\n", sn, sn, d); + gbfprintf(file_out, "%s - %s
\n", sn, sn, d); - xfree(sn); - xfree(d); + xfree(sn); + xfree(d); } static void data_write(void) { - setshort_length(mkshort_handle, 6); - - gbfprintf(file_out, "\n"); - gbfprintf(file_out, "\n"); - gbfprintf(file_out, "\n"); - gbfprintf(file_out, " \n"); - gbfprintf(file_out, " \n", gpsbabel_version); - gbfprintf(file_out, " GPSBabel HTML Output\n"); - if (stylesheet) - gbfprintf(file_out, " \n", stylesheet); - else { - gbfprintf(file_out, " \n"); - } - gbfprintf(file_out, "\n"); - gbfprintf(file_out, "\n"); - - gbfprintf(file_out, "

\n"); - waypt_disp_all(html_index); - gbfprintf(file_out, "

\n"); - - waypt_disp_all(html_disp); - - gbfprintf(file_out, ""); - gbfprintf(file_out, ""); + setshort_length(mkshort_handle, 6); + + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, " \n"); + gbfprintf(file_out, " \n", gpsbabel_version); + gbfprintf(file_out, " GPSBabel HTML Output\n"); + if (stylesheet) { + gbfprintf(file_out, " \n", stylesheet); + } else { + gbfprintf(file_out, " \n"); + } + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + + gbfprintf(file_out, "

\n"); + waypt_disp_all(html_index); + gbfprintf(file_out, "

\n"); + + waypt_disp_all(html_disp); + + gbfprintf(file_out, ""); + gbfprintf(file_out, ""); } ff_vecs_t html_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_none, ff_cap_none }, - NULL, - wr_init, - NULL, - wr_deinit, - NULL, - data_write, - NULL, - html_args, - CET_CHARSET_UTF8, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none }, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + html_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/humminbird.c b/gpsbabel/humminbird.c index 90ec0071e..4eaa7f85e 100644 --- a/gpsbabel/humminbird.c +++ b/gpsbabel/humminbird.c @@ -59,165 +59,169 @@ Still, they're usful in the code as a plain signature. /* The hwr data format is records-based, and the records are 36 bytes long. */ typedef struct humminbird_waypt_s { - /* O.K.: the file can also contain routes with a different magic. */ - /* gbuint32 signature; */ /* Just for error checking(?) */ - gbuint16 num; /* Always ascending in the file. */ - gbuint16 zero; /* Always seems to be zero. */ - gbuint8 status; /* Always seems to be 1. Ends up as + /* O.K.: the file can also contain routes with a different magic. */ + /* gbuint32 signature; */ /* Just for error checking(?) */ + gbuint16 num; /* Always ascending in the file. */ + gbuint16 zero; /* Always seems to be zero. */ + gbuint8 status; /* Always seems to be 1. Ends up as in gpx files exported by HumminbirdPC. */ - gbuint8 icon; /* See below */ - gbuint16 depth; /* Water depth. These are fishfinders. In centimeters */ - gbuint32 time; /* This is a time_t. In UTC */ - gbint32 east; - gbint32 north; - char name[WPT_NAME_LEN]; + gbuint8 icon; /* See below */ + gbuint16 depth; /* Water depth. These are fishfinders. In centimeters */ + gbuint32 time; /* This is a time_t. In UTC */ + gbint32 east; + gbint32 north; + char name[WPT_NAME_LEN]; } humminbird_waypt_t; typedef struct humminbird_rte_s { - /* O.K.: the file can contain also routes with a different magic. */ - /* gbuint32 signature; */ /* Just for error checking(?) */ - gbuint16 num; - gbuint16 zero; - gbuint8 status; - gbuint8 U0; - gbuint8 U1; - gbint8 count; - gbuint32 time; - char name[RTE_NAME_LEN]; - gbuint16 points[MAX_RTE_POINTS]; + /* O.K.: the file can contain also routes with a different magic. */ + /* gbuint32 signature; */ /* Just for error checking(?) */ + gbuint16 num; + gbuint16 zero; + gbuint8 status; + gbuint8 U0; + gbuint8 U1; + gbint8 count; + gbuint32 time; + char name[RTE_NAME_LEN]; + gbuint16 points[MAX_RTE_POINTS]; } humminbird_rte_t; typedef struct humminbird_trk_header_s { /* 68 bytes, incl signature */ - /* gbuint32 signature; */ - gbuint16 trk_num; - gbuint16 zero; - gbuint16 num_points; - gbuint16 unknown; /* Always zero so far. */ - gbuint32 time; /* a time_t, in UTC */ - - gbint32 start_east; /* Start of track */ - gbint32 start_north; - gbint32 end_east; /* end of track */ - gbint32 end_north; - - gbint32 sw_east; /* Bounding box, enclosing the track */ - gbint32 sw_north; /* sw is the south-west point */ - gbint32 ne_east; /* ne is the north-east point */ - gbint32 ne_north; - - char name[20]; + /* gbuint32 signature; */ + gbuint16 trk_num; + gbuint16 zero; + gbuint16 num_points; + gbuint16 unknown; /* Always zero so far. */ + gbuint32 time; /* a time_t, in UTC */ + + gbint32 start_east; /* Start of track */ + gbint32 start_north; + gbint32 end_east; /* end of track */ + gbint32 end_north; + + gbint32 sw_east; /* Bounding box, enclosing the track */ + gbint32 sw_north; /* sw is the south-west point */ + gbint32 ne_east; /* ne is the north-east point */ + gbint32 ne_north; + + char name[20]; } humminbird_trk_header_t; typedef struct humminbird_trk_point_s { - gbint16 deltaeast; - gbint16 deltanorth; - gbuint16 depth; /* in centimeters */ + gbint16 deltaeast; + gbint16 deltanorth; + gbuint16 depth; /* in centimeters */ } humminbird_trk_point_t; typedef struct humminbird_trk_header_old_s { /* 16 bytes, incl signature */ - /* gbuint32 signature; */ - gbuint16 trk_num; - gbuint16 zero; - gbuint16 num_points; - gbuint16 unknown; /* Always zero so far. */ - gbuint32 time; /* a time_t, in UTC */ - - gbint32 start_east; /* Start of track */ - gbint32 start_north; - gbint32 end_east; /* end of track */ - gbint32 end_north; + /* gbuint32 signature; */ + gbuint16 trk_num; + gbuint16 zero; + gbuint16 num_points; + gbuint16 unknown; /* Always zero so far. */ + gbuint32 time; /* a time_t, in UTC */ + + gbint32 start_east; /* Start of track */ + gbint32 start_north; + gbint32 end_east; /* end of track */ + gbint32 end_north; } humminbird_trk_header_old_t; typedef struct humminbird_trk_point_old_s { - gbint16 deltaeast; - gbint16 deltanorth; + gbint16 deltaeast; + gbint16 deltanorth; } humminbird_trk_point_old_t; static const char* humminbird_icons[] = { - "Normal", /* 0 */ - "House", /* 1 */ - "Red cross", /* 2 */ - "Fish", /* 3 */ - "Duck", /* 4 */ - "Anchor", /* 5 */ - "Buoy", /* 6 */ - "Airport", /* 7 */ - "Camping", /* 8 */ - "Danger", /* 9 */ - "Fuel", /* 10 */ - "Rock", /* 11 */ - "Weed", /* 12 */ - "Wreck", /* 13 */ - "Phone", /* 14 */ - "Coffee", /* 15 */ - "Beer", /* 16 */ - "Mooring", /* 17 */ - "Pier", /* 18 */ - "Slip", /* 19 */ - "Ramp", /* 20 */ - "Circle", /* 21 */ - "Diamond", /* 22 */ - "Flag", /* 23 */ - "Pattern", /* 24 */ - "Shower", /* 25 */ - "Water tap", /* 26 */ - "Tree", /* 27 */ - "Recording", /* 28 */ - "Snapshot" /* 29 */ + "Normal", /* 0 */ + "House", /* 1 */ + "Red cross", /* 2 */ + "Fish", /* 3 */ + "Duck", /* 4 */ + "Anchor", /* 5 */ + "Buoy", /* 6 */ + "Airport", /* 7 */ + "Camping", /* 8 */ + "Danger", /* 9 */ + "Fuel", /* 10 */ + "Rock", /* 11 */ + "Weed", /* 12 */ + "Wreck", /* 13 */ + "Phone", /* 14 */ + "Coffee", /* 15 */ + "Beer", /* 16 */ + "Mooring", /* 17 */ + "Pier", /* 18 */ + "Slip", /* 19 */ + "Ramp", /* 20 */ + "Circle", /* 21 */ + "Diamond", /* 22 */ + "Flag", /* 23 */ + "Pattern", /* 24 */ + "Shower", /* 25 */ + "Water tap", /* 26 */ + "Tree", /* 27 */ + "Recording", /* 28 */ + "Snapshot" /* 29 */ }; static gbfile* fin; static gbfile* fout; static int waypoint_num; static short_handle wptname_sh, rtename_sh, trkname_sh; -static avltree_t *waypoints; -static humminbird_rte_t *humrte; +static avltree_t* waypoints; +static humminbird_rte_t* humrte; static int rte_num; static arglist_t humminbird_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /* Takes a latitude in degrees, * returns a latitude in degrees. */ static double -geodetic_to_geocentric_hwr(const double gd_lat) { - const double cos_ae = 0.9966349016452; - const double cos2_ae = cos_ae * cos_ae; - const double gdr = gd_lat *M_PI / 180.0; +geodetic_to_geocentric_hwr(const double gd_lat) +{ + const double cos_ae = 0.9966349016452; + const double cos2_ae = cos_ae * cos_ae; + const double gdr = gd_lat *M_PI / 180.0; - return atan(cos2_ae * tan(gdr)) * 180.0/M_PI; + return atan(cos2_ae * tan(gdr)) * 180.0/M_PI; } /* Takes a latitude in degrees, * returns a latitude in degrees. */ static double -geocentric_to_geodetic_hwr(const double gc_lat) { - const double cos_ae = 0.9966349016452; - const double cos2_ae = cos_ae * cos_ae; - const double gcr = gc_lat *M_PI / 180.0; +geocentric_to_geodetic_hwr(const double gc_lat) +{ + const double cos_ae = 0.9966349016452; + const double cos2_ae = cos_ae * cos_ae; + const double gcr = gc_lat *M_PI / 180.0; - return atan( tan(gcr)/cos2_ae ) * 180.0/M_PI; + return atan(tan(gcr)/cos2_ae) * 180.0/M_PI; } /* Takes a projected "north" value, returns latitude in degrees. */ static double -gudermannian_i1924(const double x) { - const double norm_x = x/i1924_equ_axis; +gudermannian_i1924(const double x) +{ + const double norm_x = x/i1924_equ_axis; - return atan(sinh(norm_x)) * 180.0/M_PI; + return atan(sinh(norm_x)) * 180.0/M_PI; } /* Takes latitude in degrees, returns projected "north" value. */ static double -inverse_gudermannian_i1924(const double x) { - const double x_r = x/180.0 * M_PI; - const double guder = log(tan(M_PI/4.0 + x_r/2.0)); +inverse_gudermannian_i1924(const double x) +{ + const double x_r = x/180.0 * M_PI; + const double guder = log(tan(M_PI/4.0 + x_r/2.0)); - return guder * i1924_equ_axis; + return guder * i1924_equ_axis; } /******************************************************************************* @@ -225,288 +229,303 @@ inverse_gudermannian_i1924(const double x) { *******************************************************************************/ static void -humminbird_rd_init(const char *fname) +humminbird_rd_init(const char* fname) { - fin = gbfopen_be(fname, "rb", MYNAME); - waypoints = avltree_init(0, MYNAME); + fin = gbfopen_be(fname, "rb", MYNAME); + waypoints = avltree_init(0, MYNAME); } -static void +static void humminbird_rd_deinit(void) { - avltree_done(waypoints); - gbfclose(fin); + avltree_done(waypoints); + gbfclose(fin); } static void -humminbird_read_wpt(gbfile* fin) { +humminbird_read_wpt(gbfile* fin) +{ + + humminbird_waypt_t w; + double guder; + int num_icons; + waypoint* wpt; + char buff[10]; - humminbird_waypt_t w; - double guder; - int num_icons; - waypoint *wpt; - char buff[10]; + if (! gbfread(&w, 1, sizeof(w), fin)) { + fatal(MYNAME ": Unexpected end of file!\n"); + } - if (! gbfread(&w, 1, sizeof(w), fin)) - fatal(MYNAME ": Unexpected end of file!\n"); + /* Fix endianness - these are now BE */ + w.num = be_read16(&w.num); + w.zero = be_read16(&w.zero); + w.depth = be_read16(&w.depth); + w.time = be_read32(&w.time); + w.north = be_read32(&w.north); + w.east = be_read32(&w.east); - /* Fix endianness - these are now BE */ - w.num = be_read16(&w.num); - w.zero = be_read16(&w.zero); - w.depth = be_read16(&w.depth); - w.time = be_read32(&w.time); - w.north = be_read32(&w.north); - w.east = be_read32(&w.east); + /* All right! Copy the data to the gpsbabel struct... */ - /* All right! Copy the data to the gpsbabel struct... */ + wpt = waypt_new(); - wpt = waypt_new(); + wpt->shortname = xstrndup(w.name, sizeof(w.name)); + wpt->creation_time = w.time; - wpt->shortname = xstrndup(w.name, sizeof(w.name)); - wpt->creation_time = w.time; + guder = gudermannian_i1924(w.north); + wpt->latitude = geocentric_to_geodetic_hwr(guder); + wpt->longitude = (double)w.east / EAST_SCALE * 180.0; - guder = gudermannian_i1924(w.north); - wpt->latitude = geocentric_to_geodetic_hwr(guder); - wpt->longitude = (double)w.east / EAST_SCALE * 180.0; + wpt->altitude = 0.0; /* It's from a fishfinder... */ - wpt->altitude = 0.0; /* It's from a fishfinder... */ + if (w.depth != 0) { + WAYPT_SET(wpt,depth,(double)w.depth / 100.0); + } - if (w.depth != 0) - WAYPT_SET(wpt,depth,(double)w.depth / 100.0); + num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]); + if (w.icon < num_icons) { + wpt->icon_descr = humminbird_icons[w.icon]; + } - num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]); - if (w.icon < num_icons) - wpt->icon_descr = humminbird_icons[w.icon]; + waypt_add(wpt); - waypt_add(wpt); - - /* register the point over his internal Humminbird "Number" */ - snprintf(buff, sizeof(buff), "%d", w.num); - avltree_insert(waypoints, buff, wpt); + /* register the point over his internal Humminbird "Number" */ + snprintf(buff, sizeof(buff), "%d", w.num); + avltree_insert(waypoints, buff, wpt); } static void -humminbird_read_route(gbfile* fin) { - - humminbird_rte_t hrte; - - if (! gbfread(&hrte, 1, sizeof(hrte), fin)) - fatal(MYNAME ": Unexpected end of file!\n"); - - hrte.time = be_read32(&hrte.time); - hrte.num = be_read16(&hrte.num); - - if (hrte.count > 0) { - int i; - route_head *rte = NULL; - - for (i = 0; i < hrte.count; i++) { - waypoint *wpt; - char buff[10]; - hrte.points[i] = be_read16(&hrte.points[i]); - - /* locate the point over his internal Humminbird "Number" */ - snprintf(buff, sizeof(buff), "%d", hrte.points[i]); - if (avltree_find(waypoints, buff, (void *) &wpt)) { - if (rte == NULL) { - rte = route_head_alloc(); - route_add_head(rte); - rte->rte_name = xstrndup(hrte.name, sizeof(hrte.name)); - /* rte->rte_num = hrte.num + 1; only internal number */ - } - route_add_wpt(rte, waypt_dupe(wpt)); - } - } - } +humminbird_read_route(gbfile* fin) +{ + + humminbird_rte_t hrte; + + if (! gbfread(&hrte, 1, sizeof(hrte), fin)) { + fatal(MYNAME ": Unexpected end of file!\n"); + } + + hrte.time = be_read32(&hrte.time); + hrte.num = be_read16(&hrte.num); + + if (hrte.count > 0) { + int i; + route_head* rte = NULL; + + for (i = 0; i < hrte.count; i++) { + waypoint* wpt; + char buff[10]; + hrte.points[i] = be_read16(&hrte.points[i]); + + /* locate the point over his internal Humminbird "Number" */ + snprintf(buff, sizeof(buff), "%d", hrte.points[i]); + if (avltree_find(waypoints, buff, (const void**) &wpt)) { + if (rte == NULL) { + rte = route_head_alloc(); + route_add_head(rte); + rte->rte_name = xstrndup(hrte.name, sizeof(hrte.name)); + /* rte->rte_num = hrte.num + 1; only internal number */ + } + route_add_wpt(rte, waypt_dupe(wpt)); + } + } + } } static void -humminbird_read_track(gbfile* fin) { - - humminbird_trk_header_t th; - humminbird_trk_point_t* points; - route_head* trk; - waypoint* first_wpt; - int i; - int max_points = 0; - gbint32 accum_east; - gbint32 accum_north; - double g_lat; - - if (! gbfread(&th, 1, sizeof(th), fin)) - fatal(MYNAME ": Unexpected end of file reading header!\n"); - - th.trk_num = be_read16(&th.trk_num); - th.num_points = be_read16(&th.num_points); - th.time = be_read32(&th.time); - - th.start_east = be_read32(&th.start_east); - th.start_north = be_read32(&th.start_north); - th.end_east = be_read32(&th.end_east); - th.end_north = be_read32(&th.end_north); - - th.sw_east = be_read32(&th.sw_east); - th.sw_north = be_read32(&th.sw_north); - th.ne_east = be_read32(&th.ne_east); - th.ne_north = be_read32(&th.ne_north); - - max_points = (131080 - sizeof(gbuint32) - sizeof(th)) / sizeof(humminbird_trk_point_t); - - if (th.num_points > max_points) - fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); - - /* num_points is actually one too big, because it includes the value in - the header. But we want the extra point at the end because the - freak-value filter below looks at points[i+1] */ - points = xcalloc(th.num_points, sizeof(humminbird_trk_point_t)); - if (! gbfread(points, sizeof(humminbird_trk_point_t), th.num_points-1, fin)) - fatal(MYNAME ": Unexpected end of file reading points!\n"); - - accum_east = th.start_east; - accum_north = th.start_north; - - trk = route_head_alloc(); - track_add_head(trk); - - trk->rte_name = xstrndup(th.name, sizeof(th.name)); - trk->rte_num = th.trk_num; - - /* We create one wpt for the info in the header */ - - first_wpt = waypt_new(); - g_lat = gudermannian_i1924(accum_north); - first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); - first_wpt->longitude = accum_east/EAST_SCALE * 180.0; - first_wpt->altitude = 0.0; - /* No depth info in the header. */ - track_add_wpt(trk, first_wpt); - - for(i=0 ; ilatitude = geocentric_to_geodetic_hwr(guder); - wpt->longitude = accum_east/EAST_SCALE * 180.0; - wpt->altitude = 0.0; - - if (points[i].depth != 0) - WAYPT_SET(wpt,depth,(double)points[i].depth / 100.0); - - if (i == th.num_points-2 && th.time != 0) { - /* Last point. Add the date from the header. */ - /* Unless it's zero. Sometimes happens, possibly if - the gps didn't have a lock when the track was - saved. */ - wpt->creation_time = th.time; - } - track_add_wpt(trk, wpt); - } - xfree(points); +humminbird_read_track(gbfile* fin) +{ + + humminbird_trk_header_t th; + humminbird_trk_point_t* points; + route_head* trk; + waypoint* first_wpt; + int i; + int max_points = 0; + gbint32 accum_east; + gbint32 accum_north; + double g_lat; + + if (! gbfread(&th, 1, sizeof(th), fin)) { + fatal(MYNAME ": Unexpected end of file reading header!\n"); + } + + th.trk_num = be_read16(&th.trk_num); + th.num_points = be_read16(&th.num_points); + th.time = be_read32(&th.time); + + th.start_east = be_read32(&th.start_east); + th.start_north = be_read32(&th.start_north); + th.end_east = be_read32(&th.end_east); + th.end_north = be_read32(&th.end_north); + + th.sw_east = be_read32(&th.sw_east); + th.sw_north = be_read32(&th.sw_north); + th.ne_east = be_read32(&th.ne_east); + th.ne_north = be_read32(&th.ne_north); + + max_points = (131080 - sizeof(gbuint32) - sizeof(th)) / sizeof(humminbird_trk_point_t); + + if (th.num_points > max_points) { + fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); + } + + /* num_points is actually one too big, because it includes the value in + the header. But we want the extra point at the end because the + freak-value filter below looks at points[i+1] */ + points = (humminbird_trk_point_t*) xcalloc(th.num_points, sizeof(humminbird_trk_point_t)); + if (! gbfread(points, sizeof(humminbird_trk_point_t), th.num_points-1, fin)) { + fatal(MYNAME ": Unexpected end of file reading points!\n"); + } + + accum_east = th.start_east; + accum_north = th.start_north; + + trk = route_head_alloc(); + track_add_head(trk); + + trk->rte_name = xstrndup(th.name, sizeof(th.name)); + trk->rte_num = th.trk_num; + + /* We create one wpt for the info in the header */ + + first_wpt = waypt_new(); + g_lat = gudermannian_i1924(accum_north); + first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); + first_wpt->longitude = accum_east/EAST_SCALE * 180.0; + first_wpt->altitude = 0.0; + /* No depth info in the header. */ + track_add_wpt(trk, first_wpt); + + for (i=0 ; ilatitude = geocentric_to_geodetic_hwr(guder); + wpt->longitude = accum_east/EAST_SCALE * 180.0; + wpt->altitude = 0.0; + + if (points[i].depth != 0) { + WAYPT_SET(wpt,depth,(double)points[i].depth / 100.0); + } + + if (i == th.num_points-2 && th.time != 0) { + /* Last point. Add the date from the header. */ + /* Unless it's zero. Sometimes happens, possibly if + the gps didn't have a lock when the track was + saved. */ + wpt->creation_time = th.time; + } + track_add_wpt(trk, wpt); + } + xfree(points); } static void -humminbird_read_track_old(gbfile* fin) { - - humminbird_trk_header_old_t th; - humminbird_trk_point_old_t* points; - route_head* trk; - waypoint* first_wpt; - int i; - int max_points = 0; - gbint32 accum_east; - gbint32 accum_north; - double g_lat; - const int file_len = 8048; - char namebuf[TRK_NAME_LEN]; - - - if (! gbfread(&th, 1, sizeof(th), fin)) - fatal(MYNAME ": Unexpected end of file reading header!\n"); - - th.trk_num = be_read16(&th.trk_num); - th.num_points = be_read16(&th.num_points); - th.time = be_read32(&th.time); - - th.start_east = be_read32(&th.start_east); - th.start_north = be_read32(&th.start_north); - th.end_east = be_read32(&th.end_east); - th.end_north = be_read32(&th.end_north); - - // These files are always 8048 bytes long. Note that that's the value - // of the second 16-bit word in the signature. - max_points = (file_len - (sizeof(th) + sizeof (gbuint32) + TRK_NAME_LEN)) / sizeof(humminbird_trk_point_old_t); - - if (th.num_points > max_points) - fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); - - /* num_points is actually one too big, because it includes the value in - the header. But we want the extra point at the end because the - freak-value filter below looks at points[i+1] */ - points = xcalloc(th.num_points, sizeof(humminbird_trk_point_old_t)); - if (! gbfread(points, sizeof(humminbird_trk_point_old_t), th.num_points-1, fin)) - fatal(MYNAME ": Unexpected end of file reading points!\n"); - - accum_east = th.start_east; - accum_north = th.start_north; - - trk = route_head_alloc(); - track_add_head(trk); - - /* The name is not in the header, but at the end of the file. - (The last 20 bytes.) */ - - gbfseek(fin, file_len-TRK_NAME_LEN, SEEK_SET); - gbfread(&namebuf, 1, TRK_NAME_LEN, fin); - trk->rte_name = xstrndup(namebuf, sizeof(namebuf)); - - trk->rte_num = th.trk_num; - - /* We create one wpt for the info in the header */ - - first_wpt = waypt_new(); - g_lat = gudermannian_i1924(accum_north); - first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); - first_wpt->longitude = accum_east/EAST_SCALE * 180.0; - first_wpt->altitude = 0.0; - track_add_wpt(trk, first_wpt); - - for(i=0 ; i max_points) { + fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); + } + + /* num_points is actually one too big, because it includes the value in + the header. But we want the extra point at the end because the + freak-value filter below looks at points[i+1] */ + points = (humminbird_trk_point_old_t*)xcalloc(th.num_points, sizeof(humminbird_trk_point_old_t)); + if (! gbfread(points, sizeof(humminbird_trk_point_old_t), th.num_points-1, fin)) { + fatal(MYNAME ": Unexpected end of file reading points!\n"); + } + + accum_east = th.start_east; + accum_north = th.start_north; + + trk = route_head_alloc(); + track_add_head(trk); + + /* The name is not in the header, but at the end of the file. + (The last 20 bytes.) */ + + gbfseek(fin, file_len-TRK_NAME_LEN, SEEK_SET); + gbfread(&namebuf, 1, TRK_NAME_LEN, fin); + trk->rte_name = xstrndup(namebuf, sizeof(namebuf)); + + trk->rte_num = th.trk_num; + + /* We create one wpt for the info in the header */ + + first_wpt = waypt_new(); + g_lat = gudermannian_i1924(accum_north); + first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); + first_wpt->longitude = accum_east/EAST_SCALE * 180.0; + first_wpt->altitude = 0.0; + track_add_wpt(trk, first_wpt); + + for (i=0 ; ilatitude = geocentric_to_geodetic_hwr(guder); - wpt->longitude = accum_east/EAST_SCALE * 180.0; - wpt->altitude = 0.0; - - if (i == th.num_points-2 && th.time != 0) { - /* Last point. Add the date from the header. */ - /* Unless it's zero. Sometimes happens, possibly if - the gps didn't have a lock when the track was - saved. */ - wpt->creation_time = th.time; - } - track_add_wpt(trk, wpt); - } - xfree(points); + accum_east += points[i].deltaeast; + accum_north += points[i].deltanorth; + + guder = gudermannian_i1924(accum_north); + wpt->latitude = geocentric_to_geodetic_hwr(guder); + wpt->longitude = accum_east/EAST_SCALE * 180.0; + wpt->altitude = 0.0; + + if (i == th.num_points-2 && th.time != 0) { + /* Last point. Add the date from the header. */ + /* Unless it's zero. Sometimes happens, possibly if + the gps didn't have a lock when the track was + saved. */ + wpt->creation_time = th.time; + } + track_add_wpt(trk, wpt); + } + xfree(points); } static void humminbird_read(void) { - while(! gbfeof(fin)) { - gbuint32 signature; - - signature = gbfgetuint32(fin); - - switch(signature) { - case WPT_MAGIC: - humminbird_read_wpt(fin); - break; - case RTE_MAGIC: - humminbird_read_route(fin); - break; - case TRK_MAGIC: - humminbird_read_track(fin); - return; /* Don't continue. The rest of the file is all zeores */ - case TRK_MAGIC2: - humminbird_read_track_old(fin); - return; /* Don't continue. The rest of the file is all zeores */ - default: - fatal(MYNAME ": Invalid record header \"0x%08X\" (no or unknown humminbird file)!\n", signature); - } - } + while (! gbfeof(fin)) { + gbuint32 signature; + + signature = gbfgetuint32(fin); + + switch (signature) { + case WPT_MAGIC: + humminbird_read_wpt(fin); + break; + case RTE_MAGIC: + humminbird_read_route(fin); + break; + case TRK_MAGIC: + humminbird_read_track(fin); + return; /* Don't continue. The rest of the file is all zeores */ + case TRK_MAGIC2: + humminbird_read_track_old(fin); + return; /* Don't continue. The rest of the file is all zeores */ + default: + fatal(MYNAME ": Invalid record header \"0x%08X\" (no or unknown humminbird file)!\n", signature); + } + } } /************************************************************************************************/ static void -humminbird_wr_init(const char *fname) +humminbird_wr_init(const char* fname) { - fout = gbfopen_be(fname, "wb", MYNAME); - - wptname_sh = mkshort_new_handle(); - - setshort_length(wptname_sh, WPT_NAME_LEN - 1); - setshort_badchars(wptname_sh, BAD_CHARS); - setshort_mustupper(wptname_sh, 0); - setshort_mustuniq(wptname_sh, 0); - setshort_whitespace_ok(wptname_sh, 1); - setshort_repeating_whitespace_ok(wptname_sh, 1); - setshort_defname(wptname_sh, "WPT"); - - rtename_sh = mkshort_new_handle(); - setshort_length(rtename_sh, RTE_NAME_LEN - 1); - setshort_badchars(rtename_sh, BAD_CHARS); - setshort_mustupper(rtename_sh, 0); - setshort_mustuniq(rtename_sh, 0); - setshort_whitespace_ok(rtename_sh, 1); - setshort_repeating_whitespace_ok(rtename_sh, 1); - setshort_defname(rtename_sh, "Route"); - - trkname_sh = mkshort_new_handle(); - setshort_length(trkname_sh, RTE_NAME_LEN - 1); - setshort_badchars(trkname_sh, BAD_CHARS); - setshort_mustupper(trkname_sh, 0); - setshort_mustuniq(trkname_sh, 0); - setshort_whitespace_ok(trkname_sh, 1); - setshort_repeating_whitespace_ok(trkname_sh, 1); - setshort_defname(trkname_sh, "Track"); - - waypoints = avltree_init(0, MYNAME); - - waypoint_num = 0; - rte_num = 0; + fout = gbfopen_be(fname, "wb", MYNAME); + + wptname_sh = mkshort_new_handle(); + + setshort_length(wptname_sh, WPT_NAME_LEN - 1); + setshort_badchars(wptname_sh, BAD_CHARS); + setshort_mustupper(wptname_sh, 0); + setshort_mustuniq(wptname_sh, 0); + setshort_whitespace_ok(wptname_sh, 1); + setshort_repeating_whitespace_ok(wptname_sh, 1); + setshort_defname(wptname_sh, "WPT"); + + rtename_sh = mkshort_new_handle(); + setshort_length(rtename_sh, RTE_NAME_LEN - 1); + setshort_badchars(rtename_sh, BAD_CHARS); + setshort_mustupper(rtename_sh, 0); + setshort_mustuniq(rtename_sh, 0); + setshort_whitespace_ok(rtename_sh, 1); + setshort_repeating_whitespace_ok(rtename_sh, 1); + setshort_defname(rtename_sh, "Route"); + + trkname_sh = mkshort_new_handle(); + setshort_length(trkname_sh, RTE_NAME_LEN - 1); + setshort_badchars(trkname_sh, BAD_CHARS); + setshort_mustupper(trkname_sh, 0); + setshort_mustuniq(trkname_sh, 0); + setshort_whitespace_ok(trkname_sh, 1); + setshort_repeating_whitespace_ok(trkname_sh, 1); + setshort_defname(trkname_sh, "Track"); + + waypoints = avltree_init(0, MYNAME); + + waypoint_num = 0; + rte_num = 0; } static void humminbird_wr_deinit(void) { - avltree_done(waypoints); - mkshort_del_handle(&wptname_sh); - mkshort_del_handle(&rtename_sh); - mkshort_del_handle(&trkname_sh); - gbfclose(fout); + avltree_done(waypoints); + mkshort_del_handle(&wptname_sh); + mkshort_del_handle(&rtename_sh); + mkshort_del_handle(&trkname_sh); + gbfclose(fout); } static void -humminbird_write_waypoint(const waypoint *wpt) { - humminbird_waypt_t hum; - double lat, north, east; - int i; - int num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]); - char *name; - - be_write16(&hum.num, waypoint_num++); - hum.zero = 0; - hum.status = 1; - hum.icon = 255; - - // Icon.... - if (wpt->icon_descr) { - for (i = 0; i < num_icons; i++) { - if (!case_ignore_strcmp(wpt->icon_descr, humminbird_icons[i])) { - hum.icon = i; - break; - } - } - if (hum.icon == 255) { /* no success, no try to find the item in a more comlex name */ - hum.icon = 0; /* i.e. "Diamond" as part of "Diamond, Green" or "Green Diamond" */ - for (i = 0; i < num_icons; i++) { - char *match; - int j; - xasprintf(&match, "*%s*", humminbird_icons[i]); - j = case_ignore_str_match(wpt->icon_descr, match); - xfree(match); - if (j != 0) { - hum.icon = i; - break; - } - } - } - } - - hum.depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0); - be_write16(&hum.depth, hum.depth); - - be_write32(&hum.time, wpt->creation_time); - - east = wpt->longitude / 180.0 * EAST_SCALE; - be_write32(&hum.east, si_round((east))); - - lat = geodetic_to_geocentric_hwr(wpt->latitude); - north = inverse_gudermannian_i1924(lat); - be_write32(&hum.north, si_round(north)); - - name = (global_opts.synthesize_shortnames) - ? mkshort_from_wpt(wptname_sh, wpt) - : mkshort(wptname_sh, wpt->shortname); - memset(&hum.name, 0, sizeof(hum.name)); - memcpy(&hum.name, name, strlen(name)); - xfree(name); - - gbfputuint32(WPT_MAGIC, fout); - gbfwrite(&hum, sizeof(hum), 1, fout); +humminbird_write_waypoint(const waypoint* wpt) +{ + humminbird_waypt_t hum; + double lat, north, east; + int i; + int num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]); + char* name; + + be_write16(&hum.num, waypoint_num++); + hum.zero = 0; + hum.status = 1; + hum.icon = 255; + + // Icon.... + if (wpt->icon_descr) { + for (i = 0; i < num_icons; i++) { + if (!case_ignore_strcmp(wpt->icon_descr, humminbird_icons[i])) { + hum.icon = i; + break; + } + } + if (hum.icon == 255) { /* no success, no try to find the item in a more comlex name */ + hum.icon = 0; /* i.e. "Diamond" as part of "Diamond, Green" or "Green Diamond" */ + for (i = 0; i < num_icons; i++) { + char* match; + int j; + xasprintf(&match, "*%s*", humminbird_icons[i]); + j = case_ignore_str_match(wpt->icon_descr, match); + xfree(match); + if (j != 0) { + hum.icon = i; + break; + } + } + } + } + + hum.depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0); + be_write16(&hum.depth, hum.depth); + + be_write32(&hum.time, wpt->creation_time); + + east = wpt->longitude / 180.0 * EAST_SCALE; + be_write32(&hum.east, si_round((east))); + + lat = geodetic_to_geocentric_hwr(wpt->latitude); + north = inverse_gudermannian_i1924(lat); + be_write32(&hum.north, si_round(north)); + + name = (global_opts.synthesize_shortnames) + ? mkshort_from_wpt(wptname_sh, wpt) + : mkshort(wptname_sh, wpt->shortname); + memset(&hum.name, 0, sizeof(hum.name)); + memcpy(&hum.name, name, strlen(name)); + xfree(name); + + gbfputuint32(WPT_MAGIC, fout); + gbfwrite(&hum, sizeof(hum), 1, fout); } static humminbird_trk_header_t* trk_head; @@ -689,230 +709,251 @@ static gbuint32 last_time; static void -humminbird_track_head(const route_head *trk) { - int max_points = (131080 - sizeof(gbuint32)- sizeof(humminbird_trk_header_t)) / sizeof(humminbird_trk_point_t); - - trk_head = NULL; - last_time = 0; - if (trk->rte_waypt_ct > 0) { - char *name; - trk_head = xcalloc(1, sizeof(humminbird_trk_header_t)); - trk_points = xcalloc (max_points, sizeof(humminbird_trk_point_t)); - - name = mkshort(trkname_sh, trk->rte_name); - strncpy(trk_head->name, name, sizeof(trk_head->name)); - xfree(name); - be_write16(&trk_head->trk_num, trk->rte_num); - } +humminbird_track_head(const route_head* trk) +{ + int max_points = (131080 - sizeof(gbuint32)- sizeof(humminbird_trk_header_t)) / sizeof(humminbird_trk_point_t); + + trk_head = NULL; + last_time = 0; + if (trk->rte_waypt_ct > 0) { + char* name; + trk_head = (humminbird_trk_header_t*) xcalloc(1, sizeof(humminbird_trk_header_t)); + trk_points = (humminbird_trk_point_t*) xcalloc(max_points, sizeof(humminbird_trk_point_t)); + + name = mkshort(trkname_sh, trk->rte_name); + strncpy(trk_head->name, name, sizeof(trk_head->name)); + xfree(name); + be_write16(&trk_head->trk_num, trk->rte_num); + } } static void -humminbird_track_tail(const route_head *rte) { - int max_points = (131080 - sizeof(gbuint32)- sizeof(humminbird_trk_header_t)) / sizeof(humminbird_trk_point_t); +humminbird_track_tail(const route_head* rte) +{ + int max_points = (131080 - sizeof(gbuint32)- sizeof(humminbird_trk_header_t)) / sizeof(humminbird_trk_point_t); + + if (trk_head == NULL) { + return; + } - if (trk_head == NULL) - return; + be_write32(&trk_head->end_east, last_east); + be_write32(&trk_head->end_north, last_north); + be_write32(&trk_head->time, last_time); - be_write32(&trk_head->end_east, last_east); - be_write32(&trk_head->end_north, last_north); - be_write32(&trk_head->time, last_time); + /* Fix some endianness */ - /* Fix some endianness */ + be_write32(&trk_head->sw_east, trk_head->sw_east); + be_write32(&trk_head->ne_east, trk_head->ne_east); + be_write32(&trk_head->sw_north, trk_head->sw_north); + be_write32(&trk_head->ne_north, trk_head->ne_north); - be_write32(&trk_head->sw_east, trk_head->sw_east); - be_write32(&trk_head->ne_east, trk_head->ne_east); - be_write32(&trk_head->sw_north, trk_head->sw_north); - be_write32(&trk_head->ne_north, trk_head->ne_north); - - be_write16(&trk_head->num_points, trk_head->num_points); + be_write16(&trk_head->num_points, trk_head->num_points); - /* Actually write it out */ + /* Actually write it out */ - - gbfputuint32(TRK_MAGIC, fout); - gbfwrite(trk_head, 1, sizeof(humminbird_trk_header_t), fout); - gbfwrite(trk_points, max_points, sizeof(humminbird_trk_point_t), fout); - gbfputuint16(0, fout); /* Odd but true. The format doesn't fit an int nr of entries. */ - xfree(trk_head); - xfree(trk_points); + gbfputuint32(TRK_MAGIC, fout); + gbfwrite(trk_head, 1, sizeof(humminbird_trk_header_t), fout); + gbfwrite(trk_points, max_points, sizeof(humminbird_trk_point_t), fout); + gbfputuint16(0, fout); /* Odd but true. The format doesn't fit an int nr of entries. */ - trk_head = NULL; - trk_points = NULL; + xfree(trk_head); + xfree(trk_points); + + trk_head = NULL; + trk_points = NULL; } static void -humminbird_track_cb(const waypoint *wpt) { - gbint32 north, east; - double lat; - int i; - - if (trk_head == NULL) - return; - - i = trk_head->num_points; - - east = si_round(wpt->longitude / 180.0 * EAST_SCALE); - lat = geodetic_to_geocentric_hwr(wpt->latitude); - north = si_round(inverse_gudermannian_i1924(lat)); - - if (wpt->creation_time != 0) - last_time = wpt->creation_time; - - if (i == 0) { - /* It's the first point. That info goes in the header. */ - - be_write32(&trk_head->start_east, east); - be_write32(&trk_head->start_north, north); - - /* Bounding box. Easy for one point. */ - /* These are not BE yet, fixed in the end. */ - trk_head->sw_east = east; - trk_head->ne_east = east; - trk_head->sw_north = north; - trk_head->ne_north = north; - - /* No depth info in the header. */ - } else { - /* These points are 16-bit differential. */ - int j = i-1; - trk_points[j].deltaeast = east - last_east; - trk_points[j].deltanorth = north - last_north; - trk_points[j].depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0); - - /* BE-ify */ - be_write16(&trk_points[j].deltaeast, trk_points[j].deltaeast); - be_write16(&trk_points[j].deltanorth, trk_points[j].deltanorth); - be_write16(&trk_points[j].depth, trk_points[j].depth); - - /* Update bounding box in header if neccessary */ - if (east > trk_head->ne_east) trk_head->ne_east = east; - if (east < trk_head->sw_east) trk_head->sw_east = east; - if (north > trk_head->ne_north) trk_head->ne_north = north; - if (north < trk_head->sw_north) trk_head->sw_north = north; - } - - last_east = east; - last_north = north; - - trk_head->num_points++; +humminbird_track_cb(const waypoint* wpt) +{ + gbint32 north, east; + double lat; + int i; + + if (trk_head == NULL) { + return; + } + + i = trk_head->num_points; + + east = si_round(wpt->longitude / 180.0 * EAST_SCALE); + lat = geodetic_to_geocentric_hwr(wpt->latitude); + north = si_round(inverse_gudermannian_i1924(lat)); + + if (wpt->creation_time != 0) { + last_time = wpt->creation_time; + } + + if (i == 0) { + /* It's the first point. That info goes in the header. */ + + be_write32(&trk_head->start_east, east); + be_write32(&trk_head->start_north, north); + + /* Bounding box. Easy for one point. */ + /* These are not BE yet, fixed in the end. */ + trk_head->sw_east = east; + trk_head->ne_east = east; + trk_head->sw_north = north; + trk_head->ne_north = north; + + /* No depth info in the header. */ + } else { + /* These points are 16-bit differential. */ + int j = i-1; + trk_points[j].deltaeast = east - last_east; + trk_points[j].deltanorth = north - last_north; + trk_points[j].depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0); + + /* BE-ify */ + be_write16(&trk_points[j].deltaeast, trk_points[j].deltaeast); + be_write16(&trk_points[j].deltanorth, trk_points[j].deltanorth); + be_write16(&trk_points[j].depth, trk_points[j].depth); + + /* Update bounding box in header if neccessary */ + if (east > trk_head->ne_east) { + trk_head->ne_east = east; + } + if (east < trk_head->sw_east) { + trk_head->sw_east = east; + } + if (north > trk_head->ne_north) { + trk_head->ne_north = north; + } + if (north < trk_head->sw_north) { + trk_head->sw_north = north; + } + } + + last_east = east; + last_north = north; + + trk_head->num_points++; } static void -humminbird_track_write(void) { +humminbird_track_write(void) +{ - track_disp_all(humminbird_track_head, humminbird_track_tail, humminbird_track_cb); + track_disp_all(humminbird_track_head, humminbird_track_tail, humminbird_track_cb); } static void -humminbird_rte_head(const route_head *rte) +humminbird_rte_head(const route_head* rte) { - humrte = NULL; - if (rte->rte_waypt_ct > 0) - humrte = xcalloc(1, sizeof(*humrte)); + humrte = NULL; + if (rte->rte_waypt_ct > 0) { + humrte = (humminbird_rte_t*) xcalloc(1, sizeof(*humrte)); + } } static void -humminbird_rte_tail(const route_head *rte) +humminbird_rte_tail(const route_head* rte) { - if (humrte == NULL) return; - - if (humrte->count > 0) { - int i; - char *name; - - humrte->num = rte_num++; - humrte->time = gpsbabel_time; - for (i = 0; i < humrte->count; i++) - be_write16(&humrte->points[i], humrte->points[i]); - - be_write16(&humrte->num, humrte->num); - be_write32(&humrte->time, humrte->time); - - name = mkshort(rtename_sh, rte->rte_name); - strncpy(humrte->name, name, sizeof(humrte->name)); - xfree(name); - - gbfputuint32(RTE_MAGIC, fout); - gbfwrite(humrte, sizeof(*humrte), 1, fout); - } - - xfree(humrte); - humrte = NULL; + if (humrte == NULL) { + return; + } + + if (humrte->count > 0) { + int i; + char* name; + + humrte->num = rte_num++; + humrte->time = gpsbabel_time; + for (i = 0; i < humrte->count; i++) { + be_write16(&humrte->points[i], humrte->points[i]); + } + + be_write16(&humrte->num, humrte->num); + be_write32(&humrte->time, humrte->time); + + name = mkshort(rtename_sh, rte->rte_name); + strncpy(humrte->name, name, sizeof(humrte->name)); + xfree(name); + + gbfputuint32(RTE_MAGIC, fout); + gbfwrite(humrte, sizeof(*humrte), 1, fout); + } + + xfree(humrte); + humrte = NULL; } static void -humminbird_write_rtept(const waypoint *wpt) +humminbird_write_rtept(const waypoint* wpt) { - int i; - - if (humrte == NULL) return; - i = gb_ptr2int(wpt->extra_data); - if (i <= 0) return; - - if (humrte->count < MAX_RTE_POINTS) { - humrte->points[humrte->count] = i - 1; - humrte->count++; - } - else { - warning(MYNAME ": Sorry, routes are limited to %d points!\n", MAX_RTE_POINTS); - fatal(MYNAME ": You can use our simplify filter to reduce the number of route points.\n"); - } + int i; + + if (humrte == NULL) { + return; + } + i = gb_ptr2int(wpt->extra_data); + if (i <= 0) { + return; + } + + if (humrte->count < MAX_RTE_POINTS) { + humrte->points[humrte->count] = i - 1; + humrte->count++; + } else { + warning(MYNAME ": Sorry, routes are limited to %d points!\n", MAX_RTE_POINTS); + fatal(MYNAME ": You can use our simplify filter to reduce the number of route points.\n"); + } } static void -humminbird_write_waypoint_wrapper(const waypoint *wpt) +humminbird_write_waypoint_wrapper(const waypoint* wpt) { - char *key; - waypoint *tmpwpt; + char* key; + waypoint* tmpwpt; - xasprintf(&key, "%s\01%.9f\01%.9f", wpt->shortname, wpt->latitude, wpt->longitude); + xasprintf(&key, "%s\01%.9f\01%.9f", wpt->shortname, wpt->latitude, wpt->longitude); - if (! avltree_find(waypoints, key, (void *)&tmpwpt)) { - tmpwpt = (waypoint *)wpt; + if (! avltree_find(waypoints, key, (const void**)&tmpwpt)) { + tmpwpt = (waypoint*)wpt; - avltree_insert(waypoints, key, wpt); + avltree_insert(waypoints, key, wpt); - tmpwpt->extra_data = gb_int2ptr(waypoint_num + 1); /* NOT NULL */ - humminbird_write_waypoint(wpt); - } - else { - void *p = tmpwpt->extra_data; - tmpwpt = (waypoint *)wpt; - tmpwpt->extra_data = p; - } + tmpwpt->extra_data = gb_int2ptr(waypoint_num + 1); /* NOT NULL */ + humminbird_write_waypoint(wpt); + } else { + void* p = tmpwpt->extra_data; + tmpwpt = (waypoint*)wpt; + tmpwpt->extra_data = p; + } - xfree(key); + xfree(key); } static void humminbird_write(void) { - waypt_disp_all(humminbird_write_waypoint_wrapper); - route_disp_all(NULL, NULL, humminbird_write_waypoint_wrapper); - route_disp_all(humminbird_rte_head, humminbird_rte_tail, humminbird_write_rtept); + waypt_disp_all(humminbird_write_waypoint_wrapper); + route_disp_all(NULL, NULL, humminbird_write_waypoint_wrapper); + route_disp_all(humminbird_rte_head, humminbird_rte_tail, humminbird_write_rtept); } /**************************************************************************/ ff_vecs_t humminbird_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_read | ff_cap_write /* routes */ - }, - humminbird_rd_init, - humminbird_wr_init, - humminbird_rd_deinit, - humminbird_wr_deinit, - humminbird_read, - humminbird_write, - NULL, // humminbird_exit, - humminbird_args, - CET_CHARSET_ASCII, 1 /* ascii is the expected character set */ - /* currently fixed !!! */ + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + ff_cap_read /* tracks */, + (ff_cap)(ff_cap_read | ff_cap_write) /* routes */ + }, + humminbird_rd_init, + humminbird_wr_init, + humminbird_rd_deinit, + humminbird_wr_deinit, + humminbird_read, + humminbird_write, + NULL, // humminbird_exit, + humminbird_args, + CET_CHARSET_ASCII, 1 /* ascii is the expected character set */ + /* currently fixed !!! */ }; /**************************************************************************/ @@ -920,22 +961,22 @@ ff_vecs_t humminbird_vecs = { /**************************************************************************/ ff_vecs_t humminbird_ht_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_read /* routes */ - }, - humminbird_rd_init, - humminbird_wr_init, - humminbird_rd_deinit, - humminbird_wr_deinit, - humminbird_read, - humminbird_track_write, - NULL, // humminbird_exit, - humminbird_args, - CET_CHARSET_ASCII, 1 /* ascii is the expected character set */ - /* currently fixed !!! */ + ff_type_file, + { + ff_cap_read /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_read /* routes */ + }, + humminbird_rd_init, + humminbird_wr_init, + humminbird_rd_deinit, + humminbird_wr_deinit, + humminbird_read, + humminbird_track_write, + NULL, // humminbird_exit, + humminbird_args, + CET_CHARSET_ASCII, 1 /* ascii is the expected character set */ + /* currently fixed !!! */ }; /**************************************************************************/ diff --git a/gpsbabel/igc.c b/gpsbabel/igc.c index 3fa95d518..2bc7dde78 100644 --- a/gpsbabel/igc.c +++ b/gpsbabel/igc.c @@ -1,35 +1,35 @@ /* * FAI/IGC data format translation. - * + * * Refer to Appendix 1 of * http://www.fai.org:81/gliding/gnss/tech_spec_gnss.asp for the * specification of the IGC data format. This translation code was * written when the latest ammendment list for the specification was AL6. - * + * * Copyright (C) 2004 Chris Jones - * - * This program is free software; you can redistribute it and/or modify it + * + * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111 USA + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111 USA */ #include "defs.h" #include -static gbfile *file_in, *file_out; +static gbfile* file_in, *file_out; static char manufacturer[4]; -static const route_head *head; -static char *timeadj = NULL; +static const route_head* head; +static char* timeadj = NULL; static int lineno; #define MYNAME "IGC" @@ -46,23 +46,23 @@ static int lineno; * These appear as the first char in each record. */ typedef enum { - rec_manuf_id = 'A', // FR manufacturer and identification - rec_fix = 'B', // Fix - rec_task = 'C', // Task/declaration - rec_diff_gps = 'D', // Differential GPS - rec_event = 'E', // Event - rec_constel = 'F', // Constellation - rec_security = 'G', // Security - rec_header = 'H', // File header - rec_fix_defn = 'I', // List of extension data included at end of each fix (B) record - rec_extn_defn = 'J', // List of data included in each extension (K) record - rec_extn_data = 'K', // Extension data - rec_log_book = 'L', // Logbook/comments - - // M..Z are spare - - rec_none = 0, // No record - rec_bad = 1, // Bad record + rec_manuf_id = 'A', // FR manufacturer and identification + rec_fix = 'B', // Fix + rec_task = 'C', // Task/declaration + rec_diff_gps = 'D', // Differential GPS + rec_event = 'E', // Event + rec_constel = 'F', // Constellation + rec_security = 'G', // Security + rec_header = 'H', // File header + rec_fix_defn = 'I', // List of extension data included at end of each fix (B) record + rec_extn_defn = 'J', // List of data included in each extension (K) record + rec_extn_data = 'K', // Extension data + rec_log_book = 'L', // Logbook/comments + + // M..Z are spare + + rec_none = 0, // No record + rec_bad = 1, // Bad record } igc_rec_type_t; /* @@ -76,11 +76,11 @@ typedef enum { */ static unsigned char coords_match(double lat1, double lon1, double lat2, double lon2) { - return (fabs(lat1 - lat2) < 0.0001 && fabs(lon1 - lon2) < 0.0001) ? 1 : 0; + return (fabs(lat1 - lat2) < 0.0001 && fabs(lon1 - lon2) < 0.0001) ? 1 : 0; } /************************************************************************************************* - * Input file processing + * Input file processing */ /* @@ -88,394 +88,407 @@ static unsigned char coords_match(double lat1, double lon1, double lat2, double * @param rec Caller allocated storage for the record. At least MAXRECLEN chars must be allocated. * @return the record type. rec_none on EOF, rec_bad on fgets() or parse error. */ -static igc_rec_type_t get_record(char **rec) +static igc_rec_type_t get_record(char** rec) { - size_t len; - char *c; + size_t len; + char* c; retry: - *rec = c = gbfgetstr(file_in); - if ((lineno++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - if (c == NULL) return rec_none; - - len = strlen(c); - - /* Trackwiev writes (bogus) blank links between each record */ - if (len == 0) goto retry; - - if (len < 3 || c[0] < 'A' || c[0] > 'Z') { - warning(MYNAME " bad input record: '%s'\n", c); - return rec_bad; - } - return (igc_rec_type_t) c[0]; + *rec = c = gbfgetstr(file_in); + if ((lineno++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + if (c == NULL) { + return rec_none; + } + + len = strlen(c); + + /* Trackwiev writes (bogus) blank links between each record */ + if (len == 0) { + goto retry; + } + + if (len < 3 || c[0] < 'A' || c[0] > 'Z') { + warning(MYNAME " bad input record: '%s'\n", c); + return rec_bad; + } + return (igc_rec_type_t) c[0]; } -static void rd_init(const char *fname) +static void rd_init(const char* fname) { - char *ibuf; - - file_in = gbfopen(fname, "r", MYNAME); - lineno = 0; - // File must begin with a manufacturer/ID record - if (get_record(&ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) { - fatal(MYNAME ": %s is not an IGC file\n", fname); - } + char* ibuf; + + file_in = gbfopen(fname, "r", MYNAME); + lineno = 0; + // File must begin with a manufacturer/ID record + if (get_record(&ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) { + fatal(MYNAME ": %s is not an IGC file\n", fname); + } } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); +} + +typedef enum { id, takeoff, start, turnpoint, finish, landing } state_t; +#if __cplusplus +inline state_t operator++(state_t& rs, int) +{ + return rs = (state_t)((int)rs + 1); } +#endif /** * Handle pre- or post-flight task declarations. * A route is created for each set of waypoints in a task declaration. * @param rec A single task record */ -static void igc_task_rec(const char *rec) +static void igc_task_rec(const char* rec) { - static char flight_date[7]; - static unsigned int num_tp, tp_ct; - static route_head *rte_head; - static time_t creation; - - char task_num[5]; - char task_desc[MAXRECLEN]; - waypoint *wpt; - unsigned int lat_deg, lat_min, lat_frac; - unsigned int lon_deg, lon_min, lon_frac; - char lat_hemi[2], lon_hemi[2]; - char short_name[8]; - char tmp_str[MAXRECLEN]; - struct tm tm; - - static enum { id, takeoff, start, turnpoint, finish, landing } state = id; - - // First task record identifies the task to follow - if (id == state) { - task_desc[0] = '\0'; - if (sscanf(rec, "C%2u%2u%2u%2u%2u%2u%6[0-9]%4c%2u%[^\r]\r\n", - &tm.tm_mday, &tm.tm_mon, &tm.tm_year, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec, - flight_date, task_num, &num_tp, task_desc) < 9) { - fatal(MYNAME ": task id (C) record parse error\n'%s'", rec); - } - task_num[4] = '\0'; - tm.tm_mon -= 1; - if (tm.tm_year < 70) { - tm.tm_year += 100; - } - tm.tm_isdst = 0; - creation = mkgmtime(&tm); - - // Create a route to store the task data in. - rte_head = route_head_alloc(); - rte_head->rte_name = xstrdup(task_num); - sprintf(tmp_str, DATEMAGIC "%s: %s", flight_date, task_desc); - rte_head->rte_desc = xstrdup(tmp_str); - route_add_head(rte_head); - state++; - return; - } - // Get the waypoint - tmp_str[0] = '\0'; - if (sscanf(rec, "C%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%[^\r]\r\n", - &lat_deg, &lat_min, &lat_frac, lat_hemi, - &lon_deg, &lon_min, &lon_frac, lon_hemi, tmp_str) < 8) { - fatal(MYNAME ": task waypoint (C) record parse error\n%s", rec); - } - - wpt = waypt_new(); - wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * - (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); - - wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * - (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); - - wpt->creation_time = creation; - wpt->description = xstrdup(tmp_str); - - // Name the waypoint according to the order of the task record - switch (state) { - case takeoff: - snprintf(short_name, 8, "TAKEOFF"); - state++; - break; - - case start: - snprintf(short_name, 8, "START"); - tp_ct = 0; - state++; - break; - - case turnpoint: - if (++tp_ct == num_tp) { - state++; - } - snprintf(short_name, 8, "TURN%02u", tp_ct); - break; - - case finish: - snprintf(short_name, 8, "FINISH"); - state++; - break; - - case landing: - snprintf(short_name, 8, "LANDING"); - state = id; - break; - - default: - fatal(MYNAME ": task id (C) record internal error\n%s", rec); - break; - } - - // Zero lat and lon indicates an unknown waypoint - if (coords_match(wpt->latitude, wpt->longitude, 0.0, 0.0)) { - waypt_free(wpt); - return; - } - wpt->shortname = xstrdup(short_name); - route_add_wpt(rte_head, wpt); + static char flight_date[7]; + static unsigned int num_tp, tp_ct; + static route_head* rte_head; + static time_t creation; + + char task_num[5]; + char task_desc[MAXRECLEN]; + waypoint* wpt; + unsigned int lat_deg, lat_min, lat_frac; + unsigned int lon_deg, lon_min, lon_frac; + char lat_hemi[2], lon_hemi[2]; + char short_name[8]; + char tmp_str[MAXRECLEN]; + struct tm tm; + static state_t state = id; + + // First task record identifies the task to follow + if (id == state) { + task_desc[0] = '\0'; + if (sscanf(rec, "C%2u%2u%2u%2u%2u%2u%6[0-9]%4c%2u%[^\r]\r\n", + &tm.tm_mday, &tm.tm_mon, &tm.tm_year, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec, + flight_date, task_num, &num_tp, task_desc) < 9) { + fatal(MYNAME ": task id (C) record parse error\n'%s'", rec); + } + task_num[4] = '\0'; + tm.tm_mon -= 1; + if (tm.tm_year < 70) { + tm.tm_year += 100; + } + tm.tm_isdst = 0; + creation = mkgmtime(&tm); + + // Create a route to store the task data in. + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(task_num); + sprintf(tmp_str, DATEMAGIC "%s: %s", flight_date, task_desc); + rte_head->rte_desc = xstrdup(tmp_str); + route_add_head(rte_head); + state++; + return; + } + // Get the waypoint + tmp_str[0] = '\0'; + if (sscanf(rec, "C%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%[^\r]\r\n", + &lat_deg, &lat_min, &lat_frac, lat_hemi, + &lon_deg, &lon_min, &lon_frac, lon_hemi, tmp_str) < 8) { + fatal(MYNAME ": task waypoint (C) record parse error\n%s", rec); + } + + wpt = waypt_new(); + wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * + (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); + + wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * + (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); + + wpt->creation_time = creation; + wpt->description = xstrdup(tmp_str); + + // Name the waypoint according to the order of the task record + switch (state) { + case takeoff: + snprintf(short_name, 8, "TAKEOFF"); + state++; + break; + + case start: + snprintf(short_name, 8, "START"); + tp_ct = 0; + state++; + break; + + case turnpoint: + if (++tp_ct == num_tp) { + state++; + } + snprintf(short_name, 8, "TURN%02u", tp_ct); + break; + + case finish: + snprintf(short_name, 8, "FINISH"); + state++; + break; + + case landing: + snprintf(short_name, 8, "LANDING"); + state = id; + break; + + default: + fatal(MYNAME ": task id (C) record internal error\n%s", rec); + break; + } + + // Zero lat and lon indicates an unknown waypoint + if (coords_match(wpt->latitude, wpt->longitude, 0.0, 0.0)) { + waypt_free(wpt); + return; + } + wpt->shortname = xstrdup(short_name); + route_add_wpt(rte_head, wpt); } static void data_read(void) { - char *ibuf; - igc_rec_type_t rec_type; - unsigned int hours, mins, secs; - unsigned int lat_deg, lat_min, lat_frac; - unsigned int lon_deg, lon_min, lon_frac; - char lat_hemi[2], lon_hemi[2]; - char validity; - route_head *pres_head = NULL; - route_head *gnss_head = NULL; - int pres_alt, gnss_alt; - char pres_valid = 0; - char gnss_valid = 0; - waypoint *pres_wpt = NULL; - waypoint *gnss_wpt = NULL; - time_t date = 0; - time_t prev_tod = 0; - time_t tod; - struct tm tm; - char tmp_str[20]; - char *hdr_data; - size_t remain; - char trk_desc[MAXDESCLEN + 1]; - - strcpy(trk_desc, HDRMAGIC HDRDELIM); - - while (1) { - rec_type = get_record(&ibuf); - switch (rec_type) { - case rec_manuf_id: - // Manufacturer/ID record already found in rd_init(). - warning(MYNAME ": duplicate manufacturer/ID record\n"); - break; - - case rec_header: - // Get the header sub type - if (sscanf(ibuf, "H%*1[FOP]%3s", tmp_str) != 1) { - fatal(MYNAME ": header (H) record parse error\n%s\n%s\n", ibuf, tmp_str); - } - // Optional long name of record sub type is followed by a - // colon. Actual header data follows that. - if (NULL == (hdr_data = strchr(ibuf, ':'))) { - hdr_data = ibuf + 5; - } else { - hdr_data++; - } - - // Date sub type - if (strcmp(tmp_str, "DTE") == 0) { - if (sscanf(hdr_data, "%2u%2u%2u", &tm.tm_mday, &tm.tm_mon, &tm.tm_year) != 3) { - fatal(MYNAME ": date (H) record parse error\n'%s'\n", ibuf); - } - tm.tm_sec = tm.tm_min = tm.tm_hour = 0; - tm.tm_mon -= 1; - if (tm.tm_year < 70) { - tm.tm_year += 100; - } - tm.tm_isdst = 0; - date = mkgmtime(&tm); - } else { - // Store other header data in the track descriptions - if (strlen(trk_desc) < MAXDESCLEN) { - strcat(ibuf, HDRDELIM); - remain = MAXDESCLEN - strlen(trk_desc); - strncat(trk_desc, ibuf, remain); - } - } - break; - - case rec_fix: - // Date must appear in file before the first fix record - if (date < 1000000L) { - fatal(MYNAME ": bad date %d\n", (int)date); - } - // Create a track for pressure altitude waypoints - if (!pres_head) { - pres_head = route_head_alloc(); - pres_head->rte_name = xstrdup(PRESTRKNAME); - pres_head->rte_desc = xstrdup(trk_desc); - track_add_head(pres_head); - } - // Create a second track for GNSS altitude waypoints - if (!gnss_head) { - gnss_head = route_head_alloc(); - gnss_head->rte_name = xstrdup(GNSSTRKNAME); - gnss_head->rte_desc = xstrdup(trk_desc); - track_add_head(gnss_head); - } - // Create a waypoint from the fix record data - if (sscanf(ibuf, - "B%2u%2u%2u%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%c%5d%5d", - &hours, &mins, &secs, &lat_deg, &lat_min, &lat_frac, - lat_hemi, &lon_deg, &lon_min, &lon_frac, lon_hemi, - &validity, &pres_alt, &gnss_alt) != 14) { - fatal(MYNAME ": fix (B) record parse error\n%s\n", ibuf); - } - pres_wpt = waypt_new(); - - pres_wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * - (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); - - pres_wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * - (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); - - // Increment date if we pass midnight UTC - tod = (hours * 60 + mins) * 60 + secs; - if (tod < prev_tod) { - date += 24 * 60 * 60; - } - prev_tod = tod; - pres_wpt->creation_time = date + tod; - - // Add the waypoint to the pressure altitude track - if (pres_alt) { - pres_valid = 1; - pres_wpt->altitude = pres_alt; - } else { - pres_wpt->altitude = unknown_alt; - } - track_add_wpt(pres_head, pres_wpt); - - // Add the same waypoint with GNSS altitude to the second - // track - gnss_wpt = waypt_dupe(pres_wpt); - - if (gnss_alt) { - gnss_valid = 1; - gnss_wpt->altitude = gnss_alt; - } else { - gnss_wpt->altitude = unknown_alt; - } - track_add_wpt(gnss_head, gnss_wpt); - break; - - case rec_task: - // Create a route for each pre-flight declaration - igc_task_rec(ibuf); - break; - - case rec_log_book: - // Get the log book sub type - if (sscanf(ibuf, "L%3s", tmp_str) != 1) { - fatal(MYNAME ": log book (L) record parse error\n'%s'\n", ibuf); - } - - if (strcmp(tmp_str, "PFC") == 0) { - // Create a route for each post-flight declaration - igc_task_rec(ibuf + 4); - break; - } else if (global_opts.debug_level) { - if (strcmp(tmp_str, "OOI") == 0) { - fputs(MYNAME ": Observer Input> ", stdout); - } else if (strcmp(tmp_str, "PLT") == 0) { - fputs(MYNAME ": Pilot Input> ", stdout); - } else if (strcmp(tmp_str, manufacturer) == 0) { - fputs(MYNAME ": Manufacturer Input> ", stdout); - } else { - fputs(MYNAME ": Anonymous Input> ", stdout); - fputs(ibuf + 1, stdout); - break; - } - fputs(ibuf + 4, stdout); - putchar('\n'); - } - break; - - // These record types are discarded - case rec_diff_gps: - case rec_event: - case rec_constel: - case rec_security: - case rec_fix_defn: - case rec_extn_defn: - case rec_extn_data: - break; - - // No more records - case rec_none: - - // Include pressure altitude track only if it has useful - // altitude data or if it is the only track available. - if (pres_head && !pres_valid && gnss_head) { - track_del_head(pres_head); - pres_head = NULL; - } - // Include GNSS altitude track only if it has useful altitude - // data or if it is the only track available. - if (gnss_head && !gnss_valid && pres_head) { - track_del_head(gnss_head); - } - return; // All done so bail - - default: - case rec_bad: - fatal(MYNAME ": failure reading file\n"); - break; - } + char* ibuf; + igc_rec_type_t rec_type; + unsigned int hours, mins, secs; + unsigned int lat_deg, lat_min, lat_frac; + unsigned int lon_deg, lon_min, lon_frac; + char lat_hemi[2], lon_hemi[2]; + char validity; + route_head* pres_head = NULL; + route_head* gnss_head = NULL; + int pres_alt, gnss_alt; + char pres_valid = 0; + char gnss_valid = 0; + waypoint* pres_wpt = NULL; + waypoint* gnss_wpt = NULL; + time_t date = 0; + time_t prev_tod = 0; + time_t tod; + struct tm tm; + char tmp_str[20]; + char* hdr_data; + size_t remain; + char trk_desc[MAXDESCLEN + 1]; + + strcpy(trk_desc, HDRMAGIC HDRDELIM); + + while (1) { + rec_type = get_record(&ibuf); + switch (rec_type) { + case rec_manuf_id: + // Manufacturer/ID record already found in rd_init(). + warning(MYNAME ": duplicate manufacturer/ID record\n"); + break; + + case rec_header: + // Get the header sub type + if (sscanf(ibuf, "H%*1[FOP]%3s", tmp_str) != 1) { + fatal(MYNAME ": header (H) record parse error\n%s\n%s\n", ibuf, tmp_str); + } + // Optional long name of record sub type is followed by a + // colon. Actual header data follows that. + if (NULL == (hdr_data = strchr(ibuf, ':'))) { + hdr_data = ibuf + 5; + } else { + hdr_data++; + } + + // Date sub type + if (strcmp(tmp_str, "DTE") == 0) { + if (sscanf(hdr_data, "%2u%2u%2u", &tm.tm_mday, &tm.tm_mon, &tm.tm_year) != 3) { + fatal(MYNAME ": date (H) record parse error\n'%s'\n", ibuf); + } + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + tm.tm_mon -= 1; + if (tm.tm_year < 70) { + tm.tm_year += 100; + } + tm.tm_isdst = 0; + date = mkgmtime(&tm); + } else { + // Store other header data in the track descriptions + if (strlen(trk_desc) < MAXDESCLEN) { + strcat(ibuf, HDRDELIM); + remain = MAXDESCLEN - strlen(trk_desc); + strncat(trk_desc, ibuf, remain); + } + } + break; + + case rec_fix: + // Date must appear in file before the first fix record + if (date < 1000000L) { + fatal(MYNAME ": bad date %d\n", (int)date); + } + // Create a track for pressure altitude waypoints + if (!pres_head) { + pres_head = route_head_alloc(); + pres_head->rte_name = xstrdup(PRESTRKNAME); + pres_head->rte_desc = xstrdup(trk_desc); + track_add_head(pres_head); + } + // Create a second track for GNSS altitude waypoints + if (!gnss_head) { + gnss_head = route_head_alloc(); + gnss_head->rte_name = xstrdup(GNSSTRKNAME); + gnss_head->rte_desc = xstrdup(trk_desc); + track_add_head(gnss_head); + } + // Create a waypoint from the fix record data + if (sscanf(ibuf, + "B%2u%2u%2u%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%c%5d%5d", + &hours, &mins, &secs, &lat_deg, &lat_min, &lat_frac, + lat_hemi, &lon_deg, &lon_min, &lon_frac, lon_hemi, + &validity, &pres_alt, &gnss_alt) != 14) { + fatal(MYNAME ": fix (B) record parse error\n%s\n", ibuf); + } + pres_wpt = waypt_new(); + + pres_wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * + (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); + + pres_wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * + (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); + + // Increment date if we pass midnight UTC + tod = (hours * 60 + mins) * 60 + secs; + if (tod < prev_tod) { + date += 24 * 60 * 60; + } + prev_tod = tod; + pres_wpt->creation_time = date + tod; + + // Add the waypoint to the pressure altitude track + if (pres_alt) { + pres_valid = 1; + pres_wpt->altitude = pres_alt; + } else { + pres_wpt->altitude = unknown_alt; + } + track_add_wpt(pres_head, pres_wpt); + + // Add the same waypoint with GNSS altitude to the second + // track + gnss_wpt = waypt_dupe(pres_wpt); + + if (gnss_alt) { + gnss_valid = 1; + gnss_wpt->altitude = gnss_alt; + } else { + gnss_wpt->altitude = unknown_alt; + } + track_add_wpt(gnss_head, gnss_wpt); + break; + + case rec_task: + // Create a route for each pre-flight declaration + igc_task_rec(ibuf); + break; + + case rec_log_book: + // Get the log book sub type + if (sscanf(ibuf, "L%3s", tmp_str) != 1) { + fatal(MYNAME ": log book (L) record parse error\n'%s'\n", ibuf); + } + + if (strcmp(tmp_str, "PFC") == 0) { + // Create a route for each post-flight declaration + igc_task_rec(ibuf + 4); + break; + } else if (global_opts.debug_level) { + if (strcmp(tmp_str, "OOI") == 0) { + fputs(MYNAME ": Observer Input> ", stdout); + } else if (strcmp(tmp_str, "PLT") == 0) { + fputs(MYNAME ": Pilot Input> ", stdout); + } else if (strcmp(tmp_str, manufacturer) == 0) { + fputs(MYNAME ": Manufacturer Input> ", stdout); + } else { + fputs(MYNAME ": Anonymous Input> ", stdout); + fputs(ibuf + 1, stdout); + break; + } + fputs(ibuf + 4, stdout); + putchar('\n'); + } + break; + + // These record types are discarded + case rec_diff_gps: + case rec_event: + case rec_constel: + case rec_security: + case rec_fix_defn: + case rec_extn_defn: + case rec_extn_data: + break; + + // No more records + case rec_none: + + // Include pressure altitude track only if it has useful + // altitude data or if it is the only track available. + if (pres_head && !pres_valid && gnss_head) { + track_del_head(pres_head); + pres_head = NULL; + } + // Include GNSS altitude track only if it has useful altitude + // data or if it is the only track available. + if (gnss_head && !gnss_valid && pres_head) { + track_del_head(gnss_head); + } + return; // All done so bail + + default: + case rec_bad: + fatal(MYNAME ": failure reading file\n"); + break; } + } } /************************************************************************************************* - * Output file processing + * Output file processing */ /************************************************* * Callbacks used to scan for specific track types */ -static void detect_pres_track(const route_head * rh) +static void detect_pres_track(const route_head* rh) { - if (rh->rte_name && strncmp(rh->rte_name, PRESTRKNAME, 6) == 0) { - head = rh; - } + if (rh->rte_name && strncmp(rh->rte_name, PRESTRKNAME, 6) == 0) { + head = rh; + } } -static void detect_gnss_track(const route_head * rh) +static void detect_gnss_track(const route_head* rh) { - if (rh->rte_name && strncmp(rh->rte_name, GNSSTRKNAME, 6) == 0) { - head = rh; - } + if (rh->rte_name && strncmp(rh->rte_name, GNSSTRKNAME, 6) == 0) { + head = rh; + } } -static void detect_other_track(const route_head * rh) +static void detect_other_track(const route_head* rh) { - static int max_waypt_ct; - - if (!head) { - max_waypt_ct = 0; - } - // Find other track with the most waypoints - if (rh->rte_waypt_ct > max_waypt_ct && - (!rh->rte_name || - (strncmp(rh->rte_name, PRESTRKNAME, 6) != 0 && - strncmp(rh->rte_name, GNSSTRKNAME, 6) != 0))) { - head = rh; - max_waypt_ct = rh->rte_waypt_ct; - } + static int max_waypt_ct; + + if (!head) { + max_waypt_ct = 0; + } + // Find other track with the most waypoints + if (rh->rte_waypt_ct > max_waypt_ct && + (!rh->rte_name || + (strncmp(rh->rte_name, PRESTRKNAME, 6) != 0 && + strncmp(rh->rte_name, GNSSTRKNAME, 6) != 0))) { + head = rh; + max_waypt_ct = rh->rte_waypt_ct; + } } /* @@ -485,67 +498,67 @@ static void detect_other_track(const route_head * rh) * @param gnss_track Set by the function to the GNSS altitude track * head. NULL if not found. */ -static void get_tracks(const route_head ** pres_track, const route_head ** gnss_track) +static void get_tracks(const route_head** pres_track, const route_head** gnss_track) { - head = NULL; - track_disp_all(detect_pres_track, NULL, NULL); - *pres_track = head; + head = NULL; + track_disp_all(detect_pres_track, NULL, NULL); + *pres_track = head; - head = NULL; - track_disp_all(detect_gnss_track, NULL, NULL); - *gnss_track = head; + head = NULL; + track_disp_all(detect_gnss_track, NULL, NULL); + *gnss_track = head; - head = NULL; - track_disp_all(detect_other_track, NULL, NULL); + head = NULL; + track_disp_all(detect_other_track, NULL, NULL); - if (!*pres_track && *gnss_track && head) { - *pres_track = head; - } + if (!*pres_track && *gnss_track && head) { + *pres_track = head; + } - if (!*gnss_track && head) { - *gnss_track = head; - } + if (!*gnss_track && head) { + *gnss_track = head; + } } /************************************************* * IGC string formatting functions */ -static char *latlon2str(const waypoint * wpt) +static char* latlon2str(const waypoint* wpt) { - static char str[18] = ""; - char lat_hemi = wpt->latitude < 0 ? 'S' : 'N'; - char lon_hemi = wpt->longitude < 0 ? 'W' : 'E'; - unsigned char lat_deg = fabs(wpt->latitude); - unsigned char lon_deg = fabs(wpt->longitude); - unsigned int lat_min = (fabs(wpt->latitude) - lat_deg) * 60000 + 0.500000000001; - unsigned int lon_min = (fabs(wpt->longitude) - lon_deg) * 60000 + 0.500000000001; - - if (snprintf(str, 18, "%02u%05u%c%03u%05u%c", - lat_deg, lat_min, lat_hemi, lon_deg, lon_min, lon_hemi) != 17) { - fatal(MYNAME ": Bad waypoint format '%s'\n", str); - } - return str; + static char str[18] = ""; + char lat_hemi = wpt->latitude < 0 ? 'S' : 'N'; + char lon_hemi = wpt->longitude < 0 ? 'W' : 'E'; + unsigned char lat_deg = fabs(wpt->latitude); + unsigned char lon_deg = fabs(wpt->longitude); + unsigned int lat_min = (fabs(wpt->latitude) - lat_deg) * 60000 + 0.500000000001; + unsigned int lon_min = (fabs(wpt->longitude) - lon_deg) * 60000 + 0.500000000001; + + if (snprintf(str, 18, "%02u%05u%c%03u%05u%c", + lat_deg, lat_min, lat_hemi, lon_deg, lon_min, lon_hemi) != 17) { + fatal(MYNAME ": Bad waypoint format '%s'\n", str); + } + return str; } -static char *date2str(struct tm *dt) +static char* date2str(struct tm* dt) { - static char str[7] = ""; + static char str[7] = ""; - if (snprintf(str, 7, "%02u%02u%02u", dt->tm_mday, dt->tm_mon + 1, dt->tm_year % 100) != 6) { - fatal(MYNAME ": Bad date format '%s'\n", str); - } - return str; + if (snprintf(str, 7, "%02u%02u%02u", dt->tm_mday, dt->tm_mon + 1, dt->tm_year % 100) != 6) { + fatal(MYNAME ": Bad date format '%s'\n", str); + } + return str; } -static char *tod2str(struct tm *tod) +static char* tod2str(struct tm* tod) { - static char str[7] = ""; + static char str[7] = ""; - if (snprintf(str, 7, "%02u%02u%02u", tod->tm_hour, tod->tm_min, tod->tm_sec) != 6) { - fatal(MYNAME ": Bad time of day format '%s'\n", str); - } - return str; + if (snprintf(str, 7, "%02u%02u%02u", tod->tm_hour, tod->tm_min, tod->tm_sec) != 6) { + fatal(MYNAME ": Bad time of day format '%s'\n", str); + } + return str; } /* @@ -553,143 +566,142 @@ static char *tod2str(struct tm *tod) */ static void wr_header(void) { - const route_head *pres_track; - const route_head *track; - struct tm *tm; - time_t date; - static const char dflt_str[] = "Unknown"; - const char *str; - waypoint *wpt; - - get_tracks(&pres_track, &track); - if (!track && pres_track) { - track = pres_track; - } - // Date in header record is that of the first fix record - date = !track ? current_time() : - ((waypoint *) QUEUE_FIRST(&track->waypoint_list))->creation_time; - - if (NULL == (tm = gmtime(&date))) { - fatal(MYNAME ": Bad track timestamp\n"); - } - gbfprintf(file_out, "HFDTE%s\r\n", date2str(tm)); - - // Other header data may have been stored in track description - if (track && track->rte_desc && strncmp(track->rte_desc, HDRMAGIC, strlen(HDRMAGIC)) == 0) { - for (str = strtok(track->rte_desc + strlen(HDRMAGIC) + strlen(HDRDELIM), HDRDELIM); - str; str = strtok(NULL, HDRDELIM)) { - gbfprintf(file_out, "%s\r\n", str); - } - } else { - // IGC header info not found so synthesise it. - // If a waypoint is supplied with a short name of "PILOT", use - // its description as the pilot's name in the header. - str = dflt_str; - if (NULL != (wpt = find_waypt_by_name("PILOT")) && wpt->description) { - str = wpt->description; - } - gbfprintf(file_out, "HFPLTPILOT:%s\r\n", str); - } + const route_head* pres_track; + const route_head* track; + struct tm* tm; + time_t date; + static const char dflt_str[] = "Unknown"; + const char* str; + waypoint* wpt; + + get_tracks(&pres_track, &track); + if (!track && pres_track) { + track = pres_track; + } + // Date in header record is that of the first fix record + date = !track ? current_time() : + ((waypoint*) QUEUE_FIRST(&track->waypoint_list))->creation_time; + + if (NULL == (tm = gmtime(&date))) { + fatal(MYNAME ": Bad track timestamp\n"); + } + gbfprintf(file_out, "HFDTE%s\r\n", date2str(tm)); + + // Other header data may have been stored in track description + if (track && track->rte_desc && strncmp(track->rte_desc, HDRMAGIC, strlen(HDRMAGIC)) == 0) { + for (str = strtok(track->rte_desc + strlen(HDRMAGIC) + strlen(HDRDELIM), HDRDELIM); + str; str = strtok(NULL, HDRDELIM)) { + gbfprintf(file_out, "%s\r\n", str); + } + } else { + // IGC header info not found so synthesise it. + // If a waypoint is supplied with a short name of "PILOT", use + // its description as the pilot's name in the header. + str = dflt_str; + if (NULL != (wpt = find_waypt_by_name("PILOT")) && wpt->description) { + str = wpt->description; + } + gbfprintf(file_out, "HFPLTPILOT:%s\r\n", str); + } } /************************************************* * Generation of IGC task declaration records */ -static void wr_task_wpt_name(const waypoint * wpt, const char *alt_name) +static void wr_task_wpt_name(const waypoint* wpt, const char* alt_name) { - gbfprintf(file_out, "C%s%s\r\n", latlon2str(wpt), - wpt->description ? wpt->description : wpt->shortname ? wpt->shortname : alt_name); + gbfprintf(file_out, "C%s%s\r\n", latlon2str(wpt), + wpt->description ? wpt->description : wpt->shortname ? wpt->shortname : alt_name); } -static void wr_task_hdr(const route_head * rte) +static void wr_task_hdr(const route_head* rte) { - unsigned char have_takeoff = 0; - const waypoint *wpt; - char flight_date[7] = "000000"; - char task_desc[MAXRECLEN] = ""; - int num_tps = rte->rte_waypt_ct - 2; - struct tm *tm; - time_t rte_time; - static unsigned int task_num = 1; - - if (num_tps < 0) { - fatal(MYNAME ": Empty task route\n"); - } - // See if the takeoff and landing waypoints are there or if we need to - // generate them. - wpt = (waypoint *) QUEUE_LAST(&rte->waypoint_list); - if (wpt->shortname && strncmp(wpt->shortname, "LANDING", 6) == 0) { - num_tps--; - } - wpt = (waypoint *) QUEUE_FIRST(&rte->waypoint_list); - if (wpt->shortname && strncmp(wpt->shortname, "TAKEOFF", 6) == 0) { - have_takeoff = 1; - num_tps--; - } - if (num_tps < 0) { - fatal(MYNAME ": Too few waypoints in task route\n"); - } - else if (num_tps > 99) { - fatal(MYNAME ": Too much waypoints (more than 99) in task route.\n"); - } - // Gather data to write to the task identification (first) record - rte_time = wpt->creation_time ? wpt->creation_time : current_time(); - if (NULL == (tm = gmtime(&rte_time))) { - fatal(MYNAME ": Bad task route timestamp\n"); - } - - if (rte->rte_desc) { - sscanf(rte->rte_desc, DATEMAGIC "%6[0-9]: %s", flight_date, task_desc); - } - - gbfprintf(file_out, "C%s%s%s%04u%02u%s\r\n", date2str(tm), - tod2str(tm), flight_date, task_num++, num_tps, task_desc); - - if (!have_takeoff) { - // Generate the takeoff waypoint - wr_task_wpt_name(wpt, "TAKEOFF"); - } + unsigned char have_takeoff = 0; + const waypoint* wpt; + char flight_date[7] = "000000"; + char task_desc[MAXRECLEN] = ""; + int num_tps = rte->rte_waypt_ct - 2; + struct tm* tm; + time_t rte_time; + static unsigned int task_num = 1; + + if (num_tps < 0) { + fatal(MYNAME ": Empty task route\n"); + } + // See if the takeoff and landing waypoints are there or if we need to + // generate them. + wpt = (waypoint*) QUEUE_LAST(&rte->waypoint_list); + if (wpt->shortname && strncmp(wpt->shortname, "LANDING", 6) == 0) { + num_tps--; + } + wpt = (waypoint*) QUEUE_FIRST(&rte->waypoint_list); + if (wpt->shortname && strncmp(wpt->shortname, "TAKEOFF", 6) == 0) { + have_takeoff = 1; + num_tps--; + } + if (num_tps < 0) { + fatal(MYNAME ": Too few waypoints in task route\n"); + } else if (num_tps > 99) { + fatal(MYNAME ": Too much waypoints (more than 99) in task route.\n"); + } + // Gather data to write to the task identification (first) record + rte_time = wpt->creation_time ? wpt->creation_time : current_time(); + if (NULL == (tm = gmtime(&rte_time))) { + fatal(MYNAME ": Bad task route timestamp\n"); + } + + if (rte->rte_desc) { + sscanf(rte->rte_desc, DATEMAGIC "%6[0-9]: %s", flight_date, task_desc); + } + + gbfprintf(file_out, "C%s%s%s%04u%02u%s\r\n", date2str(tm), + tod2str(tm), flight_date, task_num++, num_tps, task_desc); + + if (!have_takeoff) { + // Generate the takeoff waypoint + wr_task_wpt_name(wpt, "TAKEOFF"); + } } -static void wr_task_wpt(const waypoint * wpt) +static void wr_task_wpt(const waypoint* wpt) { - wr_task_wpt_name(wpt, ""); + wr_task_wpt_name(wpt, ""); } -static void wr_task_tlr(const route_head * rte) +static void wr_task_tlr(const route_head* rte) { - // If the landing waypoint is not supplied we need to generate it. - const waypoint *wpt = (waypoint *) QUEUE_LAST(&rte->waypoint_list); - if (!wpt->shortname || strncmp(wpt->shortname, "LANDIN", 6) != 0) { - wr_task_wpt_name(wpt, "LANDING"); - } + // If the landing waypoint is not supplied we need to generate it. + const waypoint* wpt = (waypoint*) QUEUE_LAST(&rte->waypoint_list); + if (!wpt->shortname || strncmp(wpt->shortname, "LANDIN", 6) != 0) { + wr_task_wpt_name(wpt, "LANDING"); + } } static void wr_tasks(void) { - route_disp_all(wr_task_hdr, wr_task_tlr, wr_task_wpt); + route_disp_all(wr_task_hdr, wr_task_tlr, wr_task_wpt); } /* * Write a single fix record */ -static void wr_fix_record(const waypoint * wpt, int pres_alt, int gnss_alt) +static void wr_fix_record(const waypoint* wpt, int pres_alt, int gnss_alt) { - struct tm *tm; - - if (NULL == (tm = gmtime(&wpt->creation_time))) { - fatal(MYNAME ": bad track timestamp\n"); - } - - if (unknown_alt == pres_alt) { - pres_alt = 0; - } - if (unknown_alt == gnss_alt) { - gnss_alt = 0; - } - gbfprintf(file_out, "B%02u%02u%02u%sA%05d%05d\r\n", tm->tm_hour, - tm->tm_min, tm->tm_sec, latlon2str(wpt), pres_alt, gnss_alt); + struct tm* tm; + + if (NULL == (tm = gmtime(&wpt->creation_time))) { + fatal(MYNAME ": bad track timestamp\n"); + } + + if (unknown_alt == pres_alt) { + pres_alt = 0; + } + if (unknown_alt == gnss_alt) { + gnss_alt = 0; + } + gbfprintf(file_out, "B%02u%02u%02u%sA%05d%05d\r\n", tm->tm_hour, + tm->tm_min, tm->tm_sec, latlon2str(wpt), pres_alt, gnss_alt); } /** @@ -700,64 +712,64 @@ static void wr_fix_record(const waypoint * wpt, int pres_alt, int gnss_alt) * @return The number of seconds to add to the GNSS track in order to align * it with the pressure track. */ -static int correlate_tracks(const route_head * pres_track, const route_head * gnss_track) +static int correlate_tracks(const route_head* pres_track, const route_head* gnss_track) { - const queue *elem; - double last_alt, alt_diff; - double speed; - time_t pres_time, gnss_time; - int time_diff; - const waypoint *wpt; - - // Deduce the landing time from the pressure altitude track based on - // when we last descended to within 10m of the final track altitude. - elem = QUEUE_LAST(&pres_track->waypoint_list); - last_alt = ((waypoint *) elem)->altitude; - do { - elem = elem->prev; - if (&pres_track->waypoint_list == elem) { - // No track left - return 0; - } - alt_diff = last_alt - ((waypoint *) elem)->altitude; - if (alt_diff > 10.0) { - // Last part of track was ascending - return 0; - } - } while (alt_diff > -10.0); - pres_time = ((waypoint *) elem->next)->creation_time; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": pressure landing time %s", ctime(&pres_time)); - } - // Deduce the landing time from the GNSS altitude track based on - // when the groundspeed last dropped below a certain level. - elem = QUEUE_LAST(&gnss_track->waypoint_list); - last_alt = ((waypoint *) elem)->altitude; - do { - wpt = (waypoint *) elem; - elem = elem->prev; - if (&gnss_track->waypoint_list == elem) { - // No track left - return 0; - } - // Get a crude indication of groundspeed from the change in lat/lon - time_diff = wpt->creation_time - ((waypoint *) elem)->creation_time; - speed = !time_diff ? 0 : - (fabs(wpt->latitude - ((waypoint *) elem)->latitude) + - fabs(wpt->longitude - ((waypoint *) elem)->longitude)) / time_diff; - if (global_opts.debug_level >= 2) { - printf(MYNAME ": speed=%f\n", speed); - } - } while (speed < 0.00003); - gnss_time = ((waypoint *) elem->next)->creation_time; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": gnss landing time %s", ctime(&gnss_time)); - } - // Time adjustment is difference between the two estimated landing times - if (15 * 60 < abs(time_diff = pres_time - gnss_time)) { - warning(MYNAME ": excessive time adjustment %ds\n", time_diff); - } - return time_diff; + const queue* elem; + double last_alt, alt_diff; + double speed; + time_t pres_time, gnss_time; + int time_diff; + const waypoint* wpt; + + // Deduce the landing time from the pressure altitude track based on + // when we last descended to within 10m of the final track altitude. + elem = QUEUE_LAST(&pres_track->waypoint_list); + last_alt = ((waypoint*) elem)->altitude; + do { + elem = elem->prev; + if (&pres_track->waypoint_list == elem) { + // No track left + return 0; + } + alt_diff = last_alt - ((waypoint*) elem)->altitude; + if (alt_diff > 10.0) { + // Last part of track was ascending + return 0; + } + } while (alt_diff > -10.0); + pres_time = ((waypoint*) elem->next)->creation_time; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": pressure landing time %s", ctime(&pres_time)); + } + // Deduce the landing time from the GNSS altitude track based on + // when the groundspeed last dropped below a certain level. + elem = QUEUE_LAST(&gnss_track->waypoint_list); + last_alt = ((waypoint*) elem)->altitude; + do { + wpt = (waypoint*) elem; + elem = elem->prev; + if (&gnss_track->waypoint_list == elem) { + // No track left + return 0; + } + // Get a crude indication of groundspeed from the change in lat/lon + time_diff = wpt->creation_time - ((waypoint*) elem)->creation_time; + speed = !time_diff ? 0 : + (fabs(wpt->latitude - ((waypoint*) elem)->latitude) + + fabs(wpt->longitude - ((waypoint*) elem)->longitude)) / time_diff; + if (global_opts.debug_level >= 2) { + printf(MYNAME ": speed=%f\n", speed); + } + } while (speed < 0.00003); + gnss_time = ((waypoint*) elem->next)->creation_time; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": gnss landing time %s", ctime(&gnss_time)); + } + // Time adjustment is difference between the two estimated landing times + if (15 * 60 < abs(time_diff = pres_time - gnss_time)) { + warning(MYNAME ": excessive time adjustment %ds\n", time_diff); + } + return time_diff; } /** @@ -766,48 +778,48 @@ static int correlate_tracks(const route_head * pres_track, const route_head * gn * @param time The time that we are interested in. * @return The altitude interpolated from the track. */ -static double interpolate_alt(const route_head * track, time_t time) +static double interpolate_alt(const route_head* track, time_t time) { - static const queue *prev_elem = NULL; - static const queue *curr_elem = NULL; - const waypoint *prev_wpt; - const waypoint *curr_wpt; - int time_diff; - double alt_diff; - - // Start search at the beginning of the track - if (!prev_elem) { - curr_elem = prev_elem = QUEUE_FIRST(&track->waypoint_list); - } - // Find the track points either side of the requested time - while (((waypoint *) curr_elem)->creation_time < time) { - if (QUEUE_LAST(&track->waypoint_list) == curr_elem) { - // Requested time later than all track points, we can't interpolate - return unknown_alt; - } - prev_elem = curr_elem; - curr_elem = QUEUE_NEXT(prev_elem); - } - - prev_wpt = (waypoint *) prev_elem; - curr_wpt = (waypoint *) curr_elem; - - if (QUEUE_FIRST(&track->waypoint_list) == curr_elem) { - if (curr_wpt->creation_time == time) { - // First point's creation time is an exact match so use it's altitude - return curr_wpt->altitude; - } else { - // Requested time is prior to any track points, we can't interpolate - return unknown_alt; - } - } - // Interpolate - if (0 == (time_diff = curr_wpt->creation_time - prev_wpt->creation_time)) { - // Avoid divide by zero - return curr_wpt->altitude; - } - alt_diff = curr_wpt->altitude - prev_wpt->altitude; - return prev_wpt->altitude + (alt_diff / time_diff) * (time - prev_wpt->creation_time); + static const queue* prev_elem = NULL; + static const queue* curr_elem = NULL; + const waypoint* prev_wpt; + const waypoint* curr_wpt; + int time_diff; + double alt_diff; + + // Start search at the beginning of the track + if (!prev_elem) { + curr_elem = prev_elem = QUEUE_FIRST(&track->waypoint_list); + } + // Find the track points either side of the requested time + while (((waypoint*) curr_elem)->creation_time < time) { + if (QUEUE_LAST(&track->waypoint_list) == curr_elem) { + // Requested time later than all track points, we can't interpolate + return unknown_alt; + } + prev_elem = curr_elem; + curr_elem = QUEUE_NEXT(prev_elem); + } + + prev_wpt = (waypoint*) prev_elem; + curr_wpt = (waypoint*) curr_elem; + + if (QUEUE_FIRST(&track->waypoint_list) == curr_elem) { + if (curr_wpt->creation_time == time) { + // First point's creation time is an exact match so use it's altitude + return curr_wpt->altitude; + } else { + // Requested time is prior to any track points, we can't interpolate + return unknown_alt; + } + } + // Interpolate + if (0 == (time_diff = curr_wpt->creation_time - prev_wpt->creation_time)) { + // Avoid divide by zero + return curr_wpt->altitude; + } + alt_diff = curr_wpt->altitude - prev_wpt->altitude; + return prev_wpt->altitude + (alt_diff / time_diff) * (time - prev_wpt->creation_time); } /* @@ -816,95 +828,97 @@ static double interpolate_alt(const route_head * track, time_t time) */ static void wr_track(void) { - const route_head *pres_track; - const route_head *gnss_track; - const waypoint *wpt; - const queue *elem; - const queue *tmp; - int time_adj; - double pres_alt; - - // Find pressure altitude and GNSS altitude tracks - get_tracks(&pres_track, &gnss_track); - - // If both found, attempt to merge them - if (pres_track && gnss_track) { - if (timeadj) { - if (strcmp(timeadj, "auto") == 0) { - time_adj = correlate_tracks(pres_track, gnss_track); - } else if (sscanf(timeadj, "%d", &time_adj) != 1) { - fatal(MYNAME ": bad timeadj argument '%s'\n", timeadj); - } - } else { - time_adj = 0; - } - if (global_opts.debug_level >= 1) { - printf(MYNAME ": adjusting time by %ds\n", time_adj); - } - // Iterate through waypoints in both tracks simultaneously - QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { - wpt = (waypoint *) elem; - pres_alt = interpolate_alt(pres_track, wpt->creation_time + time_adj); - wr_fix_record(wpt, (int) pres_alt, (int) wpt->altitude); - } + const route_head* pres_track; + const route_head* gnss_track; + const waypoint* wpt; + const queue* elem; + const queue* tmp; + int time_adj; + double pres_alt; + + // Find pressure altitude and GNSS altitude tracks + get_tracks(&pres_track, &gnss_track); + + // If both found, attempt to merge them + if (pres_track && gnss_track) { + if (timeadj) { + if (strcmp(timeadj, "auto") == 0) { + time_adj = correlate_tracks(pres_track, gnss_track); + } else if (sscanf(timeadj, "%d", &time_adj) != 1) { + fatal(MYNAME ": bad timeadj argument '%s'\n", timeadj); + } + } else { + time_adj = 0; + } + if (global_opts.debug_level >= 1) { + printf(MYNAME ": adjusting time by %ds\n", time_adj); + } + // Iterate through waypoints in both tracks simultaneously + QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { + wpt = (waypoint*) elem; + pres_alt = interpolate_alt(pres_track, wpt->creation_time + time_adj); + wr_fix_record(wpt, (int) pres_alt, (int) wpt->altitude); + } + } else { + if (pres_track) { + // Only the pressure altitude track was found so generate fix + // records from it alone. + QUEUE_FOR_EACH(&pres_track->waypoint_list, elem, tmp) { + wr_fix_record((waypoint*) elem, (int)((waypoint*) elem)->altitude, (int) unknown_alt); + } + } else if (gnss_track) { + // Only the GNSS altitude track was found so generate fix + // records from it alone. + QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { + wr_fix_record((waypoint*) elem, (int) unknown_alt, (int)((waypoint*) elem)->altitude); + } } else { - if (pres_track) { - // Only the pressure altitude track was found so generate fix - // records from it alone. - QUEUE_FOR_EACH(&pres_track->waypoint_list, elem, tmp) { - wr_fix_record((waypoint *) elem, (int) ((waypoint *) elem)->altitude, (int) unknown_alt); - } - } else if (gnss_track) { - // Only the GNSS altitude track was found so generate fix - // records from it alone. - QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { - wr_fix_record((waypoint *) elem, (int) unknown_alt, (int) ((waypoint *) elem)->altitude); - } - } else { - // No tracks found so nothing to do - return; - } + // No tracks found so nothing to do + return; } + } } -static void wr_init(const char *fname) +static void wr_init(const char* fname) { - file_out = gbfopen(fname, "wb", MYNAME); + file_out = gbfopen(fname, "wb", MYNAME); } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } static void data_write(void) { - gbfputs("AXXXZZZGPSBabel\r\n", file_out); - wr_header(); - wr_tasks(); - wr_track(); - gbfprintf(file_out, "LXXXGenerated by GPSBabel Version %s\r\n", gpsbabel_version); - gbfputs("GGPSBabelSecurityRecordGuaranteedToFailVALIChecks\r\n", file_out); + gbfputs("AXXXZZZGPSBabel\r\n", file_out); + wr_header(); + wr_tasks(); + wr_track(); + gbfprintf(file_out, "LXXXGenerated by GPSBabel Version %s\r\n", gpsbabel_version); + gbfputs("GGPSBabelSecurityRecordGuaranteedToFailVALIChecks\r\n", file_out); } static arglist_t igc_args[] = { - {"timeadj", &timeadj, - "(integer sec or 'auto') Barograph to GPS time diff", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "timeadj", &timeadj, + "(integer sec or 'auto') Barograph to GPS time diff", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t igc_vecs = { - ff_type_file, - { ff_cap_none , ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - igc_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none , (ff_cap)(ff_cap_read | ff_cap_write), (ff_cap)(ff_cap_read | ff_cap_write) }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + igc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/ignrando.c b/gpsbabel/ignrando.c index 58ab29bcc..ba38292b0 100644 --- a/gpsbabel/ignrando.c +++ b/gpsbabel/ignrando.c @@ -1,7 +1,7 @@ -/* +/* Support for IGN Rando track files. - + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -33,30 +33,29 @@ #define MYNAME "IGNRando" -static gbfile *fout; +static gbfile* fout; -static route_head *track; -static waypoint *wpt; +static route_head* track; +static waypoint* wpt; static int track_index; /* index of track we'll write */ static int track_num; /* current index of track within track_disp_all */ static int xmlpoints; /* options */ -static char *index_opt = NULL; +static char* index_opt = NULL; -static arglist_t ignr_args[] = -{ - {"index", &index_opt, "Index of track to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR +static arglist_t ignr_args[] = { + {"index", &index_opt, "Index of track to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR }; #if ! HAVE_LIBEXPAT static void -ignr_rd_init(const char *fname) +ignr_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded \"" MYNAME "\" input support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \"" MYNAME "\" input support because expat was not installed.\n"); } static void @@ -77,24 +76,24 @@ static xg_callback ignr_nb_etapes, ignr_descr; static xg_callback ignr_etape_begin, ignr_etape_end; static xg_callback ignr_etape_pos, ignr_etape_alt; -static -xg_tag_mapping ignr_xml_map[] = -{ - { ignr_start, cb_start, "/RANDONNEE" }, - { ignr_nb_etapes, cb_cdata, "/RANDONNEE/INFORMATIONS/NB_ETAPES" }, - { ignr_descr, cb_cdata, "/RANDONNEE/INFORMATIONS/DESCRIPTION" }, - { ignr_etape_begin, cb_start, "/RANDONNEE/ETAPE" }, - { ignr_etape_end, cb_end, "/RANDONNEE/ETAPE" }, - { ignr_etape_pos, cb_cdata, "/RANDONNEE/ETAPE/POSITION" }, - { ignr_etape_alt, cb_cdata, "/RANDONNEE/ETAPE/ALTITUDE" }, - { NULL, 0, NULL } +static +xg_tag_mapping ignr_xml_map[] = { + { ignr_start, cb_start, "/RANDONNEE" }, + { ignr_nb_etapes, cb_cdata, "/RANDONNEE/INFORMATIONS/NB_ETAPES" }, + { ignr_descr, cb_cdata, "/RANDONNEE/INFORMATIONS/DESCRIPTION" }, + { ignr_etape_begin, cb_start, "/RANDONNEE/ETAPE" }, + { ignr_etape_end, cb_end, "/RANDONNEE/ETAPE" }, + { ignr_etape_pos, cb_cdata, "/RANDONNEE/ETAPE/POSITION" }, + { ignr_etape_alt, cb_cdata, "/RANDONNEE/ETAPE/ALTITUDE" }, + { NULL, (xg_cb_type)0, NULL } }; static void ignr_xml_error(int condition) { - if (condition != 0) - fatal(MYNAME ": Error in XML structure!\n"); + if (condition != 0) { + fatal(MYNAME ": Error in XML structure!\n"); + } } /* xmlgeneric callbacks */ @@ -103,86 +102,91 @@ static xg_callback ignr_start; static xg_callback ignr_nb_etapes, ignr_descr; static xg_callback ignr_etape_begin, ignr_etape_end; -static void -ignr_start(const char *args, const char **attrv) +static void +ignr_start(const char* args, const char** attrv) { - ignr_xml_error((track != NULL)); - - track = route_head_alloc(); - track_add_head(track); + ignr_xml_error((track != NULL)); + + track = route_head_alloc(); + track_add_head(track); } -static void -ignr_nb_etapes(const char *args, const char **attrv) +static void +ignr_nb_etapes(const char* args, const char** attrv) { - xmlpoints = atoi(args); + xmlpoints = atoi(args); } -static void -ignr_descr(const char *args, const char **attrv) +static void +ignr_descr(const char* args, const char** attrv) { - ignr_xml_error((track == NULL)); + ignr_xml_error((track == NULL)); - if ((args != NULL) && (strlen(args) > 0)) - track->rte_desc = xstrdup(args); + if ((args != NULL) && (strlen(args) > 0)) { + track->rte_desc = xstrdup(args); + } } -static void -ignr_etape_begin(const char *args, const char **attrv) +static void +ignr_etape_begin(const char* args, const char** attrv) { - ignr_xml_error((wpt != NULL)); - - wpt = waypt_new(); + ignr_xml_error((wpt != NULL)); + + wpt = waypt_new(); } -static void -ignr_etape_end(const char *args, const char **attrv) +static void +ignr_etape_end(const char* args, const char** attrv) { - ignr_xml_error((track == NULL) || (wpt == NULL)); - - track_add_wpt(track, wpt); - wpt = NULL; + ignr_xml_error((track == NULL) || (wpt == NULL)); + + track_add_wpt(track, wpt); + wpt = NULL; } static void -ignr_etape_pos(const char *args, const char **attrv) +ignr_etape_pos(const char* args, const char** attrv) { - ignr_xml_error((wpt == NULL) || (args == NULL)); + ignr_xml_error((wpt == NULL) || (args == NULL)); - if (2 != sscanf(args, "%lf,%lf", &wpt->latitude, &wpt->longitude)) - fatal(MYNAME ": Invalid coordinates \"%s\"!\n", args); + if (2 != sscanf(args, "%lf,%lf", &wpt->latitude, &wpt->longitude)) { + fatal(MYNAME ": Invalid coordinates \"%s\"!\n", args); + } } static void -ignr_etape_alt(const char *args, const char **attrv) +ignr_etape_alt(const char* args, const char** attrv) { - ignr_xml_error((wpt == NULL)); - if (args == NULL) return; - - if (1 != sscanf(args, "%lf", &wpt->altitude)) - fatal(MYNAME ": Invalid altitude \"%s\"!\n", args); + ignr_xml_error((wpt == NULL)); + if (args == NULL) { + return; + } + + if (1 != sscanf(args, "%lf", &wpt->altitude)) { + fatal(MYNAME ": Invalid altitude \"%s\"!\n", args); + } } /* callbacks registered in ignr_vecs */ -static void -ignr_rd_init(const char *fname) +static void +ignr_rd_init(const char* fname) { - xml_init(fname, ignr_xml_map, NULL); - wpt = NULL; - track = NULL; + xml_init(fname, ignr_xml_map, NULL); + wpt = NULL; + track = NULL; } -static void +static void ignr_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } -static void +static void ignr_read(void) { - xml_read(); + xml_read(); } #endif @@ -191,96 +195,101 @@ ignr_read(void) /* callbacks registered in ignr_vecs */ -static void -ignr_rw_init(const char *fname) +static void +ignr_rw_init(const char* fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } -static void +static void ignr_rw_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void -ignr_write_track_hdr(const route_head *track) +ignr_write_track_hdr(const route_head* track) { - track_num++; - - if (track_num != track_index) return; - - gbfprintf(fout, "\t\n"); - gbfprintf(fout, "\t\t%d\n", track->rte_waypt_ct); - if (track->rte_desc != NULL) - gbfprintf(fout, "\t\t%s\n", track->rte_desc); - gbfprintf(fout, "\t\n"); + track_num++; + + if (track_num != track_index) { + return; + } + + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%d\n", track->rte_waypt_ct); + if (track->rte_desc != NULL) { + gbfprintf(fout, "\t\t%s\n", track->rte_desc); + } + gbfprintf(fout, "\t\n"); } static void -ignr_write_track_trl(const route_head *track) +ignr_write_track_trl(const route_head* track) { } static void -ignr_write_waypt(const waypoint *wpt) +ignr_write_waypt(const waypoint* wpt) { - if (track_num != track_index) return; - - gbfprintf(fout, "\t\n"); - gbfprintf(fout, "\t\t%3.6f,%3.6f\n", wpt->latitude, wpt->longitude); - if (wpt->altitude != unknown_alt) - gbfprintf(fout, "\t\t%3.6f\n", wpt->altitude); - gbfprintf(fout, "\t\n"); + if (track_num != track_index) { + return; + } + + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%3.6f,%3.6f\n", wpt->latitude, wpt->longitude); + if (wpt->altitude != unknown_alt) { + gbfprintf(fout, "\t\t%3.6f\n", wpt->altitude); + } + gbfprintf(fout, "\t\n"); } -static void +static void ignr_write(void) { - time_t now; - struct tm tm; - char buff[32]; - - if (index_opt != NULL) - { - track_index = atoi(index_opt); - if ((track_index < 1) || (track_index > (int) track_count())) - fatal(MYNAME ": Invalid track index %d (we have currently %d track(s))!\n", - track_index, track_count()); - } - else - track_index = 1; - track_num = 0; - - now = current_time(); - tm = *localtime(&now); - - gbfprintf(fout, "\n"); - gbfprintf(fout, "\n"); - gbfprintf(fout, "\t\n"); - gbfprintf(fout, "\t\t1.1\n"); - gbfprintf(fout, "\t\tIHA03AA\n"); - - strftime(buff, sizeof(buff), "%d/%m/%Y", &tm); - gbfprintf(fout, "\t\t%s\n", buff); - strftime(buff, sizeof(buff), "%H:%M:%S", &tm); - gbfprintf(fout, "\t\t%s\n", buff); - - gbfprintf(fout, "\t\n"); - track_disp_all(ignr_write_track_hdr, ignr_write_track_trl, ignr_write_waypt); - gbfprintf(fout, "\n"); + time_t now; + struct tm tm; + char buff[32]; + + if (index_opt != NULL) { + track_index = atoi(index_opt); + if ((track_index < 1) || (track_index > (int) track_count())) + fatal(MYNAME ": Invalid track index %d (we have currently %d track(s))!\n", + track_index, track_count()); + } else { + track_index = 1; + } + track_num = 0; + + now = current_time(); + tm = *localtime(&now); + + gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t1.1\n"); + gbfprintf(fout, "\t\tIHA03AA\n"); + + strftime(buff, sizeof(buff), "%d/%m/%Y", &tm); + gbfprintf(fout, "\t\t%s\n", buff); + strftime(buff, sizeof(buff), "%H:%M:%S", &tm); + gbfprintf(fout, "\t\t%s\n", buff); + + gbfprintf(fout, "\t\n"); + track_disp_all(ignr_write_track_hdr, ignr_write_track_trl, ignr_write_waypt); + gbfprintf(fout, "\n"); } ff_vecs_t ignr_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, - ignr_rd_init, - ignr_rw_init, - ignr_rd_deinit, - ignr_rw_deinit, - ignr_read, - ignr_write, - NULL, - ignr_args, - CET_CHARSET_MS_ANSI, 1 + ff_type_file, + { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none }, + ignr_rd_init, + ignr_rw_init, + ignr_rd_deinit, + ignr_rw_deinit, + ignr_read, + ignr_write, + NULL, + ignr_args, + CET_CHARSET_MS_ANSI, 1 }; diff --git a/gpsbabel/igo8.c b/gpsbabel/igo8.c index 6bbcd4483..61c72bbdb 100644 --- a/gpsbabel/igo8.c +++ b/gpsbabel/igo8.c @@ -29,14 +29,14 @@ | ID Block (20B) | | |------------------------------| | | | | - | | + | | | | H | | e | | a | Description Block (256B) | d | | e | | r - | | + | | | | | | | | | | | @@ -54,7 +54,7 @@ ID Block: defined by igo8_id_block Description Block: Two null-terminated unicode 2 strings. - The first is the title of the track, + The first is the title of the track, the second is the description. Information Block: defined by igo8_information_block Waypoint: defined by igo8_point @@ -71,32 +71,29 @@ #define IGO8_HEADER_SIZE (sizeof(igo8_id_block) + 256) #define MYNAME "IGO8" -typedef struct _igo8_id_block -{ - gbuint32 unknown_1; - gbuint32 unknown_2; - gbuint32 unknown_3; - gbuint32 track_number; - gbuint32 unknown_4; +typedef struct _igo8_id_block { + gbuint32 unknown_1; + gbuint32 unknown_2; + gbuint32 unknown_3; + gbuint32 track_number; + gbuint32 unknown_4; } igo8_id_block, *p_igo8_id_block; -typedef struct _igo8_information_block -{ - gbuint32 start_time; // In Unix time - gbuint32 zero; // Doesn't appear to serve a purpose - gbuint32 total_file_size; // In bytes +typedef struct _igo8_information_block { + gbuint32 start_time; // In Unix time + gbuint32 zero; // Doesn't appear to serve a purpose + gbuint32 total_file_size; // In bytes } igo8_information_block, *p_igo8_information_block; -typedef struct _igo8_point -{ - gbuint32 unix_time; - gbuint32 lon; - gbuint32 lat; +typedef struct _igo8_point { + gbuint32 unix_time; + gbuint32 lon; + gbuint32 lat; } igo8_point, *p_igo8_point; // Files -static gbfile *igo8_file_in; -static gbfile *igo8_file_out; +static gbfile* igo8_file_in; +static gbfile* igo8_file_out; // Options static char* igo8_option_tracknum = NULL; @@ -110,182 +107,170 @@ static int in_point_count; // Exported options list static arglist_t igo8_options[] = { - { "tracknum", &igo8_option_tracknum, "Track identification number", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - { "title", &igo8_option_title, "Track title", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "description", &igo8_option_description, "Track description", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { "tracknum", &igo8_option_tracknum, "Track identification number", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + { "title", &igo8_option_title, "Track title", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "description", &igo8_option_description, "Track description", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; // Sanity check static void igo8_check_type_sizes() { - if (sizeof(igo8_point) != 12) - { - fatal(MYNAME ": igo8_point is %ld bytes instead of the required 12.\n", - (long) sizeof(igo8_point)); - } - - if (sizeof(igo8_information_block) != 12) - { - fatal(MYNAME ": igo8_information_block is %ld bytes instead of the required 12.\n", - (long) sizeof(igo8_information_block)); - } - - if (sizeof(igo8_id_block) != 20) - { - fatal(MYNAME ": igo8_id_block is %ld bytes instead of the required 20.\n", - (long) sizeof(igo8_id_block)); - } + if (sizeof(igo8_point) != 12) { + fatal(MYNAME ": igo8_point is %ld bytes instead of the required 12.\n", + (long) sizeof(igo8_point)); + } + + if (sizeof(igo8_information_block) != 12) { + fatal(MYNAME ": igo8_information_block is %ld bytes instead of the required 12.\n", + (long) sizeof(igo8_information_block)); + } + + if (sizeof(igo8_id_block) != 20) { + fatal(MYNAME ": igo8_id_block is %ld bytes instead of the required 20.\n", + (long) sizeof(igo8_id_block)); + } } // Reader initialization callback -static void igo8_read_init(const char *fname) +static void igo8_read_init(const char* fname) { - igo8_file_in = gbfopen_le(fname, "rb", MYNAME); - - // Make sure that we are in the environment we expect and require - igo8_check_type_sizes(); - - // Seek past the header and most of the Information Block. Read - // the last word for trackpoint count since latest igo8 seems to - // zero-pad the files. - gbfseek(igo8_file_in, IGO8_HEADER_SIZE + sizeof(igo8_information_block) - 4, SEEK_SET); - in_point_count = (gbfgetint32(igo8_file_in) - IGO8_HEADER_SIZE - - sizeof(igo8_information_block)) / sizeof(igo8_point); + igo8_file_in = gbfopen_le(fname, "rb", MYNAME); + + // Make sure that we are in the environment we expect and require + igo8_check_type_sizes(); + + // Seek past the header and most of the Information Block. Read + // the last word for trackpoint count since latest igo8 seems to + // zero-pad the files. + gbfseek(igo8_file_in, IGO8_HEADER_SIZE + sizeof(igo8_information_block) - 4, SEEK_SET); + in_point_count = (gbfgetint32(igo8_file_in) - IGO8_HEADER_SIZE - + sizeof(igo8_information_block)) / sizeof(igo8_point); } // Reader callback static void igo8_read(void) { - waypoint *wpt_tmp; - route_head *track_head; - igo8_point point; + waypoint* wpt_tmp; + route_head* track_head; + igo8_point point; - track_head = route_head_alloc(); - track_add_head(track_head); + track_head = route_head_alloc(); + track_add_head(track_head); - while (in_point_count && - gbfread(&point, sizeof(point), 1, igo8_file_in) > 0) { - in_point_count--; - wpt_tmp = waypt_new(); + while (in_point_count && + gbfread(&point, sizeof(point), 1, igo8_file_in) > 0) { + in_point_count--; + wpt_tmp = waypt_new(); - wpt_tmp->latitude = le_read32(&point.lat) / (double)0x800000; - wpt_tmp->longitude = le_read32(&point.lon) / (double)0x800000; - wpt_tmp->creation_time = le_read32(&point.unix_time); + wpt_tmp->latitude = le_read32(&point.lat) / (double)0x800000; + wpt_tmp->longitude = le_read32(&point.lon) / (double)0x800000; + wpt_tmp->creation_time = le_read32(&point.unix_time); - track_add_wpt(track_head, wpt_tmp); - } + track_add_wpt(track_head, wpt_tmp); + } } // Reader close callback static void igo8_read_deinit(void) { - gbfclose(igo8_file_in); + gbfclose(igo8_file_in); } // Writer initialize callback -static void igo8_write_init(const char *fname) +static void igo8_write_init(const char* fname) { - igo8_file_out = gbfopen_le(fname, "wb", MYNAME); + igo8_file_out = gbfopen_le(fname, "wb", MYNAME); - igo8_check_type_sizes(); + igo8_check_type_sizes(); - invented_time = 1; - point_count = 0; + invented_time = 1; + point_count = 0; } // Writer close callback static void igo8_write_deinit(void) { - gbuint32 normalized_file_size; + gbuint32 normalized_file_size; - // Seek to the start of the third long in the Information Block, this is - // where we will write out the total size of the file. - gbfseek(igo8_file_out, IGO8_HEADER_SIZE + sizeof(gbuint32)*2, SEEK_SET); + // Seek to the start of the third long in the Information Block, this is + // where we will write out the total size of the file. + gbfseek(igo8_file_out, IGO8_HEADER_SIZE + sizeof(gbuint32)*2, SEEK_SET); - // The total size of the file is the number of points written + Information block + Header - le_write32(&normalized_file_size, sizeof(igo8_point)*(point_count) + sizeof(igo8_information_block) + IGO8_HEADER_SIZE); + // The total size of the file is the number of points written + Information block + Header + le_write32(&normalized_file_size, sizeof(igo8_point)*(point_count) + sizeof(igo8_information_block) + IGO8_HEADER_SIZE); - // Write the size - gbfwrite(&normalized_file_size, sizeof(normalized_file_size), 1, igo8_file_out); + // Write the size + gbfwrite(&normalized_file_size, sizeof(normalized_file_size), 1, igo8_file_out); - gbfclose(igo8_file_out); + gbfclose(igo8_file_out); } // Write point callback -static void write_igo8_track_point(const waypoint *wpt) +static void write_igo8_track_point(const waypoint* wpt) { - igo8_point point; - - memset(&point, 0, sizeof(point)); - - // iGo8 appears to expect a time, if one isn't provided - // then we shall make our own, where each point is one - // second apart. - if (wpt->creation_time == 0) - { - le_write32(&point.unix_time, invented_time++); - } - else - { - le_write32(&point.unix_time, wpt->creation_time); - } - - // Write the first part of the Information Block, the start time - if (point_count == 0) - { - gbfwrite(&point, sizeof(point), 1, igo8_file_out); - } - - le_write32(&point.lon, FLOAT_TO_INT(wpt->longitude * 0x800000)); - le_write32(&point.lat, FLOAT_TO_INT(wpt->latitude * 0x800000)); - - gbfwrite(&point, sizeof(point), 1, igo8_file_out); - - // Count the number of point printed, we will use this at the end to - // finish filling out the Information Block. - point_count++; + igo8_point point; + + memset(&point, 0, sizeof(point)); + + // iGo8 appears to expect a time, if one isn't provided + // then we shall make our own, where each point is one + // second apart. + if (wpt->creation_time == 0) { + le_write32(&point.unix_time, invented_time++); + } else { + le_write32(&point.unix_time, wpt->creation_time); + } + + // Write the first part of the Information Block, the start time + if (point_count == 0) { + gbfwrite(&point, sizeof(point), 1, igo8_file_out); + } + + le_write32(&point.lon, FLOAT_TO_INT(wpt->longitude * 0x800000)); + le_write32(&point.lat, FLOAT_TO_INT(wpt->latitude * 0x800000)); + + gbfwrite(&point, sizeof(point), 1, igo8_file_out); + + // Count the number of point printed, we will use this at the end to + // finish filling out the Information Block. + point_count++; } // Write src unicode str to the dst cstring using unicode characters // All lengths are in bytes -unsigned int print_unicode(char *dst, const unsigned int dst_max_length, short *src, unsigned int src_len) +unsigned int print_unicode(char* dst, const unsigned int dst_max_length, short* src, unsigned int src_len) { - // Check to see what length we were passed, if the length doesn't include the null - // then we make it include the null - if (src[(src_len/2) - 1] != 0) - { - // If the last character isn't null check the next one - if (src[(src_len/2)] != 0) - { - // If the next character also inst' null, make it null - src[(src_len/2)] = 0; - } - else - { - // The next character is null, adjust the total length of the str to account for this - src_len += 2; - } - } - - // Make sure we fit in our dst size - if (src_len > dst_max_length) - { - src_len = dst_max_length; - src[(src_len/2) - 1] = 0; // Make sure we keep that terminating null around - } - - // Copy the str - memcpy(dst, src, src_len); - - return src_len; + // Check to see what length we were passed, if the length doesn't include the null + // then we make it include the null + if (src[(src_len/2) - 1] != 0) { + // If the last character isn't null check the next one + if (src[(src_len/2)] != 0) { + // If the next character also inst' null, make it null + src[(src_len/2)] = 0; + } else { + // The next character is null, adjust the total length of the str to account for this + src_len += 2; + } + } + + // Make sure we fit in our dst size + if (src_len > dst_max_length) { + src_len = dst_max_length; + src[(src_len/2) - 1] = 0; // Make sure we keep that terminating null around + } + + // Copy the str + memcpy(dst, src, src_len); + + return src_len; } // This is a sort of hacked together ascii-> unicode 2 converter. I have no idea // if iGo8 even supports real unicode 2, but is does look like it as every ascii // character is a short with the ascii character as the least significant 7 bits // -// Please replace this with a much more filled out and correct version if you see +// Please replace this with a much more filled out and correct version if you see // fit. /* 2008/06/24, O.K.: Use CET library for ascii-> unicode 2 converter */ @@ -293,99 +278,94 @@ unsigned int print_unicode(char *dst, const unsigned int dst_max_length, short * // string, validate that the use of the CET library provides // conmforming output, remove my old junk converter code. -unsigned int ascii_to_unicode_2(char *dst, const unsigned int dst_max_length, const char *src) +unsigned int ascii_to_unicode_2(char* dst, const unsigned int dst_max_length, const char* src) { - short *unicode; - int len; + short* unicode; + int len; + + unicode = cet_str_any_to_uni(src, &cet_cs_vec_ansi_x3_4_1968, &len); - unicode = cet_str_any_to_uni(src, &cet_cs_vec_ansi_x3_4_1968, &len); + len *= 2; /* real size in bytes */ + len = print_unicode(dst, dst_max_length, unicode, len); - len *= 2; /* real size in bytes */ - len = print_unicode(dst, dst_max_length, unicode, len); + xfree(unicode); - xfree(unicode); - - return len; + return len; } void write_header() { - char header[IGO8_HEADER_SIZE] = {'\0'}; - igo8_id_block tmp_id_block; - p_igo8_id_block id_block = (p_igo8_id_block)header; - gbuint32 current_position = 0; - const char* title = "Title"; - const char* description = "Description"; - - // These values seem to be constant for me, but I have no idea what they are. - tmp_id_block.unknown_1 = 0x0000029B; - tmp_id_block.unknown_2 = 0x000003E7; - tmp_id_block.unknown_3 = 0x00000003; - - // This appears to be a unique number that IDs the track. - // It is mono-incrementing and offset by 2 above the track number. - // e.g. "Track 1" --> track_number = 3 - // XXX - Dustin: My guess is that this number is used as the key for the track color, if - // XXX - Dustin: multiple tracks have the same color they will be colored the same, just - // XXX - Dustin: a guess though. - if (igo8_option_tracknum) - { - tmp_id_block.track_number = atoi(igo8_option_tracknum); - } - else - { - tmp_id_block.track_number = 0x00000010; - } - tmp_id_block.unknown_4 = 0x00000001; - - // Byte swap out to the header buffer. - le_write32(&id_block->unknown_1, tmp_id_block.unknown_1); - le_write32(&id_block->unknown_2, tmp_id_block.unknown_2); - le_write32(&id_block->unknown_3, tmp_id_block.unknown_3); - le_write32(&id_block->track_number, tmp_id_block.track_number); - le_write32(&id_block->unknown_4, tmp_id_block.unknown_4); - - // Move past the ID block, we have just filled it. - current_position += sizeof(*id_block); - - // Set the title of the track - // Note: we shorten the length of the potential title by 2 because we need to leave at - // least enough room to have a null for the description string that follows it. - if (igo8_option_title) - { - title = igo8_option_title; - } - current_position += ascii_to_unicode_2((char*)(header+current_position), IGO8_HEADER_SIZE - current_position - 2, title); - - // Set the description of the track - if (igo8_option_description) - { - description = igo8_option_description; - } - current_position += ascii_to_unicode_2((char*)(header+current_position), IGO8_HEADER_SIZE - current_position, description); - - gbfwrite(&header, IGO8_HEADER_SIZE, 1, igo8_file_out); + char header[IGO8_HEADER_SIZE] = {'\0'}; + igo8_id_block tmp_id_block; + p_igo8_id_block id_block = (p_igo8_id_block)header; + gbuint32 current_position = 0; + const char* title = "Title"; + const char* description = "Description"; + + // These values seem to be constant for me, but I have no idea what they are. + tmp_id_block.unknown_1 = 0x0000029B; + tmp_id_block.unknown_2 = 0x000003E7; + tmp_id_block.unknown_3 = 0x00000003; + + // This appears to be a unique number that IDs the track. + // It is mono-incrementing and offset by 2 above the track number. + // e.g. "Track 1" --> track_number = 3 + // XXX - Dustin: My guess is that this number is used as the key for the track color, if + // XXX - Dustin: multiple tracks have the same color they will be colored the same, just + // XXX - Dustin: a guess though. + if (igo8_option_tracknum) { + tmp_id_block.track_number = atoi(igo8_option_tracknum); + } else { + tmp_id_block.track_number = 0x00000010; + } + tmp_id_block.unknown_4 = 0x00000001; + + // Byte swap out to the header buffer. + le_write32(&id_block->unknown_1, tmp_id_block.unknown_1); + le_write32(&id_block->unknown_2, tmp_id_block.unknown_2); + le_write32(&id_block->unknown_3, tmp_id_block.unknown_3); + le_write32(&id_block->track_number, tmp_id_block.track_number); + le_write32(&id_block->unknown_4, tmp_id_block.unknown_4); + + // Move past the ID block, we have just filled it. + current_position += sizeof(*id_block); + + // Set the title of the track + // Note: we shorten the length of the potential title by 2 because we need to leave at + // least enough room to have a null for the description string that follows it. + if (igo8_option_title) { + title = igo8_option_title; + } + current_position += ascii_to_unicode_2((char*)(header+current_position), IGO8_HEADER_SIZE - current_position - 2, title); + + // Set the description of the track + if (igo8_option_description) { + description = igo8_option_description; + } + current_position += ascii_to_unicode_2((char*)(header+current_position), IGO8_HEADER_SIZE - current_position, description); + + gbfwrite(&header, IGO8_HEADER_SIZE, 1, igo8_file_out); } // Writer callback static void igo8_write(void) { - write_header(); - track_disp_all(NULL, NULL, write_igo8_track_point); + write_header(); + track_disp_all(NULL, NULL, write_igo8_track_point); } // Callback definitions ff_vecs_t igo8_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, - igo8_read_init, - igo8_write_init, - igo8_read_deinit, - igo8_write_deinit, - igo8_read, - igo8_write, - NULL, - igo8_options, - CET_CHARSET_UTF8, - 1 + ff_type_file, + { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none }, + igo8_read_init, + igo8_write_init, + igo8_read_deinit, + igo8_write_deinit, + igo8_read, + igo8_write, + NULL, + igo8_options, + CET_CHARSET_UTF8, + 1 }; diff --git a/gpsbabel/ik3d.c b/gpsbabel/ik3d.c index 9a5c50c45..0e46ff51f 100644 --- a/gpsbabel/ik3d.c +++ b/gpsbabel/ik3d.c @@ -1,4 +1,4 @@ -/* +/* Support for "MagicMaps" project files (.ikt) @@ -23,20 +23,19 @@ #include "defs.h" #include "xmlgeneric.h" -static arglist_t ikt_args[] = -{ - ARG_TERMINATOR +static arglist_t ikt_args[] = { + ARG_TERMINATOR }; #define MYNAME "ikt" -static char *name, *text; +static char* name, *text; #if ! HAVE_LIBEXPAT void -ikt_rd_init(const char *fname) +ikt_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); } void @@ -51,8 +50,8 @@ ikt_object_end(void) #else -static route_head *track; -static waypoint *waypt; +static route_head* track; +static waypoint* waypt; static xg_callback iktobj_waypt, iktobj_type, iktobj_name, iktobj_trkpt, iktobj_text; @@ -61,142 +60,151 @@ static xg_callback iktobj_waypt, iktobj_type, iktobj_name, iktobj_trkpt, iktobj_ /* Here we are working with wildcards in the tag list. Please ensure that the longest entries comes first */ -static +static xg_tag_mapping ikt_map[] = { - { iktobj_trkpt, cb_start, IKTOBJ "_*/PathPoints/Point_*/GeoPosition" }, - { iktobj_type, cb_cdata, IKTOBJ "_*/GeoObjectType" }, - { iktobj_waypt, cb_start, IKTOBJ "_*/GeoPosition" }, - { iktobj_name, cb_cdata, IKTOBJ "_*/Name" }, - { iktobj_text, cb_cdata, IKTOBJ "_*/POIDrawable2D/Text" }, - { NULL, 0, NULL } + { iktobj_trkpt, cb_start, IKTOBJ "_*/PathPoints/Point_*/GeoPosition" }, + { iktobj_type, cb_cdata, IKTOBJ "_*/GeoObjectType" }, + { iktobj_waypt, cb_start, IKTOBJ "_*/GeoPosition" }, + { iktobj_name, cb_cdata, IKTOBJ "_*/Name" }, + { iktobj_text, cb_cdata, IKTOBJ "_*/POIDrawable2D/Text" }, + { NULL, (xg_cb_type)0, NULL } }; static void ikt_object_end(void) { - if (track) { - track->rte_name = name; - track_add_head(track); - name = NULL; - } - else if (waypt) { - waypt->shortname = name; - waypt->description = text; - waypt_add(waypt); - name = NULL; - text = NULL; - } - if (name) { - xfree(name); - name = NULL; - } - if (text) { - xfree(text); - text = NULL; - } - track = NULL; - waypt = NULL; + if (track) { + track->rte_name = name; + track_add_head(track); + name = NULL; + } else if (waypt) { + waypt->shortname = name; + waypt->description = text; + waypt_add(waypt); + name = NULL; + text = NULL; + } + if (name) { + xfree(name); + name = NULL; + } + if (text) { + xfree(text); + text = NULL; + } + track = NULL; + waypt = NULL; } -static void -iktobj_waypt(const char *args, const char **attrv) +static void +iktobj_waypt(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - - while (*avp) { - if (strcmp(avp[0], "X") == 0) waypt->longitude = atof(avp[1]); - else if (strcmp(avp[0], "Y") == 0) waypt->latitude = atof(avp[1]); - avp+=2; - } + const char** avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "X") == 0) { + waypt->longitude = atof(avp[1]); + } else if (strcmp(avp[0], "Y") == 0) { + waypt->latitude = atof(avp[1]); + } + avp+=2; + } } static void -iktobj_trkpt(const char *args, const char **attrv) +iktobj_trkpt(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - - waypt = waypt_new(); - while (*avp) { - if (strcmp(avp[0], "X") == 0) waypt->longitude = atof(avp[1]); - else if (strcmp(avp[0], "Y") == 0) waypt->latitude = atof(avp[1]); - avp+=2; - } - track_add_wpt(track, waypt); - waypt = NULL; + const char** avp = &attrv[0]; + + waypt = waypt_new(); + while (*avp) { + if (strcmp(avp[0], "X") == 0) { + waypt->longitude = atof(avp[1]); + } else if (strcmp(avp[0], "Y") == 0) { + waypt->latitude = atof(avp[1]); + } + avp+=2; + } + track_add_wpt(track, waypt); + waypt = NULL; } -static void -iktobj_name(const char *args, const char **unused) +static void +iktobj_name(const char* args, const char** unused) { - name = xstrdup(args); + name = xstrdup(args); } -static void -iktobj_text(const char *args, const char **unused) +static void +iktobj_text(const char* args, const char** unused) { - text = xstrdup(args); + text = xstrdup(args); } -static void -iktobj_type(const char *args, const char **unused) +static void +iktobj_type(const char* args, const char** unused) { - ikt_object_end(); - - switch(atoi(args)) { - case 0: - waypt = waypt_new(); - break; - case 1: - track = route_head_alloc(); - break; - default: - fatal(MYNAME ": Unknown object type %s!\n", args); - } + ikt_object_end(); + + switch (atoi(args)) { + case 0: + waypt = waypt_new(); + break; + case 1: + track = route_head_alloc(); + break; + default: + fatal(MYNAME ": Unknown object type %s!\n", args); + } } -static void -ikt_rd_init(const char *fname) +static void +ikt_rd_init(const char* fname) { - xml_init(fname, ikt_map, NULL); - - track = NULL; - waypt = NULL; - name = NULL; - text = NULL; + xml_init(fname, ikt_map, NULL); + + track = NULL; + waypt = NULL; + name = NULL; + text = NULL; } -static void +static void ikt_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void ikt_rd_deinit(void) { - ikt_object_end(); - if (name) xfree(name); - if (text) xfree(text); - - xml_deinit(); + ikt_object_end(); + if (name) { + xfree(name); + } + if (text) { + xfree(text); + } + + xml_deinit(); } ff_vecs_t ik3d_vecs = { - ff_type_file, - { - ff_cap_read, /* waypoints */ - ff_cap_read, /* tracks */ - ff_cap_none /* routes */ - }, - ikt_rd_init, - NULL, - ikt_rd_deinit, - NULL, - ikt_read, - NULL, - NULL, - ikt_args, - CET_CHARSET_UTF8, 1 + ff_type_file, + { + ff_cap_read, /* waypoints */ + ff_cap_read, /* tracks */ + ff_cap_none /* routes */ + }, + ikt_rd_init, + NULL, + ikt_rd_deinit, + NULL, + ikt_read, + NULL, + NULL, + ikt_args, + CET_CHARSET_UTF8, 1 }; diff --git a/gpsbabel/inifile.c b/gpsbabel/inifile.c index bc8ed9148..d63216b29 100644 --- a/gpsbabel/inifile.c +++ b/gpsbabel/inifile.c @@ -1,6 +1,6 @@ /* Library for inifile like data files. - + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -28,19 +28,17 @@ #define MYNAME "inifile" -typedef struct inifile_entry_s -{ - queue Q; - char *key; - char *val; +typedef struct inifile_entry_s { + queue Q; + char* key; + char* val; } inifile_entry_t; -typedef struct inifile_section_s -{ - queue Q; - char *name; - int ientries; - queue entries; +typedef struct inifile_section_s { + queue Q; + char* name; + int ientries; + queue entries; } inifile_section_t; /* internal procedures */ @@ -51,184 +49,195 @@ typedef struct inifile_section_s #define GPSBABEL_INIFILE "gpsbabel.ini" /* Remember the filename we used so we can include it in errors. */ -char *gbinipathname; +char* gbinipathname; -static char * -find_gpsbabel_inifile(const char *path) /* can be empty or NULL */ +static char* +find_gpsbabel_inifile(const char* path) /* can be empty or NULL */ { - FILE *test; - char *buff; - int len; - - if (path == NULL) return NULL; - - len = strlen(path); - buff = xmalloc(len + 1 + strlen(GPSBABEL_INIFILE) + 1); - strcpy(buff, path); - if (len > 0) { - char test = buff[len - 1]; + FILE* test; + char* buff; + int len; + + if (path == NULL) { + return NULL; + } + + len = strlen(path); + buff = (char*) xmalloc(len + 1 + strlen(GPSBABEL_INIFILE) + 1); + strcpy(buff, path); + if (len > 0) { + char test = buff[len - 1]; #ifdef __WIN32__ - if ((test != '\\') && (test != ':')) - strcat(buff, "\\"); + if ((test != '\\') && (test != ':')) { + strcat(buff, "\\"); + } #else - if (test != '/') - strcat(buff, "/"); + if (test != '/') { + strcat(buff, "/"); + } #endif - } - strcat(buff, GPSBABEL_INIFILE); - test = fopen(buff, "rb"); - if (test) { - fclose(test); - return buff; - } - xfree(buff); - return NULL; + } + strcat(buff, GPSBABEL_INIFILE); + test = fopen(buff, "rb"); + if (test) { + fclose(test); + return buff; + } + xfree(buff); + return NULL; } -static gbfile * +static gbfile* open_gpsbabel_inifile(void) { - char *name; - char *envstr; - gbfile *res = NULL; - - envstr = getenv("GPSBABELINI"); - if (envstr != NULL) { - FILE *test; - - test = fopen(envstr, "r"); - if (test != NULL) { - fclose(test); - return gbfopen(envstr, "r", "GPSBabel"); - } - warning("WARNING: GPSBabel-inifile, defined in environment, NOT found!\n"); - return NULL; - } - name = find_gpsbabel_inifile(""); /* PWD */ - if (name == NULL) { + char* name; + char* envstr; + gbfile* res = NULL; + + envstr = getenv("GPSBABELINI"); + if (envstr != NULL) { + FILE* test; + + test = fopen(envstr, "r"); + if (test != NULL) { + fclose(test); + return gbfopen(envstr, "r", "GPSBabel"); + } + warning("WARNING: GPSBabel-inifile, defined in environment, NOT found!\n"); + return NULL; + } + name = find_gpsbabel_inifile(""); /* PWD */ + if (name == NULL) { #ifdef __WIN32__ - name = find_gpsbabel_inifile(getenv("APPDATA")); - if (name == NULL) name = find_gpsbabel_inifile(getenv("WINDIR")); - if (name == NULL) name = find_gpsbabel_inifile(getenv("SYSTEMROOT")); + name = find_gpsbabel_inifile(getenv("APPDATA")); + if (name == NULL) { + name = find_gpsbabel_inifile(getenv("WINDIR")); + } + if (name == NULL) { + name = find_gpsbabel_inifile(getenv("SYSTEMROOT")); + } #else - if ((envstr = getenv("HOME")) != NULL) { - char *path; - - path = xmalloc(strlen(envstr) + 11); - strcpy(path, envstr); - strcat(path, "/.gpsbabel"); - name = find_gpsbabel_inifile(path); - xfree(path); - } - if (name == NULL) name = find_gpsbabel_inifile("/usr/local/etc"); - if (name == NULL) name = find_gpsbabel_inifile("/etc"); + if ((envstr = getenv("HOME")) != NULL) { + char* path; + + path = (char*) xmalloc(strlen(envstr) + 11); + strcpy(path, envstr); + strcat(path, "/.gpsbabel"); + name = find_gpsbabel_inifile(path); + xfree(path); + } + if (name == NULL) { + name = find_gpsbabel_inifile("/usr/local/etc"); + } + if (name == NULL) { + name = find_gpsbabel_inifile("/etc"); + } #endif - } - if (name != NULL) { - res = gbfopen(name, "r", "GPSBabel"); - if (gbinipathname) { - xfree(gbinipathname); - } - gbinipathname = name; - } - return res; + } + if (name != NULL) { + res = gbfopen(name, "r", "GPSBabel"); + if (gbinipathname) { + xfree(gbinipathname); + } + gbinipathname = name; + } + return res; } static void -inifile_load_file(gbfile *fin, inifile_t *inifile, const char *myname) +inifile_load_file(gbfile* fin, inifile_t* inifile, const char* myname) { - char *buf; - inifile_section_t *sec = NULL; - int line = 0; - - while ((buf = gbfgetstr(fin))) - { - char *cin = lrtrim(buf); - - if ((line++ == 0) && fin->unicode) inifile->unicode = 1; - - if (*cin == '\0') continue; /* skip empty lines */ - if ((*cin == '#') || (*cin == ';')) continue; /* skip comments */ - - if (*cin == '[') - { - - char *cend = strchr(++cin, ']'); - - if (cend != NULL) - { - *cend = '\0'; - cin = lrtrim(cin); - } - if ((*cin == '\0') || (cend == NULL)) - fatal("%s: invalid section header '%s' in '%s'.\n", myname, cin, gbinipathname); - - sec = (inifile_section_t *) xcalloc(1, sizeof(*sec)); - - sec->name = xstrdup(cin); - QUEUE_INIT(&sec->entries); - ENQUEUE_TAIL(&inifile->secs, &sec->Q); - inifile->isecs++; - } - else - { - char *cx; - inifile_entry_t *entry; - - if (sec == NULL) - fatal("%s: missing section header in '%s'.\n", myname,gbinipathname); - - entry = (inifile_entry_t *) xcalloc(1, sizeof(*entry)); - ENQUEUE_TAIL(&sec->entries, &entry->Q); - sec->ientries++; - - cx = strchr(cin, '='); - if (cx != NULL) - { - *cx = '\0'; - cin = lrtrim(cin); - } - - entry->key = xstrdup(cin); - - if (cx != NULL) - { - cx = lrtrim(++cx); - entry->val = xstrdup(cx); - } - else - entry->val = xstrdup(""); - } - } + char* buf; + inifile_section_t* sec = NULL; + int line = 0; + + while ((buf = gbfgetstr(fin))) { + char* cin = lrtrim(buf); + + if ((line++ == 0) && fin->unicode) { + inifile->unicode = 1; + } + + if (*cin == '\0') { + continue; /* skip empty lines */ + } + if ((*cin == '#') || (*cin == ';')) { + continue; /* skip comments */ + } + + if (*cin == '[') { + + char* cend = strchr(++cin, ']'); + + if (cend != NULL) { + *cend = '\0'; + cin = lrtrim(cin); + } + if ((*cin == '\0') || (cend == NULL)) { + fatal("%s: invalid section header '%s' in '%s'.\n", myname, cin, gbinipathname); + } + + sec = (inifile_section_t*) xcalloc(1, sizeof(*sec)); + + sec->name = xstrdup(cin); + QUEUE_INIT(&sec->entries); + ENQUEUE_TAIL(&inifile->secs, &sec->Q); + inifile->isecs++; + } else { + char* cx; + inifile_entry_t* entry; + + if (sec == NULL) { + fatal("%s: missing section header in '%s'.\n", myname,gbinipathname); + } + + entry = (inifile_entry_t*) xcalloc(1, sizeof(*entry)); + ENQUEUE_TAIL(&sec->entries, &entry->Q); + sec->ientries++; + + cx = strchr(cin, '='); + if (cx != NULL) { + *cx = '\0'; + cin = lrtrim(cin); + } + + entry->key = xstrdup(cin); + + if (cx != NULL) { + cx = lrtrim(++cx); + entry->val = xstrdup(cx); + } else { + entry->val = xstrdup(""); + } + } + } } -static char * -inifile_find_value(const inifile_t *inifile, const char *sec_name, const char *key) +static char* +inifile_find_value(const inifile_t* inifile, const char* sec_name, const char* key) { - queue *elem, *tmp; - - if (inifile == NULL) return NULL; - - QUEUE_FOR_EACH(&inifile->secs, elem, tmp) - { - inifile_section_t *sec = (inifile_section_t *) elem; - - if (case_ignore_strcmp(sec->name, sec_name) == 0) - { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&sec->entries, elem, tmp) - { - inifile_entry_t *entry = (inifile_entry_t *) elem; - - if (case_ignore_strcmp(entry->key, key) == 0) - { - return entry->val; - } - } - } - } - return NULL; + queue* elem, *tmp; + + if (inifile == NULL) { + return NULL; + } + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { + inifile_section_t* sec = (inifile_section_t*) elem; + + if (case_ignore_strcmp(sec->name, sec_name) == 0) { + queue* elem, *tmp; + + QUEUE_FOR_EACH(&sec->entries, elem, tmp) { + inifile_entry_t* entry = (inifile_entry_t*) elem; + + if (case_ignore_strcmp(entry->key, key) == 0) { + return entry->val; + } + } + } + } + return NULL; } /* public procedures */ @@ -237,112 +246,122 @@ inifile_find_value(const inifile_t *inifile, const char *sec_name, const char *k inifile_init: reads inifile filename into memory myname represents the calling module - + filename == NULL: try to open global gpsbabel.ini */ -inifile_t * -inifile_init(const char *filename, const char *myname) +inifile_t* +inifile_init(const char* filename, const char* myname) { - inifile_t *result; - gbfile *fin = NULL; - - if (filename == NULL) { - fin = open_gpsbabel_inifile(); - if (fin == NULL) return NULL; - } - else fin = gbfopen(filename, "rb", myname); - - result = (inifile_t *) xcalloc(1, sizeof(*result)); - QUEUE_INIT(&result->secs); - inifile_load_file(fin, result, myname); - - gbfclose(fin); - return result; + inifile_t* result; + gbfile* fin = NULL; + + if (filename == NULL) { + fin = open_gpsbabel_inifile(); + if (fin == NULL) { + return NULL; + } + } else { + fin = gbfopen(filename, "rb", myname); + } + + result = (inifile_t*) xcalloc(1, sizeof(*result)); + QUEUE_INIT(&result->secs); + inifile_load_file(fin, result, myname); + + gbfclose(fin); + return result; } void -inifile_done(inifile_t *inifile) +inifile_done(inifile_t* inifile) { - if (inifile == NULL) return; - - if (inifile->isecs > 0) - { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { - inifile_section_t *sec = (inifile_section_t *) elem; - - if (sec->ientries > 0) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&sec->entries, elem, tmp) { - inifile_entry_t *entry = (inifile_entry_t *) elem; - - if (entry->key) xfree(entry->key); - if (entry->val) xfree(entry->val); - dequeue(elem); - xfree(entry); - } - } - dequeue(elem); - if (sec->name) xfree(sec->name); - xfree(sec); - } - xfree(inifile); - } - if (gbinipathname) { - xfree(gbinipathname); - gbinipathname = NULL; - } + if (inifile == NULL) { + return; + } + + if (inifile->isecs > 0) { + queue* elem, *tmp; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { + inifile_section_t* sec = (inifile_section_t*) elem; + + if (sec->ientries > 0) { + queue* elem, *tmp; + + QUEUE_FOR_EACH(&sec->entries, elem, tmp) { + inifile_entry_t* entry = (inifile_entry_t*) elem; + + if (entry->key) { + xfree(entry->key); + } + if (entry->val) { + xfree(entry->val); + } + dequeue(elem); + xfree(entry); + } + } + dequeue(elem); + if (sec->name) { + xfree(sec->name); + } + xfree(sec); + } + xfree(inifile); + } + if (gbinipathname) { + xfree(gbinipathname); + gbinipathname = NULL; + } } -int -inifile_has_section(const inifile_t *inifile, const char *section) +int +inifile_has_section(const inifile_t* inifile, const char* section) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&inifile->secs, elem, tmp) - { - inifile_section_t *sec = (inifile_section_t *) elem; - if (case_ignore_strcmp(sec->name, section) == 0) - return 1; - } - return 0; + queue* elem, *tmp; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { + inifile_section_t* sec = (inifile_section_t*) elem; + if (case_ignore_strcmp(sec->name, section) == 0) { + return 1; + } + } + return 0; } -/* +/* inifile_readstr: returns NULL if not found, otherwise a pointer to the value of key ... - all key values are valid entities until "inifile_done" + all key values are valid entities until "inifile_done" */ -char * -inifile_readstr(const inifile_t *inifile, const char *section, const char *key) +char* +inifile_readstr(const inifile_t* inifile, const char* section, const char* key) { - return inifile_find_value(inifile, section, key); + return inifile_find_value(inifile, section, key); } -/* +/* inifile_readint: on success the value is stored into "*value" and "inifile_readint" returns 1, otherwise inifile_readint returns 0 */ - -int -inifile_readint(const inifile_t *inifile, const char *section, const char *key, int *value) + +int +inifile_readint(const inifile_t* inifile, const char* section, const char* key, int* value) { - char *str; - - str = inifile_find_value(inifile, section, key); - - if (str == NULL) { - return 0; - } - - if (value != NULL) { - *value = atoi(str); - } - return 1; + char* str; + + str = inifile_find_value(inifile, section, key); + + if (str == NULL) { + return 0; + } + + if (value != NULL) { + *value = atoi(str); + } + return 1; } /* @@ -350,15 +369,14 @@ inifile_readint(const inifile_t *inifile, const char *section, const char *key, if found inifile_readint_def returns value of key, otherwise a default value "def" */ -int -inifile_readint_def(const inifile_t *inifile, const char *section, const char *key, const int def) +int +inifile_readint_def(const inifile_t* inifile, const char* section, const char* key, const int def) { - int result; - - if (inifile_readint(inifile, section, key, &result) == 0) { - return def; - } - else { - return result; - } + int result; + + if (inifile_readint(inifile, section, key, &result) == 0) { + return def; + } else { + return result; + } } diff --git a/gpsbabel/inifile.h b/gpsbabel/inifile.h index e7fc8289f..787df7cdb 100644 --- a/gpsbabel/inifile.h +++ b/gpsbabel/inifile.h @@ -23,11 +23,10 @@ #include "defs.h" -typedef struct inifile_s -{ - int isecs; /* number of sections */ - queue secs; /* sections */ - gbuint8 unicode:1; +typedef struct inifile_s { + int isecs; /* number of sections */ + queue secs; /* sections */ + gbuint8 unicode:1; } inifile_t; /* @@ -35,29 +34,29 @@ typedef struct inifile_s reads inifile filename into memory myname represents the calling module */ -inifile_t * inifile_init(const char *filename, const char *myname); -void inifile_done(inifile_t *inifile); +inifile_t* inifile_init(const char* filename, const char* myname); +void inifile_done(inifile_t* inifile); -int inifile_has_section(const inifile_t *inifile, const char *section); +int inifile_has_section(const inifile_t* inifile, const char* section); -/* +/* inifile_readstr: returns NULL if not found, otherwise a pointer to the value of key ... - all key values are valid entities until "inifile_done" + all key values are valid entities until "inifile_done" */ -char *inifile_readstr(const inifile_t *inifile, const char *section, const char *key); +char* inifile_readstr(const inifile_t* inifile, const char* section, const char* key); -/* +/* inifile_readint: on success the value is stored into "*value" and "inifile_readint" returns 1, otherwise inifile_readint returns 0 */ -int inifile_readint(const inifile_t *inifile, const char *section, const char *key, int *value); +int inifile_readint(const inifile_t* inifile, const char* section, const char* key, int* value); /* inifile_readint_def: if found inifile_readint_def returns value of key, otherwise a default value "def" */ -int inifile_readint_def(const inifile_t *inifile, const char *section, const char *key, const int def); +int inifile_readint_def(const inifile_t* inifile, const char* section, const char* key, const int def); #endif diff --git a/gpsbabel/internal_styles.c b/gpsbabel/internal_styles.c index 07ed0a815..ab07970d8 100644 --- a/gpsbabel/internal_styles.c +++ b/gpsbabel/internal_styles.c @@ -207,6 +207,36 @@ static char dna[] = "IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" "IFIELD DESCRIPTION, \"\", \"%s\"\n" +; +static char flysight[] = +"# Format: FlySight\n" +"# Author: LukeH\n" +"# Date: 10/10/10\n" + +"DESCRIPTION FlySight GPS File\n" +"EXTENSION csv\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,\"\n" + +"PROLOGUE time lat lon hMSL velN velE velD hAcc vAcc sAcc gpsFix numSV\n" +"PROLOGUE\n" + +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"IFIELD ISO_TIME, \"\", \"%s\" # Date & time\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" +"IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" +"IFIELD ALT_METERS, \"\", \"%.0f\" # Altitude above MSL (m)\n" +"IFIELD IGNORE, \"\", \"%s\" # Velocity north (m/s)\n" +"IFIELD IGNORE, \"\", \"%s\" # Velocity east (m/s)\n" +"IFIELD IGNORE, \"\", \"%s\" # Velocity down (m/s)\n" +"IFIELD IGNORE, \"\", \"%s\" # Horizontal accuracy (m)\n" +"IFIELD IGNORE, \"\", \"%s\" # Vertical accuracy (m)\n" +"IFIELD IGNORE, \"\", \"%s\" # Speed accuracy (m/s)\n" +"IFIELD GPS_FIX, \"\", \"%s\" # GPS fix type\n" +"IFIELD GPS_SAT, \"\", \"%d\" # Number of satellites used in fix\n" ; static char fugawi[] = "# fugawi XCSV style file\n" @@ -520,6 +550,51 @@ static char iblue747[] = "IFIELD IGNORE,\"\",\"%s\" # SAT INFO\n" "IFIELD PATH_DISTANCE_KM,\"\",\"%f\" # DISTANCE\n" ; +static char iblue757[] = +"# GPSBabel XCSV Style File http://www.gpsbabel.org/htmldoc-development/Styles.html\n" +"# Author: iBlue747csv by Christian Barmala http://www.barmala.de/\n" +"# edited by Anthony Vella to suit the iBlue757 csv format (date format changed)\n" +"# License GNU Public License http://opensource.org/licenses/gpl-license.php\n" + +"DESCRIPTION Data Logger iBlue757 csv\n" +"EXTENSION csv\n" +"# full length csv with all options\n" + +"# FILE LAYOUT DEFINITIIONS:\n" + +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"# BADCHARS COMMA\n" +"# SHORTLEN 16\n" +"# SHORTWHITE 0\n" +"# ENCODING UTF-8\n" +"DATATYPE TRACK\n" +"PROLOGUE INDEX,RCR,DATE,TIME,VALID,LATITUDE,N/S,LONGITUDE,E/W,HEIGHT,SPEED,PDOP,HDOP,VDOP,NSAT,DISTANCE,\n" + + +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + +"IFIELD INDEX,\"1\",\"%d\" # INDEX\n" +"IFIELD CONSTANT,\"T\",\"%s\" # RCR\n" +"IFIELD GMT_TIME,\"\",\"%d/%m/%Y\" # DATE\n" +"IFIELD HMSG_TIME,\"\",\"%02d:%02d:%02d\" # TIME\n" +"IFIELD GPS_FIX,\"\",\"%s\" # VALID # No fix, SPS, DGPS, PPS\n" +"IFIELD LAT_DECIMAL,\"\",\"%f\" # LATITUDE\n" +"IFIELD LAT_DIR,\"\",\"%c\" # N/S\n" +"IFIELD LON_DECIMAL,\"\",\"%f\" # LONGITUDE\n" +"IFIELD LON_DIR,\"\",\"%c\" # E/W\n" +"IFIELD ALT_METERS,\"\",\"%.0f\" # HEIGHT\n" +"IFIELD PATH_SPEED_KPH,\"\",\"%.1f\" # SPEED\n" +"IFIELD IGNORE,\"\",\"%f\" # HEADING\n" +"IFIELD IGNORE,\"\",\"%d\" # DSTA\n" +"IFIELD IGNORE,\"\",\"%f\" # DAGE\n" +"IFIELD GPS_PDOP,\"\",\"%f\" # PDOP\n" +"IFIELD GPS_HDOP,\"\",\"%f\" # HDOP\n" +"IFIELD GPS_VDOP,\"\",\"%f\" # VDOP\n" +"IFIELD GPS_SAT,\"\",\"%d(\" # NSAT USED/VIEW\n" +"IFIELD IGNORE,\"\",\"%s\" # SAT INFO\n" +"IFIELD PATH_DISTANCE_KM,\"\",\"%f\" # DISTANCE\n" +; static char igo2008_poi[] = "# gpsbabel XCSV style file\n" "#\n" @@ -681,6 +756,32 @@ static char kwf2[] = "IFIELD DESCRIPTION, \"\", \"%s\"\n" "IFIELD CONSTANT, \"$\", \"%s\"\n" ; +static char land_air_sea[] = +"# Format: GPS Tracking Key Pro text file\n" +"# Author: Tyler Ritchie\n" +"# Date: 2011.02.04\n" + +"DESCRIPTION GPS Tracking Key Pro text\n" +"EXTENSION txt\n" +"ENCODING LATIN1\n" + +"DATUM WGS 84\n" +"DATATYPE TRACK\n" +"#File layout definitions\n" + +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" + +"# Individual data fields in order of appearance\n" + +"IFIELD LOCAL_TIME,\"\",\"%m-%d-%Y\"\n" +"IFIELD HMSG_TIME,\"\",\"%d:%d:%d\"\n" +"IFIELD LAT_HUMAN_READABLE,\"\",\"%c %d°%d'%f\\\"\"\n" +"IFIELD LON_HUMAN_READABLE,\"\",\"%c %d°%d'%f\\\"\"\n" +"IFIELD PATH_SPEED_MPH,\"\",\"%.1fmph\"\n" +"IFIELD IGNORE,\"\",\"%s\" #This is the bearing data\n" +"IFIELD ALT_FEET,\"\",\"%dft\"\n" +; static char mapconverter[] = "# Format: Mapopolis.com Mapconverter\n" "# Author: Gary Paulson\n" @@ -1263,8 +1364,8 @@ static char xmapwpt[] = "IFIELD IGNORE, \"\", \"%-.31s\"\n" "IFIELD DESCRIPTION, \"\", \"%-.78s\"\n" ; -style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap2006", xmap2006 } , { "xmap", xmap } , { "tomtom_itn_places", tomtom_itn_places } , { "tomtom_itn", tomtom_itn } , { "tomtom_asc", tomtom_asc } , { "tabsep", tabsep } , { "sportsim", sportsim } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "ricoh", ricoh } , { "openoffice", openoffice } , { "nima", nima } , { "navigonwpt", navigonwpt } , { "mxf", mxf } , { "mapconverter", mapconverter } , { "kwf2", kwf2 } , { "ktf2", ktf2 } , { "kompass_wp", kompass_wp } , { "kompass_tk", kompass_tk } , { "igo2008_poi", igo2008_poi } , { "iblue747", iblue747 } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } , {0,0}}; -size_t nstyles = 35; +style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap2006", xmap2006 } , { "xmap", xmap } , { "tomtom_itn_places", tomtom_itn_places } , { "tomtom_itn", tomtom_itn } , { "tomtom_asc", tomtom_asc } , { "tabsep", tabsep } , { "sportsim", sportsim } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "ricoh", ricoh } , { "openoffice", openoffice } , { "nima", nima } , { "navigonwpt", navigonwpt } , { "mxf", mxf } , { "mapconverter", mapconverter } , { "land_air_sea", land_air_sea } , { "kwf2", kwf2 } , { "ktf2", ktf2 } , { "kompass_wp", kompass_wp } , { "kompass_tk", kompass_tk } , { "igo2008_poi", igo2008_poi } , { "iblue757", iblue757 } , { "iblue747", iblue747 } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "flysight", flysight } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } , {0,0}}; +size_t nstyles = 38; #else /* CSVFMTS_ENABLED */ style_vecs_t style_list[] = {{0,0}}; size_t nstyles = 0; diff --git a/gpsbabel/interpolate.c b/gpsbabel/interpolate.c index 776513cc7..a660ca0c0 100644 --- a/gpsbabel/interpolate.c +++ b/gpsbabel/interpolate.c @@ -26,169 +26,175 @@ #if FILTERS_ENABLED #define MYNAME "Interpolate filter" -static char *opt_interval = NULL; +static char* opt_interval = NULL; int interval = 0; -static char *opt_dist = NULL; +static char* opt_dist = NULL; double dist = 0; -static char *opt_route = NULL; +static char* opt_route = NULL; static arglist_t interpfilt_args[] = { - {"time", &opt_interval, "Time interval in seconds", NULL, - ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_INT, - "0", NULL }, - {"distance", &opt_dist, "Distance interval in miles or kilometers", - NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING, - ARG_NOMINMAX }, - {"route", &opt_route, "Interpolate routes instead", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "time", &opt_interval, "Time interval in seconds", NULL, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_INT, + "0", NULL + }, + { + "distance", &opt_dist, "Distance interval in miles or kilometers", + NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + "route", &opt_route, "Interpolate routes instead", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -void +void interpfilt_process(void) { - queue *backuproute = NULL; - queue *elem, *tmp, *elem2, *tmp2; - route_head *rte_new; - int count = 0; - int first = 0; - double lat1 = 0, lon1 = 0; - int time1 = 0; - int timen; - double distn; - double curdist; - double rt1, rn1, rt2, rn2; - - if ( opt_route ) { - route_backup( &count, &backuproute ); - route_flush_all_routes(); - } - else { - track_backup( &count, &backuproute ); - route_flush_all_tracks(); - } - QUEUE_FOR_EACH( backuproute, elem, tmp ) - { - route_head *rte_old = (route_head *)elem; - - rte_new = route_head_alloc(); - rte_new->rte_name = xstrdup( rte_old->rte_name ); - rte_new->rte_desc = xstrdup( rte_old->rte_desc ); - rte_new->fs = fs_chain_copy( rte_old->fs ); - rte_new->rte_num = rte_old->rte_num; - if ( opt_route ) { - route_add_head( rte_new ); - } - else { - track_add_head( rte_new ); - } - first = 1; - QUEUE_FOR_EACH( &rte_old->waypoint_list, elem2, tmp2 ) - { - waypoint *wpt = (waypoint *)elem2; - if ( first ) { - first = 0; - } - else { - if ( opt_interval && - wpt->creation_time - time1 > interval ) { - for ( timen = time1+interval; - timen < wpt->creation_time; - timen += interval ) { - waypoint *wpt_new = waypt_dupe(wpt); - wpt_new->creation_time = timen; - if (wpt_new->shortname) xfree(wpt_new->shortname); - if (wpt_new->description) xfree(wpt_new->description); - wpt_new->shortname = wpt_new->description = NULL; - linepart( lat1, lon1, - wpt->latitude, wpt->longitude, - (double)(timen-time1)/ - (double)(wpt->creation_time-time1), - &wpt_new->latitude, - &wpt_new->longitude ); - if (opt_route) - route_add_wpt( rte_new, wpt_new); - else - track_add_wpt( rte_new, wpt_new); - } - } - else if ( opt_dist ) { - rt1 = RAD(lat1); - rn1 = RAD(lon1); - rt2 = RAD(wpt->latitude); - rn2 = RAD(wpt->longitude); - curdist = gcdist( rt1, rn1, rt2, rn2 ); - curdist = radtomiles(curdist); - if ( curdist > dist ) { - for ( distn = dist; - distn < curdist; - distn += dist ) { - waypoint *wpt_new = waypt_dupe(wpt); - wpt_new->creation_time = distn/curdist* - (wpt->creation_time - time1) + time1; - if (wpt_new->shortname) xfree(wpt_new->shortname); - if (wpt_new->description) xfree(wpt_new->description); - wpt_new->shortname = wpt_new->description = NULL; - linepart( lat1, lon1, - wpt->latitude, wpt->longitude, - distn/curdist, - &wpt_new->latitude, - &wpt_new->longitude ); - if (opt_route) - route_add_wpt( rte_new, wpt_new ); - else - track_add_wpt( rte_new, wpt_new); - } - } - } - } - if ( opt_route ) { - route_add_wpt( rte_new, waypt_dupe(wpt)); - } - else { - track_add_wpt( rte_new, waypt_dupe(wpt)); - } - - lat1 = wpt->latitude; - lon1 = wpt->longitude; - time1 = wpt->creation_time; - } - } - route_flush( backuproute ); - xfree( backuproute ); + queue* backuproute = NULL; + queue* elem, *tmp, *elem2, *tmp2; + route_head* rte_new; + int count = 0; + int first = 0; + double lat1 = 0, lon1 = 0; + int time1 = 0; + int timen; + double distn; + double curdist; + double rt1, rn1, rt2, rn2; + + if (opt_route) { + route_backup(&count, &backuproute); + route_flush_all_routes(); + } else { + track_backup(&count, &backuproute); + route_flush_all_tracks(); + } + QUEUE_FOR_EACH(backuproute, elem, tmp) { + route_head* rte_old = (route_head*)elem; + + rte_new = route_head_alloc(); + rte_new->rte_name = xstrdup(rte_old->rte_name); + rte_new->rte_desc = xstrdup(rte_old->rte_desc); + rte_new->fs = fs_chain_copy(rte_old->fs); + rte_new->rte_num = rte_old->rte_num; + if (opt_route) { + route_add_head(rte_new); + } else { + track_add_head(rte_new); + } + first = 1; + QUEUE_FOR_EACH(&rte_old->waypoint_list, elem2, tmp2) { + waypoint* wpt = (waypoint*)elem2; + if (first) { + first = 0; + } else { + if (opt_interval && + wpt->creation_time - time1 > interval) { + for (timen = time1+interval; + timen < wpt->creation_time; + timen += interval) { + waypoint* wpt_new = waypt_dupe(wpt); + wpt_new->creation_time = timen; + if (wpt_new->shortname) { + xfree(wpt_new->shortname); + } + if (wpt_new->description) { + xfree(wpt_new->description); + } + wpt_new->shortname = wpt_new->description = NULL; + linepart(lat1, lon1, + wpt->latitude, wpt->longitude, + (double)(timen-time1)/ + (double)(wpt->creation_time-time1), + &wpt_new->latitude, + &wpt_new->longitude); + if (opt_route) { + route_add_wpt(rte_new, wpt_new); + } else { + track_add_wpt(rte_new, wpt_new); + } + } + } else if (opt_dist) { + rt1 = RAD(lat1); + rn1 = RAD(lon1); + rt2 = RAD(wpt->latitude); + rn2 = RAD(wpt->longitude); + curdist = gcdist(rt1, rn1, rt2, rn2); + curdist = radtomiles(curdist); + if (curdist > dist) { + for (distn = dist; + distn < curdist; + distn += dist) { + waypoint* wpt_new = waypt_dupe(wpt); + wpt_new->creation_time = distn/curdist* + (wpt->creation_time - time1) + time1; + if (wpt_new->shortname) { + xfree(wpt_new->shortname); + } + if (wpt_new->description) { + xfree(wpt_new->description); + } + wpt_new->shortname = wpt_new->description = NULL; + linepart(lat1, lon1, + wpt->latitude, wpt->longitude, + distn/curdist, + &wpt_new->latitude, + &wpt_new->longitude); + if (opt_route) { + route_add_wpt(rte_new, wpt_new); + } else { + track_add_wpt(rte_new, wpt_new); + } + } + } + } + } + if (opt_route) { + route_add_wpt(rte_new, waypt_dupe(wpt)); + } else { + track_add_wpt(rte_new, waypt_dupe(wpt)); + } + + lat1 = wpt->latitude; + lon1 = wpt->longitude; + time1 = wpt->creation_time; + } + } + route_flush(backuproute); + xfree(backuproute); } void -interpfilt_init(const char *args) { - - char *fm; - if ( opt_interval && opt_dist ) { - fatal( MYNAME ": Can't interpolate on both time and distance.\n"); - } - else if (opt_interval && opt_route ) { - fatal( MYNAME ": Can't interpolate routes on time.\n" ); - } - else if ( opt_interval ) { - interval = atoi(opt_interval); - } - else if ( opt_dist ) { - dist = strtod(opt_dist, &fm); - if ((*fm == 'k') || (*fm == 'K')) { - /* distance is kilometers, convert to miles */ - dist *= .6214; - } - } - else { - fatal( MYNAME ": No interval specified.\n"); - } +interpfilt_init(const char* args) +{ + + char* fm; + if (opt_interval && opt_dist) { + fatal(MYNAME ": Can't interpolate on both time and distance.\n"); + } else if (opt_interval && opt_route) { + fatal(MYNAME ": Can't interpolate routes on time.\n"); + } else if (opt_interval) { + interval = atoi(opt_interval); + } else if (opt_dist) { + dist = strtod(opt_dist, &fm); + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to miles */ + dist *= .6214; + } + } else { + fatal(MYNAME ": No interval specified.\n"); + } } filter_vecs_t interpolatefilt_vecs = { - interpfilt_init, - interpfilt_process, - NULL, - NULL, - interpfilt_args + interpfilt_init, + interpfilt_process, + NULL, + NULL, + interpfilt_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/itracku.c b/gpsbabel/itracku.c index ee23585db..be26c2e7a 100644 --- a/gpsbabel/itracku.c +++ b/gpsbabel/itracku.c @@ -17,17 +17,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -/* - This module will download track data from a - +/* + This module will download track data from a + XAiOX iTrackU BLUETOOTH GPS-RECEIVER SiRF III http://www.xaiox.com/itracku_sirf3.htm Example usage:: - - # Read from USB port, output trackpoints & waypoints in GPX format + + # Read from USB port, output trackpoints & waypoints in GPX format ./gpsbabel -i itracku -f com14 -o gpx -F out.gpx - + */ #include "defs.h" #include @@ -38,12 +38,12 @@ /* memory layout of the iTrackU data record */ typedef struct { - gbuint8 longitude[4]; - gbuint8 latitude[4]; - gbuint8 creation_time[4]; - gbuint8 altitude[2]; - gbuint8 speed; - gbuint8 flag; + gbuint8 longitude[4]; + gbuint8 latitude[4]; + gbuint8 creation_time[4]; + gbuint8 altitude[2]; + gbuint8 speed; + gbuint8 flag; } itracku_data_record; static int itracku_is_valid_data_record(itracku_data_record* d); @@ -53,8 +53,8 @@ static waypoint* to_waypoint(itracku_data_record* d); /* itracku file access */ static void itracku_file_read_data_record(gbfile* fin, itracku_data_record* d); static gbuint32 itracku_file_read_last_time(gbfile* fin); -static void itracku_file_read_waypts(gbfile* fin, void (*waypt_add)(waypoint *wpt)); -static void itracku_file_write_waypt(gbfile* fout, const waypoint *wpt); +static void itracku_file_read_waypts(gbfile* fin, void (*waypt_add)(waypoint* wpt)); +static void itracku_file_write_waypt(gbfile* fout, const waypoint* wpt); /* itracku device access */ static const char read_update_data_command[] = { 0x60, 0xb5, 0, 0, 0, 0, 0 }; /* command string to start memory dump */ @@ -63,9 +63,9 @@ static const char update_end_marker[] = "WP Update Over"; /* end marker for the static const int update_end_marker_size = sizeof(update_end_marker); #if LATER static const int port_auto_detect_max_port = 32; -/* Special port name for auto detect. If used, gpsbabel will try to detect the serial +/* Special port name for auto detect. If used, gpsbabel will try to detect the serial port with the itracku device automatically. */ -static const char port_auto_detect_filename[] = "auto:"; +static const char port_auto_detect_filename[] = "auto:"; #endif static int update_data_buffer_read_count = 0; @@ -74,113 +74,113 @@ static char* update_data_buffer_read; static char* update_data_buffer_write; static char* update_data_buffer_end; -static void itracku_device_dump_waypts(void* fd, void (*waypt_add)(waypoint *wpt)); +static void itracku_device_dump_waypts(void* fd, void (*waypt_add)(waypoint* wpt)); static int itracku_device_update_data_init(); static int itracku_device_update_data_read(void* buf, int len); static void itracku_device_write_string(const char* s); static const char* itracku_device_read_string(); /* global variables */ -static void *fd; /* serial fd */ +static void* fd; /* serial fd */ static gbfile* fin; /* input file handle */ static gbfile* fout; /* output file handle */ static gbfile* fbackup; /* backup file handle */ static gbuint32 backup_last_creation_time; /* time of last data record in backup file */ static gbuint32 new_waypoint_count; /* count of new waypoints */ -static char *port; /* serial port name */ -static char *backup_file_name; /* "backup" command option */ -static char *only_new; /* "new" command option */ +static char* port; /* serial port name */ +static char* backup_file_name; /* "backup" command option */ +static char* only_new; /* "new" command option */ static void -dbg(int l, const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - fprintf(stderr, MYNAME ": "); - vfprintf(stderr,msg, ap); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(ap); +dbg(int l, const char* msg, ...) +{ + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + fprintf(stderr, MYNAME ": "); + vfprintf(stderr,msg, ap); + fprintf(stderr, "\n"); + fflush(stderr); + } + va_end(ap); } static void itracku_device_write_string(const char* s) { - int size = strlen(s) + 1; - dbg(1, "write to device: %s", s); - gbser_write(fd, s, size); + int size = strlen(s) + 1; + dbg(1, "write to device: %s", s); + gbser_write(fd, s, size); } static const char* itracku_device_read_string() { - const int size = 1024; - char* s = xmalloc(size); - gbser_read_line(fd, s, size, 1000, 0, 0); - dbg(1, "read from device: %s", s); - return s; + const int size = 1024; + char* s = (char*) xmalloc(size); + gbser_read_line(fd, s, size, 1000, 0, 0); + dbg(1, "read from device: %s", s); + return s; } -static int +static int itracku_device_update_data_init() { - update_data_buffer_read = update_data_buffer; - update_data_buffer_write = update_data_buffer; - update_data_buffer_end = update_data_buffer + sizeof(update_data_buffer); - update_data_buffer_read_count = 0; - dbg(1, "start memory dump"); - return 0; + update_data_buffer_read = update_data_buffer; + update_data_buffer_write = update_data_buffer; + update_data_buffer_end = update_data_buffer + sizeof(update_data_buffer); + update_data_buffer_read_count = 0; + dbg(1, "start memory dump"); + return 0; } -static int +static int itracku_device_update_data_read(void* buf, int len) { - int rc; + int rc; + + if (update_data_buffer_write - update_data_buffer_read >= len) { + memcpy(buf, update_data_buffer_read, len); + update_data_buffer_read += len; + return len; + } - if (update_data_buffer_write - update_data_buffer_read >= len) { - memcpy(buf, update_data_buffer_read, len); - update_data_buffer_read += len; - return len; - } - - if (update_data_buffer_read + update_end_marker_size > update_data_buffer_end) { - memcpy(update_data_buffer, update_data_buffer_read, update_data_buffer_write - update_data_buffer_read); - update_data_buffer_write = update_data_buffer + (update_data_buffer_write - update_data_buffer_read); - update_data_buffer_read = update_data_buffer; - } + if (update_data_buffer_read + update_end_marker_size > update_data_buffer_end) { + memcpy(update_data_buffer, update_data_buffer_read, update_data_buffer_write - update_data_buffer_read); + update_data_buffer_write = update_data_buffer + (update_data_buffer_write - update_data_buffer_read); + update_data_buffer_read = update_data_buffer; + } - rc = gbser_read_wait(fd, update_data_buffer_write, update_data_buffer_end - update_data_buffer_write, timeout); - if (rc == gbser_ERROR) { - return 0; - } + rc = gbser_read_wait(fd, update_data_buffer_write, update_data_buffer_end - update_data_buffer_write, timeout); + if (rc == gbser_ERROR) { + return 0; + } - update_data_buffer_write += rc; - update_data_buffer_read_count += rc; - dbg(1, "%5d kbyte read", update_data_buffer_read_count / 1024); + update_data_buffer_write += rc; + update_data_buffer_read_count += rc; + dbg(1, "%5d kbyte read", update_data_buffer_read_count / 1024); - if (0 == strncmp(update_end_marker, update_data_buffer_write - update_end_marker_size, update_end_marker_size - 1)) { - dbg(1, "end memory dump"); - return 0; - } + if (0 == strncmp(update_end_marker, update_data_buffer_write - update_end_marker_size, update_end_marker_size - 1)) { + dbg(1, "end memory dump"); + return 0; + } - return itracku_device_update_data_read(buf, len); + return itracku_device_update_data_read(buf, len); } /* Convert the degrees format of itracku to double. itracku stores degrees in a - 32-bit unsigned integer. The lower + 32-bit unsigned integer. The lower 6 digits in 10-base notation denote the - minutes multiplied by 10000, and digits + minutes multiplied by 10000, and digits 7-9 denote the degrees. To express a negative number 0x80000000 is added to integer. - Example: the integer 49347687 is interpreted + Example: the integer 49347687 is interpreted as ddmmmmmm @@ -200,27 +200,27 @@ itracku_device_update_data_read(void* buf, int len) double deg_min_to_deg(volatile gbuint32 x) { - double sign; - gbuint32 sep; - gbuint32 d; - gbuint32 m10000; - // determine the sign - if (x > 0x80000000) { - sign = -1.0; - x -= 0x80000000; - } else { - sign = 1.0; - } + double sign; + gbuint32 sep; + gbuint32 d; + gbuint32 m10000; + // determine the sign + if (x > 0x80000000) { + sign = -1.0; + x -= 0x80000000; + } else { + sign = 1.0; + } - sep = 1000000; - - // extract degrees - d = (unsigned int) x / (unsigned int) sep; - // extract (minutes * 10000) - m10000 = x - d * sep; + sep = 1000000; - // convert minutes and degrees to a double - return sign * ((double)d + ((double)m10000) / 600000.0); + // extract degrees + d = (unsigned int) x / (unsigned int) sep; + // extract (minutes * 10000) + m10000 = x - d * sep; + + // convert minutes and degrees to a double + return sign * ((double)d + ((double)m10000) / 600000.0); } /* @@ -229,45 +229,44 @@ deg_min_to_deg(volatile gbuint32 x) gbuint32 deg_to_deg_min(double x) { - gbint32 sign; - double d; - double f; + gbint32 sign; + double d; + double f; - // determine sign - if (x >= 0) { - sign = 1; - } - else { - sign = -1; - x = -x; - } + // determine sign + if (x >= 0) { + sign = 1; + } else { + sign = -1; + x = -x; + } - // integer degrees - d = floor(x); + // integer degrees + d = floor(x); - // fractional part - f = x - d; + // fractional part + f = x - d; - return - (gbuint32)d * 1000000 + // multiply integer degrees to shift it to the right digits. - (gbuint32)(f * 600000.0) + // multiply fractional part to convert to minutes and to to shift it to the right digits. - ((sign > 0) ? 0 : 0x80000000); // add 0x80000000 for negative degrees + return + (gbuint32)d * 1000000 + // multiply integer degrees to shift it to the right digits. + (gbuint32)(f * 600000.0) + // multiply fractional part to convert to minutes and to to shift it to the right digits. + ((sign > 0) ? 0 : 0x80000000); // add 0x80000000 for negative degrees } /* Convert the itracku time format to time_t. */ -static time_t +static time_t decode_itracku_time(gbuint32 date) { - struct tm t; - t.tm_sec = date & 63; - t.tm_min = (date >> 6) & 63; - t.tm_hour = (date >> 12) & 31; - t.tm_mday = (date >> 17) & 31; - t.tm_mon = ((date >> 22) & 15) - 1; - t.tm_year = ((date >> 26) & 63) + 100; - return mkgmtime(&t); + struct tm t; + t.tm_sec = date & 63; + t.tm_min = (date >> 6) & 63; + t.tm_hour = (date >> 12) & 31; + t.tm_mday = (date >> 17) & 31; + t.tm_mon = ((date >> 22) & 15) - 1; + t.tm_year = ((date >> 26) & 63) + 100; + return mkgmtime(&t); } /* @@ -276,86 +275,85 @@ decode_itracku_time(gbuint32 date) static gbuint32 encode_itracku_time(time_t time) { - struct tm* t = gmtime(&time); - return - (t->tm_sec) + - (t->tm_min << 6) + - (t->tm_hour << 12) + - (t->tm_mday << 17) + - ((t->tm_mon + 1) << 22) + - ((t->tm_year - 100) << 26); + struct tm* t = gmtime(&time); + return + (t->tm_sec) + + (t->tm_min << 6) + + (t->tm_hour << 12) + + (t->tm_mday << 17) + + ((t->tm_mon + 1) << 22) + + ((t->tm_year - 100) << 26); } /* Converts a itracku waypoint record to a gpsbabel waypoint. */ -static waypoint* +static waypoint* to_waypoint(itracku_data_record* d) { - waypoint* wp; - wp = waypt_new(); - wp->longitude = deg_min_to_deg(le_read32(d->longitude)); - wp->latitude = deg_min_to_deg(le_read32(d->latitude)); - wp->creation_time = decode_itracku_time(le_read32(d->creation_time)); - wp->speed = KNOTS_TO_MPS((float)d->speed); - wp->wpt_flags.speed = 1; - wp->altitude = le_read16(d->altitude); - return wp; + waypoint* wp; + wp = waypt_new(); + wp->longitude = deg_min_to_deg(le_read32(d->longitude)); + wp->latitude = deg_min_to_deg(le_read32(d->latitude)); + wp->creation_time = decode_itracku_time(le_read32(d->creation_time)); + wp->speed = KNOTS_TO_MPS((float)d->speed); + wp->wpt_flags.speed = 1; + wp->altitude = le_read16(d->altitude); + return wp; } static void to_itracku_data_record(const waypoint* wp, itracku_data_record* d) { - le_write32(d->longitude, deg_to_deg_min(wp->longitude)); - le_write32(d->latitude, deg_to_deg_min(wp->latitude)); - le_write32(d->creation_time, encode_itracku_time(wp->creation_time)); - d->speed = MPS_TO_KNOTS(wp->speed); - le_write16(d->altitude, wp->altitude); - d->flag = 0xff; + le_write32(d->longitude, deg_to_deg_min(wp->longitude)); + le_write32(d->latitude, deg_to_deg_min(wp->latitude)); + le_write32(d->creation_time, encode_itracku_time(wp->creation_time)); + d->speed = MPS_TO_KNOTS(wp->speed); + le_write16(d->altitude, wp->altitude); + d->flag = 0xff; } /* - Tries to initialize an itracku device attached to + Tries to initialize an itracku device attached to serial port fd. fd must already be opened. - Returns gbser_OK if the initialization is sucessful, a + Returns gbser_OK if the initialization is sucessful, a non-zero integer otherwise. */ int init_device() { - int rc; - const char* greeting; - // verify that we have a MTK based logger... - dbg(1, "verifying device on port %s", port); - - itracku_device_write_string("WP AP-Exit"); - gbser_flush(fd); - itracku_device_write_string("W'P Camera Detect"); - greeting = itracku_device_read_string(); - - if (0 == strcmp(greeting , "WP GPS+BT")) { - dbg(1, "device recognised on port %s", port); - rc = gbser_OK; - } - else { - dbg(1, "device not recognised on port %s", port); - rc = gbser_ERROR; - } - xfree((void*)greeting); - return rc; -} - -// Any arg in this list will appear in command line help and will be + int rc; + const char* greeting; + // verify that we have a MTK based logger... + dbg(1, "verifying device on port %s", port); + + itracku_device_write_string("WP AP-Exit"); + gbser_flush(fd); + itracku_device_write_string("W'P Camera Detect"); + greeting = itracku_device_read_string(); + + if (0 == strcmp(greeting , "WP GPS+BT")) { + dbg(1, "device recognised on port %s", port); + rc = gbser_OK; + } else { + dbg(1, "device not recognised on port %s", port); + rc = gbser_ERROR; + } + xfree((void*)greeting); + return rc; +} + +// Any arg in this list will appear in command line help and will be // populated for you. -// Values for ARGTYPE_xxx can be found in defs.h and are used to +// Values for ARGTYPE_xxx can be found in defs.h and are used to // select the type of option. static arglist_t itracku_args[] = { - { "backup", &backup_file_name, "Appends the input to a backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "new", &only_new, "Only waypoints that are not the backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, -// "default", ARGYTPE_STRING, ARG_NOMINMAX} , - ARG_TERMINATOR + { "backup", &backup_file_name, "Appends the input to a backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "new", &only_new, "Only waypoints that are not the backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR }; /******************************************************************************* @@ -363,131 +361,117 @@ arglist_t itracku_args[] = { *******************************************************************************/ static void -itracku_rd_init_common(const char *fname) -{ - new_waypoint_count = 0; - - if (backup_file_name != NULL) - { - fbackup = gbfopen(backup_file_name, "a+", MYNAME); - backup_last_creation_time = itracku_file_read_last_time(fbackup); - gbfseek(fbackup, 0, SEEK_END); - } - else - { - fbackup = NULL; - backup_last_creation_time = 0; - } - } +itracku_rd_init_common(const char* fname) +{ + new_waypoint_count = 0; + + if (backup_file_name != NULL) { + fbackup = gbfopen(backup_file_name, "a+", MYNAME); + backup_last_creation_time = itracku_file_read_last_time(fbackup); + gbfseek(fbackup, 0, SEEK_END); + } else { + fbackup = NULL; + backup_last_creation_time = 0; + } +} static void -itracku_rd_ser_init(const char *fname) +itracku_rd_ser_init(const char* fname) { #if LATER - int i; - if (0 == strcmp(fname, port_auto_detect_filename)) { - dbg(1, "auto detecting port for iTrackU device"); - for (i=1; !fd && icreation_time) > backup_last_creation_time) { - backup_last_creation_time = le_read32(d->creation_time); - gbfwrite(d, sizeof(*d), 1, fbackup); - result = -1; - } - else { - result = (only_new == NULL); - } - } - else { - result = -1; - } - } - if (result) { - ++new_waypoint_count; - } - return result; + int result = 0; + + if (!itracku_is_valid_data_record(d)) { + result = 0; + } else { + if (fbackup) { + if ((gbuint32)le_read32(d->creation_time) > backup_last_creation_time) { + backup_last_creation_time = le_read32(d->creation_time); + gbfwrite(d, sizeof(*d), 1, fbackup); + result = -1; + } else { + result = (only_new == NULL); + } + } else { + result = -1; + } + } + if (result) { + ++new_waypoint_count; + } + return result; } static int itracku_is_valid_data_record(itracku_data_record* d) { - return !(le_read32(d->longitude) == -1); + return !(le_read32(d->longitude) == -1); } static void -itracku_device_dump_waypts(void* fd, void (*waypt_add)(waypoint *wpt)) +itracku_device_dump_waypts(void* fd, void (*waypt_add)(waypoint* wpt)) { - itracku_data_record d; + itracku_data_record d; + + dbg(1, "reading memory"); + gbser_write(fd, read_update_data_command, sizeof(read_update_data_command)); - dbg(1, "reading memory"); - gbser_write(fd, read_update_data_command, sizeof(read_update_data_command)); - - itracku_device_update_data_init(); + itracku_device_update_data_init(); - while (itracku_device_update_data_read(&d, sizeof(d))) - { - if (itracku_is_valid_data_record(&d)) { - if (import_data_record(&d)) { - waypt_add(to_waypoint(&d)); - } - } - } + while (itracku_device_update_data_read(&d, sizeof(d))) { + if (itracku_is_valid_data_record(&d)) { + if (import_data_record(&d)) { + waypt_add(to_waypoint(&d)); + } + } + } } static void itracku_file_read_data_record(gbfile* fin, itracku_data_record* d) { - gbfread(d, sizeof(*d), 1, fin); + gbfread(d, sizeof(*d), 1, fin); } static gbuint32 itracku_file_read_last_time(gbfile* fin) { - itracku_data_record d; - gbsize_t s; - s = sizeof(itracku_data_record); - gbfseek(fin, 0, SEEK_END); - if (gbftell(fin) < s) - { - return 0; - } - gbfseek(fin, -(int)s, SEEK_END); - itracku_file_read_data_record(fin, &d); - return (gbuint32) le_read32(d.creation_time); + itracku_data_record d; + gbsize_t s; + s = sizeof(itracku_data_record); + gbfseek(fin, 0, SEEK_END); + if (gbftell(fin) < s) { + return 0; + } + gbfseek(fin, -(int)s, SEEK_END); + itracku_file_read_data_record(fin, &d); + return (gbuint32) le_read32(d.creation_time); } static void -itracku_file_read_waypts(gbfile* fin, void (*waypt_add)(waypoint *wpt)) +itracku_file_read_waypts(gbfile* fin, void (*waypt_add)(waypoint* wpt)) { - itracku_data_record d; + itracku_data_record d; - while (gbfread(&d, sizeof(d), 1, fin)) - { - if (le_read32(d.longitude) == -1) { - continue; - } - if (import_data_record(&d)) { - waypt_add(to_waypoint(&d)); - } - } + while (gbfread(&d, sizeof(d), 1, fin)) { + if (le_read32(d.longitude) == -1) { + continue; + } + if (import_data_record(&d)) { + waypt_add(to_waypoint(&d)); + } + } } static void -itracku_file_write_waypt(gbfile* fout, const waypoint *wpt) +itracku_file_write_waypt(gbfile* fout, const waypoint* wpt) { - itracku_data_record d; - to_itracku_data_record(wpt, &d); - gbfwrite(&d, sizeof(d), 1, fout); + itracku_data_record d; + to_itracku_data_record(wpt, &d); + gbfwrite(&d, sizeof(d), 1, fout); } static void -itracku_waypt_input(void (*waypt_add)(waypoint *wpt)) +itracku_waypt_input(void (*waypt_add)(waypoint* wpt)) { - if (fd) - { - itracku_device_dump_waypts(fd, waypt_add); - } - else - { - itracku_file_read_waypts(fin, waypt_add); - } + if (fd) { + itracku_device_dump_waypts(fd, waypt_add); + } else { + itracku_file_read_waypts(fin, waypt_add); + } } static void itracku_read_waypt(void) { - itracku_waypt_input(&waypt_add); + itracku_waypt_input(&waypt_add); } static route_head* itracku_read_trk_track; static void -itracku_read_trk_waypt_add(waypoint *wpt) +itracku_read_trk_waypt_add(waypoint* wpt) { - track_add_wpt(itracku_read_trk_track, wpt); + track_add_wpt(itracku_read_trk_track, wpt); } static void itracku_read_trk(void) { - itracku_read_trk_track = route_head_alloc(); - track_add_head(itracku_read_trk_track); - itracku_waypt_input(&itracku_read_trk_waypt_add); + itracku_read_trk_track = route_head_alloc(); + track_add_head(itracku_read_trk_track); + itracku_waypt_input(&itracku_read_trk_waypt_add); } static void itracku_read(void) { - switch(global_opts.objective) { - case wptdata: - itracku_read_waypt(); - break; - case trkdata: - itracku_read_trk(); - break; - case rtedata: - fatal(MYNAME ": reading routes is not supported.\n"); - break; - case posndata: - break; - } -} - + switch (global_opts.objective) { + case wptdata: + case unknown_gpsdata: + itracku_read_waypt(); + break; + case trkdata: + itracku_read_trk(); + break; + case rtedata: + fatal(MYNAME ": reading routes is not supported.\n"); + break; + case posndata: + break; + } +} + static void -itracku_wr_init(const char *fname) +itracku_wr_init(const char* fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } static void itracku_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void -itracku_output_waypoint(const waypoint * wp) +itracku_output_waypoint(const waypoint* wp) { - itracku_file_write_waypt(fout, wp); + itracku_file_write_waypt(fout, wp); } static void itracku_write(void) { - waypt_disp_all(itracku_output_waypoint); + waypt_disp_all(itracku_output_waypoint); } static void @@ -676,87 +652,85 @@ itracku_exit(void) /* optional */ } static void -itracku_rt_init(const char *fname) +itracku_rt_init(const char* fname) { - itracku_rd_ser_init(fname); - itracku_device_write_string("WP AP-Exit"); + itracku_rd_ser_init(fname); + itracku_device_write_string("WP AP-Exit"); } static void -nmea_set_waypoint_time(waypoint *wpt, struct tm *time, int microseconds) -{ - if (time->tm_year == 0) - { - wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; - wpt->microseconds = microseconds; - if (wpt->wpt_flags.fmt_use == 0) - { - wpt->wpt_flags.fmt_use = 1; - } - } - else - { - wpt->creation_time = mkgmtime(time); - wpt->microseconds = microseconds; - if (wpt->wpt_flags.fmt_use != 0) - { - wpt->wpt_flags.fmt_use = 0; - } - } -} - -static waypoint * -gprmc_parse(char *ibuf) -{ - double latdeg, lngdeg; - char lngdir, latdir; - double hms; - char fix; - unsigned int dmy; - double speed,course; - waypoint *waypt; - double microseconds; - struct tm tm; - - int rc = sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf,%u", - &hms, &fix, &latdeg, &latdir, - &lngdeg, &lngdir, - &speed, &course, &dmy); - - if (rc == 0) - { - return NULL; - } - - microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); - - tm.tm_sec = (long) hms % 100; - hms = hms / 100; - tm.tm_min = (long) hms % 100; - hms = hms / 100; - tm.tm_hour = (long) hms % 100; - - tm.tm_year = dmy % 100 + 100; - dmy = dmy / 100; - tm.tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm.tm_mday = dmy; - - waypt = waypt_new(); - - WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); - - WAYPT_SET(waypt, course, course); - - nmea_set_waypoint_time(waypt, &tm, microseconds); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - return waypt; +nmea_set_waypoint_time(waypoint* wpt, struct tm* time, int microseconds) +{ + if (time->tm_year == 0) { + wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use == 0) { + wpt->wpt_flags.fmt_use = 1; + } + } else { + wpt->creation_time = mkgmtime(time); + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use != 0) { + wpt->wpt_flags.fmt_use = 0; + } + } +} + +static waypoint* +gprmc_parse(char* ibuf) +{ + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + char fix; + unsigned int dmy; + double speed,course; + waypoint* waypt; + double microseconds; + struct tm tm; + + int rc = sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf,%u", + &hms, &fix, &latdeg, &latdir, + &lngdeg, &lngdir, + &speed, &course, &dmy); + + if (rc == 0) { + return NULL; + } + + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + tm.tm_year = dmy % 100 + 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; + + waypt = waypt_new(); + + WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); + + WAYPT_SET(waypt, course, course); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + return waypt; } /* @@ -766,72 +740,70 @@ gprmc_parse(char *ibuf) andreas.grimme@gmx.net */ -static waypoint * -itracku_rt_position(posn_status *posn_status) -{ - char line[1024]; - waypoint* wpt; - while (1) - { - gbser_read_line(fd, line, sizeof(line), 5000, 13, 10); - dbg(1, line); - wpt = gprmc_parse(line); - if (wpt) - { - return wpt; - } - } +static waypoint* +itracku_rt_position(posn_status* posn_status) +{ + char line[1024]; + waypoint* wpt; + while (1) { + gbser_read_line(fd, line, sizeof(line), 5000, 13, 10); + dbg(1, line); + wpt = gprmc_parse(line); + if (wpt) { + return wpt; + } + } } static void itracku_rt_deinit(void) { - itracku_rd_deinit(); + itracku_rd_deinit(); } /**************************************************************************/ // capabilities below means: we can only read and write waypoints -// please change this depending on your new module +// please change this depending on your new module ff_vecs_t itracku_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - itracku_rd_ser_init, - NULL, - itracku_rd_deinit, - NULL, - itracku_read, - itracku_write, - itracku_exit, - itracku_args, - CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ - { itracku_rt_init, itracku_rt_position, itracku_rt_deinit, NULL, NULL, NULL } + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + itracku_rd_ser_init, + NULL, + itracku_rd_deinit, + NULL, + itracku_read, + itracku_write, + itracku_exit, + itracku_args, + CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ + { itracku_rt_init, itracku_rt_position, itracku_rt_deinit, NULL, NULL, NULL } }; ff_vecs_t itracku_fvecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - itracku_rd_init, - itracku_wr_init, - itracku_rd_deinit, - itracku_wr_deinit, - itracku_read, - itracku_write, - itracku_exit, - itracku_args, - CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ - { NULL, NULL, NULL, NULL, NULL, NULL } + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + itracku_rd_init, + itracku_wr_init, + itracku_rd_deinit, + itracku_wr_deinit, + itracku_read, + itracku_write, + itracku_exit, + itracku_args, + CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ + { NULL, NULL, NULL, NULL, NULL, NULL } }; diff --git a/gpsbabel/jeeps/garminusb.h b/gpsbabel/jeeps/garminusb.h index a05f9c15d..e61fa2ade 100644 --- a/gpsbabel/jeeps/garminusb.h +++ b/gpsbabel/jeeps/garminusb.h @@ -23,45 +23,47 @@ /* This structure is a bit funny looking to avoid variable length * arrays which aren't present in C89. This contains the visible * fields in the USB packets of the Garmin USB receivers (60C, 76C, etc.) - * All data are little endian. + * All data are little endian. */ -typedef +typedef union { - struct { - unsigned char type; - unsigned char reserved1; - unsigned char reserved2; - unsigned char reserved3; - unsigned char pkt_id[2]; - unsigned char reserved6; - unsigned char reserved7; - unsigned char datasz[4]; - unsigned char databuf[1]; /* actually an variable length array... */ - } gusb_pkt; - unsigned char dbuf[1024]; + struct { + unsigned char type; + unsigned char reserved1; + unsigned char reserved2; + unsigned char reserved3; + unsigned char pkt_id[2]; + unsigned char reserved6; + unsigned char reserved7; + unsigned char datasz[4]; + unsigned char databuf[1]; /* actually an variable length array... */ + } gusb_pkt; + unsigned char dbuf[1024]; } garmin_usb_packet; /* - * Internal interfaces that are common regardless of underlying - * OS implementation. + * Internal interfaces that are common regardless of underlying + * OS implementation. */ #define GUSB_MAX_UNITS 20 -struct garmin_unit_info { - unsigned long serial_number; - unsigned long unit_id; - unsigned long unit_version; - char *os_identifier; /* In case the OS has another name for it. */ - char *product_identifier; /* From the hardware itself. */ -} garmin_unit_info[GUSB_MAX_UNITS]; +typedef struct { + unsigned long serial_number; + unsigned long unit_id; + unsigned long unit_version; + char* os_identifier; /* In case the OS has another name for it. */ + char* product_identifier; /* From the hardware itself. */ +} garmin_unit_info_t; -int gusb_cmd_send(const garmin_usb_packet *obuf, size_t sz); -int gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz); -int gusb_init(const char *portname, gpsdevh **dh); -int gusb_close(gpsdevh *); +extern garmin_unit_info_t garmin_unit_info[GUSB_MAX_UNITS]; + +int gusb_cmd_send(const garmin_usb_packet* obuf, size_t sz); +int gusb_cmd_get(garmin_usb_packet* ibuf, size_t sz); +int gusb_init(const char* portname, gpsdevh** dh); +int gusb_close(gpsdevh*); /* * New packet types in USB. */ #define GUSB_SESSION_START 5 /* We request units attention */ -#define GUSB_SESSION_ACK 6 /* Unit responds that we have its attention */ +#define GUSB_SESSION_ACK 6 /* Unit responds that we have its attention */ #define GUSB_REQUEST_BULK 2 /* Unit requests we read from bulk pipe */ diff --git a/gpsbabel/jeeps/gps.h b/gpsbabel/jeeps/gps.h index ed9d2dacb..12f30eaf2 100644 --- a/gpsbabel/jeeps/gps.h +++ b/gpsbabel/jeeps/gps.h @@ -1,6 +1,6 @@ #ifdef __cplusplus -extern "C" -{ +// extern "C" +//{ #endif #ifndef gps_h @@ -36,202 +36,192 @@ extern int32 gps_show_bytes; extern char gps_categories[16][17]; -typedef struct GPS_SPacket -{ - US type; - uint32 n; - UC *data; +typedef struct GPS_SPacket { + US type; + uint32 n; + UC* data; } GPS_OPacket, *GPS_PPacket; -typedef struct GPS_Serial_SPacket -{ - UC dle; - UC type; - UC n; - UC *data; - UC chk; - UC edle; - UC etx; +typedef struct GPS_Serial_SPacket { + UC dle; + UC type; + UC n; + UC* data; + UC chk; + UC edle; + UC etx; } GPS_Serial_OPacket, *GPS_Serial_PPacket; -typedef struct GPS_SProduct_Data_Type -{ - int16 id; - int16 version; - char desc[MAX_GPS_PACKET_SIZE]; +typedef struct GPS_SProduct_Data_Type { + int16 id; + int16 version; + char desc[MAX_GPS_PACKET_SIZE]; } GPS_OProduct_Data_Type, *GPS_PProduct_Data_Type; -typedef struct GPS_SPvt_Data_Type -{ - float alt; - float epe; - float eph; - float epv; - int16 fix; - double tow; - double lat; - double lon; - float east; - float north; - float up; - float msl_hght; - int16 leap_scnds; - int32 wn_days; +typedef struct GPS_SPvt_Data_Type { + float alt; + float epe; + float eph; + float epv; + int16 fix; + double tow; + double lat; + double lon; + float east; + float north; + float up; + float msl_hght; + int16 leap_scnds; + int32 wn_days; } GPS_OPvt_Data, *GPS_PPvt_Data; -typedef struct GPS_STrack -{ - double lat; /* Degrees */ - double lon; /* Degrees */ - time_t Time; /* Unix time */ - float alt; /* Altitude */ - float dpth; /* Depth */ - float temperature; /* Temperature. Degrees Celsius. */ - int temperature_populated; /* True if above is valid. */ - unsigned char heartrate; /* Heartrate as in Garmin 301 */ - unsigned char cadence; /* Crank cadence as in Edge 305 */ - unsigned int wsensor_pres:1; /* Wheel sensor present */ - unsigned int tnew:1; /* New track? */ - unsigned int ishdr:1; /* Track header? */ - unsigned int no_latlon:1; /* True if no valid lat/lon found. */ - int32 dspl; /* Display on map? */ - int32 colour; /* Colour */ - float distance; /* distance traveled in meters.*/ - int distance_populated; /* True if above is valid. */ - char trk_ident[256]; /* Track identifier */ +typedef struct GPS_STrack { + double lat; /* Degrees */ + double lon; /* Degrees */ + time_t Time; /* Unix time */ + float alt; /* Altitude */ + float dpth; /* Depth */ + float temperature; /* Temperature. Degrees Celsius. */ + int temperature_populated; /* True if above is valid. */ + unsigned char heartrate; /* Heartrate as in Garmin 301 */ + unsigned char cadence; /* Crank cadence as in Edge 305 */ + unsigned int wsensor_pres:1; /* Wheel sensor present */ + unsigned int tnew:1; /* New track? */ + unsigned int ishdr:1; /* Track header? */ + unsigned int no_latlon:1; /* True if no valid lat/lon found. */ + int32 dspl; /* Display on map? */ + int32 colour; /* Colour */ + float distance; /* distance traveled in meters.*/ + int distance_populated; /* True if above is valid. */ + char trk_ident[256]; /* Track identifier */ } GPS_OTrack, *GPS_PTrack; -typedef struct GPS_SAlmanac -{ - UC svid; - int16 wn; - float toa; - float af0; - float af1; - float e; - float sqrta; - float m0; - float w; - float omg0; - float odot; - float i; - UC hlth; +typedef struct GPS_SAlmanac { + UC svid; + int16 wn; + float toa; + float af0; + float af1; + float e; + float sqrta; + float m0; + float w; + float omg0; + float odot; + float i; + UC hlth; } GPS_OAlmanac, *GPS_PAlmanac; -typedef struct GPS_SWay -{ - char ident[256]; - double lat; - double lon; - char cmnt[256]; - float dst; - int32 smbl; - int32 dspl; - char wpt_ident[256]; - char lnk_ident[256]; - UC subclass[18]; - int32 colour; - char cc[2]; - UC wpt_class; - UC alt_is_unknown; - float alt; - char city[24]; - char state[2]; - char name[30]; - char facility[32]; - char addr[52]; - char cross_road[52]; - int32 attr; - float dpth; - int32 idx; - int32 prot; - int32 isrte; - int32 rte_prot; - UC rte_num; - char rte_cmnt[20]; - char rte_ident[256]; - int32 islink; - int32 rte_link_class; - char rte_link_subclass[18]; - char rte_link_ident[256]; - - char time_populated; /* 1 if true */ - time_t time; /* Unix time */ - char temperature_populated; - float temperature; /* Degrees celsius. */ - uint16 category; - +typedef struct GPS_SWay { + char ident[256]; + double lat; + double lon; + char cmnt[256]; + float dst; + int32 smbl; + int32 dspl; + char wpt_ident[256]; + char lnk_ident[256]; + UC subclass[18]; + int32 colour; + char cc[2]; + UC wpt_class; + UC alt_is_unknown; + float alt; + char city[24]; + char state[2]; + char name[30]; + char facility[32]; + char addr[52]; + char cross_road[52]; + int32 attr; + float dpth; + int32 idx; + int32 prot; + int32 isrte; + int32 rte_prot; + UC rte_num; + char rte_cmnt[20]; + char rte_ident[256]; + int32 islink; + int32 rte_link_class; + char rte_link_subclass[18]; + char rte_link_ident[256]; + + char time_populated; /* 1 if true */ + time_t time; /* Unix time */ + char temperature_populated; + float temperature; /* Degrees celsius. */ + uint16 category; + } GPS_OWay, *GPS_PWay; /* * Forerunner/Edge Lap data. */ typedef struct GPS_SLap { - uint32 index; /* unique index in device or -1 */ - time_t start_time; - uint32 total_time; /* Hundredths of a second */ - float total_distance; /* In meters */ - double begin_lat; - double begin_lon; - double end_lat; - double end_lon; - int16 calories; - uint32 track_index; /* ref to track or -1 */ - float max_speed; /* In meters per second */ - unsigned char avg_heart_rate; /* In beats-per-minute, 0 if invalid */ - unsigned char max_heart_rate; /* In beats-per-minute, 0 if invalid */ - unsigned char intensity; /* Same as D1001 */ - unsigned char avg_cadence; /* In revolutions-per-minute, 0xFF if invalid */ - unsigned char trigger_method; - /*Some D1015 unknown */ - /* unsigned char unk1015_1; - int16 unk1015_2; - int16 unk1015_3; - */ + uint32 index; /* unique index in device or -1 */ + time_t start_time; + uint32 total_time; /* Hundredths of a second */ + float total_distance; /* In meters */ + double begin_lat; + double begin_lon; + double end_lat; + double end_lon; + int16 calories; + uint32 track_index; /* ref to track or -1 */ + float max_speed; /* In meters per second */ + unsigned char avg_heart_rate; /* In beats-per-minute, 0 if invalid */ + unsigned char max_heart_rate; /* In beats-per-minute, 0 if invalid */ + unsigned char intensity; /* Same as D1001 */ + unsigned char avg_cadence; /* In revolutions-per-minute, 0xFF if invalid */ + unsigned char trigger_method; + /*Some D1015 unknown */ + /* unsigned char unk1015_1; + int16 unk1015_2; + int16 unk1015_3; + */ } GPS_OLap, *GPS_PLap; -typedef struct GPS_SCourse -{ - uint32 index; /* Unique among courses on device */ - char course_name[16]; /* Null-terminated unique course name */ - uint32 track_index; /* Index of the associated track +typedef struct GPS_SCourse { + uint32 index; /* Unique among courses on device */ + char course_name[16]; /* Null-terminated unique course name */ + uint32 track_index; /* Index of the associated track * Must be 0xFFFFFFFF if there is none*/ } GPS_OCourse, *GPS_PCourse; -typedef struct GPS_SCourse_Lap -{ - uint32 course_index; /* Index of associated course */ - uint32 lap_index; /* This lap's index in the course */ - uint32 total_time; /* In hundredths of a second */ - float total_dist; /* [m] */ - double begin_lat; /* Starting position of the lap */ - double begin_lon; /* Invalid if lat,lon are 0x7FFFFFFF.*/ - double end_lat; /* Final position of the lap */ - double end_lon; /* Invalid if lat,lon are 0x7FFFFFFF.*/ - UC avg_heart_rate; /* In beats-per-minute, >0 */ - UC max_heart_rate; /* In beats-per-minute, >0 */ - UC intensity; /* 0=standard, active lap. +typedef struct GPS_SCourse_Lap { + uint32 course_index; /* Index of associated course */ + uint32 lap_index; /* This lap's index in the course */ + uint32 total_time; /* In hundredths of a second */ + float total_dist; /* [m] */ + double begin_lat; /* Starting position of the lap */ + double begin_lon; /* Invalid if lat,lon are 0x7FFFFFFF.*/ + double end_lat; /* Final position of the lap */ + double end_lon; /* Invalid if lat,lon are 0x7FFFFFFF.*/ + UC avg_heart_rate; /* In beats-per-minute, >0 */ + UC max_heart_rate; /* In beats-per-minute, >0 */ + UC intensity; /* 0=standard, active lap. 1=rest lap in a workout */ - UC avg_cadence; /* In revolutions-per-minute */ + UC avg_cadence; /* In revolutions-per-minute */ } GPS_OCourse_Lap, *GPS_PCourse_Lap; -typedef struct GPS_SCourse_Point -{ - char name[11]; /* Null-terminated name */ - uint32 course_index; /* Index of associated course */ - time_t track_point_time; /* Time */ - UC point_type; /* generic = 0, +typedef struct GPS_SCourse_Point { + char name[11]; /* Null-terminated name */ + uint32 course_index; /* Index of associated course */ + time_t track_point_time; /* Time */ + UC point_type; /* generic = 0, * summit = 1, * valley = 2, * water = 3, @@ -249,16 +239,15 @@ typedef struct GPS_SCourse_Point * sprint = 15 */ } GPS_OCourse_Point, *GPS_PCourse_Point; -typedef struct GPS_SCourse_Limits -{ - uint32 max_courses; - uint32 max_course_laps; - uint32 max_course_pnt; - uint32 max_course_trk_pnt; +typedef struct GPS_SCourse_Limits { + uint32 max_courses; + uint32 max_course_laps; + uint32 max_course_pnt; + uint32 max_course_trk_pnt; } GPS_OCourse_Limits, *GPS_PCourse_Limits; -typedef int (*pcb_fn) (int, struct GPS_SWay **); +typedef int (*pcb_fn)(int, struct GPS_SWay**); #include "gpsdevice.h" #include "gpssend.h" @@ -274,9 +263,9 @@ typedef int (*pcb_fn) (int, struct GPS_SWay **); #include "gpsinput.h" #include "gpsproj.h" -time_t gps_save_time; -double gps_save_lat; -double gps_save_lon; +extern time_t gps_save_time; +extern double gps_save_lat; +extern double gps_save_lon; extern int32 gps_save_id; extern double gps_save_version; extern char gps_save_string[GPS_ARB_LEN]; @@ -286,14 +275,14 @@ extern struct COMMANDDATA COMMAND_ID[2]; extern struct LINKDATA LINK_ID[3]; extern struct GPS_MODEL_PROTOCOL GPS_MP[]; -extern char *gps_marine_sym[]; -extern char *gps_land_sym[]; -extern char *gps_aviation_sym[]; -extern char *gps_16_sym[]; +extern char* gps_marine_sym[]; +extern char* gps_land_sym[]; +extern char* gps_aviation_sym[]; +extern char* gps_16_sym[]; #endif #ifdef __cplusplus -} +// } #endif diff --git a/gpsbabel/jeeps/gpsapp.c b/gpsbabel/jeeps/gpsapp.c index e8b5fc755..b21761b7b 100644 --- a/gpsbabel/jeeps/gpsapp.c +++ b/gpsbabel/jeeps/gpsapp.c @@ -37,72 +37,76 @@ #include "garminusb.h" #include "gpsusbint.h" +time_t gps_save_time; +double gps_save_lat; +double gps_save_lon; + #define XMIN(a,b) (a < b? a : b) -static int32 GPS_A000(const char *port); +static int32 GPS_A000(const char* port); static void GPS_A001(GPS_PPacket packet); -static void GPS_A500_Translate(UC *s, GPS_PAlmanac *alm); -static void GPS_A500_Encode(UC *s, GPS_PAlmanac alm); -static void GPS_A300_Translate(UC *s, GPS_PTrack *trk); -static void GPS_A300_Encode(UC *s, GPS_PTrack trk); - - -static void GPS_D100_Get(GPS_PWay *way, UC *s); -static void GPS_D101_Get(GPS_PWay *way, UC *s); -static void GPS_D102_Get(GPS_PWay *way, UC *s); -static void GPS_D103_Get(GPS_PWay *way, UC *s); -static void GPS_D104_Get(GPS_PWay *way, UC *s); -static void GPS_D105_Get(GPS_PWay *way, UC *s); -static void GPS_D106_Get(GPS_PWay *way, UC *s); -static void GPS_D107_Get(GPS_PWay *way, UC *s); -static void GPS_D108_Get(GPS_PWay *way, UC *s); -static void GPS_D109_Get(GPS_PWay *way, UC *s, int proto); -static void GPS_D150_Get(GPS_PWay *way, UC *s); -static void GPS_D151_Get(GPS_PWay *way, UC *s); -static void GPS_D152_Get(GPS_PWay *way, UC *s); -static void GPS_D154_Get(GPS_PWay *way, UC *s); -static void GPS_D155_Get(GPS_PWay *way, UC *s); - -static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D105_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int proto); -static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len); - -static void GPS_D120_Get(int n, char *data); - -static void GPS_D200_Get(GPS_PWay *way, UC *s); -static void GPS_D201_Get(GPS_PWay *way, UC *s); -static void GPS_D202_Get(GPS_PWay *way, UC *s); -static void GPS_D210_Get(GPS_PWay *way, UC *s); -static void GPS_D200_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D201_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D202_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len); - -static void GPS_D400_Get(GPS_PWay *way, UC *s); -static void GPS_D403_Get(GPS_PWay *way, UC *s); -static void GPS_D450_Get(GPS_PWay *way, UC *s); -static void GPS_D400_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D403_Send(UC *data, GPS_PWay way, int32 *len); -static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len); - -static void GPS_D500_Send(UC *data, GPS_PAlmanac alm); -static void GPS_D501_Send(UC *data, GPS_PAlmanac alm); -static void GPS_D550_Send(UC *data, GPS_PAlmanac alm); -static void GPS_D551_Send(UC *data, GPS_PAlmanac alm); +static void GPS_A500_Translate(UC* s, GPS_PAlmanac* alm); +static void GPS_A500_Encode(UC* s, GPS_PAlmanac alm); +static void GPS_A300_Translate(UC* s, GPS_PTrack* trk); +static void GPS_A300_Encode(UC* s, GPS_PTrack trk); + + +static void GPS_D100_Get(GPS_PWay* way, UC* s); +static void GPS_D101_Get(GPS_PWay* way, UC* s); +static void GPS_D102_Get(GPS_PWay* way, UC* s); +static void GPS_D103_Get(GPS_PWay* way, UC* s); +static void GPS_D104_Get(GPS_PWay* way, UC* s); +static void GPS_D105_Get(GPS_PWay* way, UC* s); +static void GPS_D106_Get(GPS_PWay* way, UC* s); +static void GPS_D107_Get(GPS_PWay* way, UC* s); +static void GPS_D108_Get(GPS_PWay* way, UC* s); +static void GPS_D109_Get(GPS_PWay* way, UC* s, int proto); +static void GPS_D150_Get(GPS_PWay* way, UC* s); +static void GPS_D151_Get(GPS_PWay* way, UC* s); +static void GPS_D152_Get(GPS_PWay* way, UC* s); +static void GPS_D154_Get(GPS_PWay* way, UC* s); +static void GPS_D155_Get(GPS_PWay* way, UC* s); + +static void GPS_D100_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D101_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D102_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D103_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D104_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D105_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D106_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D107_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D108_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D109_Send(UC* data, GPS_PWay way, int32* len, int proto); +static void GPS_D150_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D151_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D152_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D154_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D155_Send(UC* data, GPS_PWay way, int32* len); + +static void GPS_D120_Get(int n, char* data); + +static void GPS_D200_Get(GPS_PWay* way, UC* s); +static void GPS_D201_Get(GPS_PWay* way, UC* s); +static void GPS_D202_Get(GPS_PWay* way, UC* s); +static void GPS_D210_Get(GPS_PWay* way, UC* s); +static void GPS_D200_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D201_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D202_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D210_Send(UC* data, GPS_PWay way, int32* len); + +static void GPS_D400_Get(GPS_PWay* way, UC* s); +static void GPS_D403_Get(GPS_PWay* way, UC* s); +static void GPS_D450_Get(GPS_PWay* way, UC* s); +static void GPS_D400_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D403_Send(UC* data, GPS_PWay way, int32* len); +static void GPS_D450_Send(UC* data, GPS_PWay way, int32* len); + +static void GPS_D500_Send(UC* data, GPS_PAlmanac alm); +static void GPS_D501_Send(UC* data, GPS_PAlmanac alm); +static void GPS_D550_Send(UC* data, GPS_PAlmanac alm); +static void GPS_D551_Send(UC* data, GPS_PAlmanac alm); static UC Is_Trackpoint_Invalid(GPS_PTrack trk); @@ -121,21 +125,25 @@ char gps_save_string[GPS_ARB_LEN]; typedef enum { UpperNo = 0, UpperYes = 1 } copycase; static -void copy_char_array(UC **dst, char* src, int count, copycase mustupper) +void copy_char_array(UC** dst, char* src, int count, copycase mustupper) { - UC *d = *dst; - int ocount = count; - do { - UC sc = *src++; - if (sc == 0) { - while (count--) - *d++ = ' '; - break; - } - if (!isalnum(sc)) continue; - else *d++ = mustupper == UpperYes ? toupper(sc) : sc; - } while (--count) ; - *dst += ocount; + UC* d = *dst; + int ocount = count; + do { + UC sc = *src++; + if (sc == 0) { + while (count--) { + *d++ = ' '; + } + break; + } + if (!isalnum(sc)) { + continue; + } else { + *d++ = mustupper == UpperYes ? toupper(sc) : sc; + } + } while (--count) ; + *dst += ocount; } @@ -150,30 +158,32 @@ void copy_char_array(UC **dst, char* src, int count, copycase mustupper) ** ** @return [int32] 1 if success -ve if error ************************************************************************/ -int32 GPS_Init(const char *port) +int32 GPS_Init(const char* port) { - int32 ret; + int32 ret; - (void) GPS_Util_Little(); + (void) GPS_Util_Little(); - ret = GPS_A000(port); - if(ret<0) return ret; - gps_save_time = GPS_Command_Get_Time(port); - - /* - * Some units may be unable to return time, such as a C320 when in - * charging mode. Only consider it fatal if the unit returns an error, - * not just absence of returning a time. - */ - if(gps_save_time < 0) { - return FRAMING_ERROR; - } - - if (0 == strncmp(gps_save_string, "GPilotS", 7)) { - return 1; - } + ret = GPS_A000(port); + if (ret<0) { + return ret; + } + gps_save_time = GPS_Command_Get_Time(port); + + /* + * Some units may be unable to return time, such as a C320 when in + * charging mode. Only consider it fatal if the unit returns an error, + * not just absence of returning a time. + */ + if (gps_save_time < 0) { + return FRAMING_ERROR; + } + + if (0 == strncmp(gps_save_string, "GPilotS", 7)) { + return 1; + } - return GPS_Command_Get_Position(port,&gps_save_lat,&gps_save_lon); + return GPS_Command_Get_Position(port,&gps_save_lat,&gps_save_lon); } @@ -185,173 +195,179 @@ int32 GPS_Init(const char *port) ** ** @return [int32] 1 if success -ve if error ************************************************************************/ -static int32 GPS_A000(const char *port) +static int32 GPS_A000(const char* port) { - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int16 version; - int16 id; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int16 version; + int16 id; - if(!GPS_Device_On(port, &fd)) - return gps_errno; + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } - if(!GPS_Device_Flush(fd)) - return gps_errno; + if (!GPS_Device_Flush(fd)) { + return gps_errno; + } - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - GPS_Make_Packet(&tra, LINK_ID[0].Pid_Product_Rqst,NULL,0); - if(!GPS_Write_Packet(fd,tra)) - return SERIAL_ERROR; + GPS_Make_Packet(&tra, LINK_ID[0].Pid_Product_Rqst,NULL,0); + if (!GPS_Write_Packet(fd,tra)) { + return SERIAL_ERROR; + } - if(!GPS_Get_Ack(fd, &tra, &rec)) - return SERIAL_ERROR; + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return SERIAL_ERROR; + } - GPS_Packet_Read(fd, &rec); - GPS_Send_Ack(fd, &tra, &rec); + GPS_Packet_Read(fd, &rec); + GPS_Send_Ack(fd, &tra, &rec); - id = GPS_Util_Get_Short(rec->data); - version = GPS_Util_Get_Short((rec->data)+2); + id = GPS_Util_Get_Short(rec->data); + version = GPS_Util_Get_Short((rec->data)+2); - (void) strcpy(gps_save_string,(char *)rec->data+4); - gps_save_id = id; - gps_save_version = (double)((double)version/(double)100.); + (void) strcpy(gps_save_string,(char*)rec->data+4); + gps_save_id = id; + gps_save_version = (double)((double)version/(double)100.); - GPS_User("Unit:\t%s\nID:\t%d\nVersion:\t%.2f", - gps_save_string, gps_save_id, gps_save_version); + GPS_User("Unit:\t%s\nID:\t%d\nVersion:\t%.2f", + gps_save_string, gps_save_id, gps_save_version); #if 0 - gps_date_time_transfer = pA600; - gps_date_time_type = pD600; /* All models so far */ - gps_position_transfer = pA700; - gps_position_type = pD700; /* All models so far */ + gps_date_time_transfer = pA600; + gps_date_time_type = pD600; /* All models so far */ + gps_position_transfer = pA700; + gps_position_type = pD700; /* All models so far */ #else - gps_date_time_transfer = -1; - gps_date_time_type = -1; - gps_position_transfer = -1; - gps_position_type = -1; + gps_date_time_transfer = -1; + gps_date_time_type = -1; + gps_position_transfer = -1; + gps_position_type = -1; #endif - gps_pvt_transfer = -1; - gps_pvt_type = -1; - gps_trk_transfer = -1; - gps_trk_type = -1; - gps_trk_hdr_type = -1; - gps_rte_link_type = -1; - - gps_waypt_transfer = -1; - gps_waypt_type = -1; - gps_route_transfer = -1; - gps_rte_hdr_type = -1; - gps_rte_type = -1; - - gps_prx_waypt_transfer = -1; - gps_prx_waypt_type = -1; - gps_almanac_transfer = -1; - gps_almanac_type = -1; - - gps_lap_transfer = -1; - gps_lap_type = -1; - gps_run_transfer = -1; - gps_run_type = -1; - gps_run_crs_trk_type = -1; - gps_run_crs_trk_hdr_type = -1; - gps_workout_transfer = -1; - gps_workout_type = -1; - gps_workout_occurrence_type = -1; - gps_user_profile_transfer = -1; - gps_user_profile_type = -1; - gps_workout_limits_transfer = -1; - gps_workout_limits_type = -1; - gps_course_transfer = -1; - gps_course_type = -1; - gps_course_lap_transfer = -1; - gps_course_lap_type = -1; - gps_course_point_transfer = -1; - gps_course_point_type = -1; - gps_course_limits_transfer = -1; - gps_course_limits_type = -1; - gps_course_trk_transfer = -1; - - gps_device_command = -1; - gps_link_type = -1; - - if(!GPS_Device_Wait(fd)) - { - GPS_Warning("A001 protocol not supported"); - id = GPS_Protocol_Version_Change(id,version); - if(GPS_Protocol_Table_Set(id)<0) - return GPS_UNSUPPORTED; - } - else - { - int i; - /* - * The unit may return more than one packet, so read and - * discard all but the product inquiry response. We have - * no way of knowing how many we'll get, so we have to keep - * reading until we incur a timeout. - * Worse still, the serial layer assumes a read timeout is a - * fatal error, while the USB layer (correctly) returns that error - * to the caller. So we call GPS_Device_Wait which spins into - * a delay/select for the serial system and a NOP for USB. - * - * Worse _yet_, this is the one place in all of Garmin Protocolsville - * where we don't know a priori how many packets will be sent in - * response. Since we want the lower levels of the USB handler - * to handle the ugliness of the "return to interrupt" packets, we - * reach behind that automation here and hand that ourselves. - */ - for (i = 0; i < 25; i++) { - rec->type = 0; - - if (gps_is_usb) { - GPS_Packet_Read_usb(fd, &rec, 0); - } else { - if(!GPS_Device_Wait(fd)) - goto carry_on; - - if (GPS_Packet_Read(fd, &rec) <= 0) { - goto carry_on; - } - - GPS_Send_Ack(fd, &tra, &rec); - } - - if (rec->type == 0xfd) { - GPS_A001(rec); - goto carry_on; - } - - /* - * If a 296 has previously been interrupted, it's going to - * ignore the session request (grrrr) and continue to send - * us left over packets. So if we see anything that isn't - * part of our A000 discovery cycle, reset the counter and - * continue to loop. - * - * Garmin acknowledges this is a firmware defect. - */ - if (rec->type < 0xf8) { - i = 0; - } - } - fatal("Failed to find a product inquiry response.\n"); + gps_pvt_transfer = -1; + gps_pvt_type = -1; + gps_trk_transfer = -1; + gps_trk_type = -1; + gps_trk_hdr_type = -1; + gps_rte_link_type = -1; + + gps_waypt_transfer = -1; + gps_waypt_type = -1; + gps_route_transfer = -1; + gps_rte_hdr_type = -1; + gps_rte_type = -1; + + gps_prx_waypt_transfer = -1; + gps_prx_waypt_type = -1; + gps_almanac_transfer = -1; + gps_almanac_type = -1; + + gps_lap_transfer = -1; + gps_lap_type = -1; + gps_run_transfer = -1; + gps_run_type = -1; + gps_run_crs_trk_type = -1; + gps_run_crs_trk_hdr_type = -1; + gps_workout_transfer = -1; + gps_workout_type = -1; + gps_workout_occurrence_type = -1; + gps_user_profile_transfer = -1; + gps_user_profile_type = -1; + gps_workout_limits_transfer = -1; + gps_workout_limits_type = -1; + gps_course_transfer = -1; + gps_course_type = -1; + gps_course_lap_transfer = -1; + gps_course_lap_type = -1; + gps_course_point_transfer = -1; + gps_course_point_type = -1; + gps_course_limits_transfer = -1; + gps_course_limits_type = -1; + gps_course_trk_transfer = -1; + + gps_device_command = -1; + gps_link_type = -1; + + if (!GPS_Device_Wait(fd)) { + GPS_Warning("A001 protocol not supported"); + id = GPS_Protocol_Version_Change(id,version); + if (GPS_Protocol_Table_Set(id)<0) { + return GPS_UNSUPPORTED; + } + } else { + int i; + /* + * The unit may return more than one packet, so read and + * discard all but the product inquiry response. We have + * no way of knowing how many we'll get, so we have to keep + * reading until we incur a timeout. + * Worse still, the serial layer assumes a read timeout is a + * fatal error, while the USB layer (correctly) returns that error + * to the caller. So we call GPS_Device_Wait which spins into + * a delay/select for the serial system and a NOP for USB. + * + * Worse _yet_, this is the one place in all of Garmin Protocolsville + * where we don't know a priori how many packets will be sent in + * response. Since we want the lower levels of the USB handler + * to handle the ugliness of the "return to interrupt" packets, we + * reach behind that automation here and hand that ourselves. + */ + for (i = 0; i < 25; i++) { + rec->type = 0; + + if (gps_is_usb) { + GPS_Packet_Read_usb(fd, &rec, 0); + } else { + if (!GPS_Device_Wait(fd)) { + goto carry_on; + } + + if (GPS_Packet_Read(fd, &rec) <= 0) { + goto carry_on; + } + + GPS_Send_Ack(fd, &tra, &rec); + } + + if (rec->type == 0xfd) { + GPS_A001(rec); + goto carry_on; + } + + /* + * If a 296 has previously been interrupted, it's going to + * ignore the session request (grrrr) and continue to send + * us left over packets. So if we see anything that isn't + * part of our A000 discovery cycle, reset the counter and + * continue to loop. + * + * Garmin acknowledges this is a firmware defect. + */ + if (rec->type < 0xf8) { + i = 0; + } } + fatal("Failed to find a product inquiry response.\n"); + } carry_on: - /* Make sure PVT is off as some GPS' have it on by default */ - if(gps_pvt_transfer != -1) - GPS_A800_Off(port,&fd); + /* Make sure PVT is off as some GPS' have it on by default */ + if (gps_pvt_transfer != -1) { + GPS_A800_Off(port,&fd); + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -368,426 +384,467 @@ carry_on: ************************************************************************/ static void GPS_A001(GPS_PPacket packet) { - int32 entries; - int32 i; - UC *p; - US tag; - US data; - US lasta=0; - - entries = packet->n / 3; - p = packet->data; - - for(i=0;i=200 && data <=202) - { - gps_rte_hdr_type = data; - continue; - } - if(data==210) - { - gps_rte_link_type = data; - continue; - } - - if(data<=110 && data>=100) - { - gps_rte_type = data; - continue; - } - if(data<153 && data>=150) - { - gps_rte_type = data; - continue; - } - if(data<156 && data>=154) - { - gps_rte_type = data; - continue; - } - if(data<451) - { - if(data==400) - gps_rte_type = pD400; - else if(data==403) - gps_rte_type = pD403; - else if(data==450) - gps_rte_type = pD450; - else - GPS_Protocol_Error(tag,data); - continue; - } - } - - else if(lasta<400) - { - switch (data) { - case 300: gps_trk_type = pD300; break; - case 301: gps_trk_type = pD301; break; - case 302: gps_trk_type = pD302; break; - case 303: gps_trk_type = pD303; break; - case 304: gps_trk_type = pD304; break; - case 310: gps_trk_hdr_type = pD310; break; - case 311: gps_trk_hdr_type = pD311; break; - case 312: gps_trk_hdr_type = pD312; break; - default: GPS_Protocol_Error(tag,data); break; - } - if (lasta==302 && gps_course_trk_transfer == pA302) - switch (data) { - case 300: gps_run_crs_trk_type = pD300; break; - case 301: gps_run_crs_trk_type = pD301; break; - case 302: gps_run_crs_trk_type = pD302; break; - case 303: gps_run_crs_trk_type = pD303; break; - case 304: gps_run_crs_trk_type = pD304; break; - case 310: gps_run_crs_trk_hdr_type = pD310; break; - case 311: gps_run_crs_trk_hdr_type = pD311; break; - case 312: gps_run_crs_trk_hdr_type = pD312; break; - default: GPS_Protocol_Error(tag,data); break; - } - continue; - } - - else if(lasta<500) - { - if((data<=110 && data>=100) || - (data<153 && data>=150) || - (data<156 && data>=154)) { - gps_prx_waypt_type = data; - } - else if(data==400) - gps_prx_waypt_type = pD400; - else if(data==403) - gps_prx_waypt_type = pD403; - else if(data==450) - gps_prx_waypt_type = pD450; - else - GPS_Protocol_Error(tag,data); - continue; - } - - else if(lasta<600) - { - if(data==500) - gps_almanac_type = pD500; - else if(data==501) - gps_almanac_type = pD501; - else if(data==550) - gps_almanac_type = pD550; - else if(data==551) - gps_almanac_type = pD551; - else - GPS_Protocol_Error(tag,data); - continue; - } - - else if(lasta<650) - { - if (data == 600) { - gps_date_time_type = pD600; - } else { - /* Stupid undocumented 60 D601 packets */ - /* GPS_Protocol_Error(tag,data); */ - continue; - } - continue; - } - - else if(lasta<651) - { - /* FlightBook Transfer Protocol, not handled */ - continue; - } - - else if(lasta<800) - { - if(data!=700) - GPS_Protocol_Error(tag,data); - else - gps_position_type = pD700; - continue; - } - - else if(lasta<900) - { - if (data == 800) - gps_pvt_type = pD800; - /* - * Stupid, undocumented Vista 3.60 D802 packets - else - GPS_Protocol_Error(tag,data); - */ - continue; - } - - else if (lasta < 1000) - { - if (data == 906) - gps_lap_type = pD906; - else if (data == 1001) - gps_lap_type = pD1001; - else if (data == 1011) - gps_lap_type = pD1011; - else if (data == 1015) - gps_lap_type = pD1015; - continue; - } - - else if (lasta < 1002) - { - if (data == 1000) - gps_run_type = pD1000; - else if (data == 1009) - gps_run_type = pD1009; - else if (data == 1010) - gps_run_type = pD1010; - continue; - } - - else if (lasta < 1003) - { - if (data == 1002) - gps_workout_type = pD1002; - else if (data == 1008) - gps_workout_type = pD1008; - continue; - } - - else if (lasta < 1004) - { - if (data == 1003) - gps_workout_occurrence_type = pD1003; - continue; - } - - else if (lasta < 1005) - { - if (data == 1004) - gps_user_profile_type = pD1004; - continue; - } - - else if (lasta < 1006) - { - if (data == 1005) - gps_workout_limits_type = pD1005; - continue; - } - - else if (lasta < 1007) - { - if (data == 1006) - gps_course_type = pD1006; - continue; - } - - else if (lasta < 1008) - { - if (data == 1007) - gps_course_lap_type = pD1007; - continue; - } - - else if (lasta < 1009) - { - if (data == 1012) - gps_course_point_type = pD1012; - continue; - } - - else if (lasta < 1010) - { - if (data == 1013) - gps_course_limits_type = pD1013; - continue; - } - else if (lasta == 1012) - { - /* We don't know which data types to expect for A1012. For now, - * accept the same ones as for A302 since it is used as a - * replacement for this. - */ - switch (data) { - case 300: gps_run_crs_trk_type = pD300; break; - case 301: gps_run_crs_trk_type = pD301; break; - case 302: gps_run_crs_trk_type = pD302; break; - case 303: gps_run_crs_trk_type = pD303; break; - case 304: gps_run_crs_trk_type = pD304; break; - case 310: gps_run_crs_trk_hdr_type = pD310; break; - case 311: gps_run_crs_trk_hdr_type = pD311; break; - case 312: gps_run_crs_trk_hdr_type = pD312; break; - default: GPS_Protocol_Error(tag,data); break; - } - continue; - } - } - } - - GPS_User("\nLink_type %d Device_command %d\n", - gps_link_type, gps_device_command); - GPS_User("Waypoint: Transfer %d Type %d\n", - gps_waypt_transfer, gps_waypt_type); - GPS_User("Route: Transfer %d Header %d Type %d\n", - gps_route_transfer, gps_rte_hdr_type, gps_rte_type); - GPS_User("Track: Transfer %d Type %d\n", - gps_trk_transfer, gps_trk_type); + int32 entries; + int32 i; + UC* p; + US tag; + US data; + US lasta=0; + + entries = packet->n / 3; + p = packet->data; + + for (i=0; i=200 && data <=202) { + gps_rte_hdr_type = data; + continue; + } + if (data==210) { + gps_rte_link_type = data; + continue; + } + + if (data<=110 && data>=100) { + gps_rte_type = data; + continue; + } + if (data<153 && data>=150) { + gps_rte_type = data; + continue; + } + if (data<156 && data>=154) { + gps_rte_type = data; + continue; + } + if (data<451) { + if (data==400) { + gps_rte_type = pD400; + } else if (data==403) { + gps_rte_type = pD403; + } else if (data==450) { + gps_rte_type = pD450; + } else { + GPS_Protocol_Error(tag,data); + } + continue; + } + } + + else if (lasta<400) { + switch (data) { + case 300: + gps_trk_type = pD300; + break; + case 301: + gps_trk_type = pD301; + break; + case 302: + gps_trk_type = pD302; + break; + case 303: + gps_trk_type = pD303; + break; + case 304: + gps_trk_type = pD304; + break; + case 310: + gps_trk_hdr_type = pD310; + break; + case 311: + gps_trk_hdr_type = pD311; + break; + case 312: + gps_trk_hdr_type = pD312; + break; + default: + GPS_Protocol_Error(tag,data); + break; + } + if (lasta==302 && gps_course_trk_transfer == pA302) + switch (data) { + case 300: + gps_run_crs_trk_type = pD300; + break; + case 301: + gps_run_crs_trk_type = pD301; + break; + case 302: + gps_run_crs_trk_type = pD302; + break; + case 303: + gps_run_crs_trk_type = pD303; + break; + case 304: + gps_run_crs_trk_type = pD304; + break; + case 310: + gps_run_crs_trk_hdr_type = pD310; + break; + case 311: + gps_run_crs_trk_hdr_type = pD311; + break; + case 312: + gps_run_crs_trk_hdr_type = pD312; + break; + default: + GPS_Protocol_Error(tag,data); + break; + } + continue; + } + + else if (lasta<500) { + if ((data<=110 && data>=100) || + (data<153 && data>=150) || + (data<156 && data>=154)) { + gps_prx_waypt_type = data; + } else if (data==400) { + gps_prx_waypt_type = pD400; + } else if (data==403) { + gps_prx_waypt_type = pD403; + } else if (data==450) { + gps_prx_waypt_type = pD450; + } else { + GPS_Protocol_Error(tag,data); + } + continue; + } + + else if (lasta<600) { + if (data==500) { + gps_almanac_type = pD500; + } else if (data==501) { + gps_almanac_type = pD501; + } else if (data==550) { + gps_almanac_type = pD550; + } else if (data==551) { + gps_almanac_type = pD551; + } else { + GPS_Protocol_Error(tag,data); + } + continue; + } + + else if (lasta<650) { + if (data == 600) { + gps_date_time_type = pD600; + } else { + /* Stupid undocumented 60 D601 packets */ + /* GPS_Protocol_Error(tag,data); */ + continue; + } + continue; + } + + else if (lasta<651) { + /* FlightBook Transfer Protocol, not handled */ + continue; + } + + else if (lasta<800) { + if (data!=700) { + GPS_Protocol_Error(tag,data); + } else { + gps_position_type = pD700; + } + continue; + } + + else if (lasta<900) { + if (data == 800) { + gps_pvt_type = pD800; + } + /* + * Stupid, undocumented Vista 3.60 D802 packets + else + GPS_Protocol_Error(tag,data); + */ + continue; + } + + else if (lasta < 1000) { + if (data == 906) { + gps_lap_type = pD906; + } else if (data == 1001) { + gps_lap_type = pD1001; + } else if (data == 1011) { + gps_lap_type = pD1011; + } else if (data == 1015) { + gps_lap_type = pD1015; + } + continue; + } + + else if (lasta < 1002) { + if (data == 1000) { + gps_run_type = pD1000; + } else if (data == 1009) { + gps_run_type = pD1009; + } else if (data == 1010) { + gps_run_type = pD1010; + } + continue; + } + + else if (lasta < 1003) { + if (data == 1002) { + gps_workout_type = pD1002; + } else if (data == 1008) { + gps_workout_type = pD1008; + } + continue; + } + + else if (lasta < 1004) { + if (data == 1003) { + gps_workout_occurrence_type = pD1003; + } + continue; + } + + else if (lasta < 1005) { + if (data == 1004) { + gps_user_profile_type = pD1004; + } + continue; + } + + else if (lasta < 1006) { + if (data == 1005) { + gps_workout_limits_type = pD1005; + } + continue; + } + + else if (lasta < 1007) { + if (data == 1006) { + gps_course_type = pD1006; + } + continue; + } + + else if (lasta < 1008) { + if (data == 1007) { + gps_course_lap_type = pD1007; + } + continue; + } + + else if (lasta < 1009) { + if (data == 1012) { + gps_course_point_type = pD1012; + } + continue; + } + + else if (lasta < 1010) { + if (data == 1013) { + gps_course_limits_type = pD1013; + } + continue; + } else if (lasta == 1012) { + /* We don't know which data types to expect for A1012. For now, + * accept the same ones as for A302 since it is used as a + * replacement for this. + */ + switch (data) { + case 300: + gps_run_crs_trk_type = pD300; + break; + case 301: + gps_run_crs_trk_type = pD301; + break; + case 302: + gps_run_crs_trk_type = pD302; + break; + case 303: + gps_run_crs_trk_type = pD303; + break; + case 304: + gps_run_crs_trk_type = pD304; + break; + case 310: + gps_run_crs_trk_hdr_type = pD310; + break; + case 311: + gps_run_crs_trk_hdr_type = pD311; + break; + case 312: + gps_run_crs_trk_hdr_type = pD312; + break; + default: + GPS_Protocol_Error(tag,data); + break; + } + continue; + } + } + } + + GPS_User("\nLink_type %d Device_command %d\n", + gps_link_type, gps_device_command); + GPS_User("Waypoint: Transfer %d Type %d\n", + gps_waypt_transfer, gps_waypt_type); + GPS_User("Route: Transfer %d Header %d Type %d\n", + gps_route_transfer, gps_rte_hdr_type, gps_rte_type); + GPS_User("Track: Transfer %d Type %d\n", + gps_trk_transfer, gps_trk_type); + + return; } @@ -802,148 +859,147 @@ static void GPS_A001(GPS_PPacket packet) ** ** @return [int32] number of waypoint entries ************************************************************************/ -int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) +int32 GPS_A100_Get(const char* port, GPS_PWay** way, int (*cb)(int, GPS_PWay*)) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - - if(!GPS_Write_Packet(fd,tra)) - { - GPS_Error("A100_Get: Cannot write packet"); - return FRAMING_ERROR; - } - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A100_Get: No acknowledge"); - return FRAMING_ERROR; - } - - GPS_Packet_Read(fd, &rec); - GPS_Send_Ack(fd, &tra, &rec); - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) - { - GPS_Error("A100_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata); - break; - case pD101: - GPS_D101_Get(&((*way)[i]),rec->data); - break; - case pD102: - GPS_D102_Get(&((*way)[i]),rec->data); - break; - case pD103: - GPS_D103_Get(&((*way)[i]),rec->data); - break; - case pD104: - GPS_D104_Get(&((*way)[i]),rec->data); - break; - case pD105: - GPS_D105_Get(&((*way)[i]),rec->data); - break; - case pD106: - GPS_D106_Get(&((*way)[i]),rec->data); - break; - case pD107: - GPS_D107_Get(&((*way)[i]),rec->data); - break; - case pD108: - GPS_D108_Get(&((*way)[i]),rec->data); - break; - case pD109: - GPS_D109_Get(&((*way)[i]),rec->data, 109); - break; - case pD110: - GPS_D109_Get(&((*way)[i]),rec->data, 110); - break; - case pD150: - GPS_D150_Get(&((*way)[i]),rec->data); - break; - case pD151: - GPS_D151_Get(&((*way)[i]),rec->data); - break; - case pD152: - GPS_D152_Get(&((*way)[i]),rec->data); - break; - case pD154: - GPS_D154_Get(&((*way)[i]),rec->data); - break; - case pD155: - GPS_D155_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A100_GET: Unknown waypoint protocol: %d", gps_waypt_type); - return PROTOCOL_ERROR; - } - /* Issue callback for status updates. */ - if (cb) { - cb(n, &((*way)[i])); - } - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A100_GET: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A100_GET: Waypoint entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + + if (!GPS_Write_Packet(fd,tra)) { + GPS_Error("A100_Get: Cannot write packet"); + return FRAMING_ERROR; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A100_Get: No acknowledge"); + return FRAMING_ERROR; + } + + GPS_Packet_Read(fd, &rec); + GPS_Send_Ack(fd, &tra, &rec); + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*way)=(GPS_PWay*)malloc(n*sizeof(GPS_PWay)))) { + GPS_Error("A100_Get: Insufficient memory"); + return MEMORY_ERROR; } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + for (i=0; idata); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data, 109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data, 110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A100_GET: Unknown waypoint protocol: %d", gps_waypt_type); + return PROTOCOL_ERROR; + } + /* Issue callback for status updates. */ + if (cb) { + cb(n, &((*way)[i])); + } + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A100_GET: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A100_GET: Waypoint entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return n; + return n; } @@ -960,198 +1016,202 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)) +int32 GPS_A100_Send(const char* port, GPS_PWay* way, int32 n, int (*cb)(GPS_PWay*)) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, (short) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("Waypoint start data not acknowledged"); - return gps_errno; - } - - - for(i=0;idata); + for (i = 0; i < n; ++i) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; } - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A101_Get: No acknowledge"); - return FRAMING_ERROR; + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; } - - GPS_Packet_Read(fd, &rec); - GPS_Send_Ack(fd, &tra, &rec); - - n = GPS_Util_Get_Short(rec->data); - for (i = 0; i < n; ++i) { - if(!GPS_Packet_Read(fd, &rec)) { - return gps_errno; - } - if(!GPS_Send_Ack(fd, &tra, &rec)) { - return gps_errno; - } - switch(gps_category_type) { - case pD120: - GPS_D120_Get(i,(char *) rec->data); - break; - } + switch (gps_category_type) { + case pD120: + GPS_D120_Get(i,(char*) rec->data); + break; } - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; + } + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A101_Get: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); - return FRAMING_ERROR; - } + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A101_Get: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); + return FRAMING_ERROR; + } - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -1164,27 +1224,31 @@ int32 GPS_A101_Get(const char *port) ** ** @return [void] ************************************************************************/ -static void GPS_D100_Get(GPS_PWay *way, UC *s) +static void GPS_D100_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 100; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 100; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - return; + return; } @@ -1198,32 +1262,36 @@ static void GPS_D100_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D101_Get(GPS_PWay *way, UC *s) +static void GPS_D101_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 101; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 101; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*way)->smbl = *p; + (*way)->smbl = *p; - return; + return; } @@ -1237,33 +1305,37 @@ static void GPS_D101_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D102_Get(GPS_PWay *way, UC *s) +static void GPS_D102_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 102; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 102; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*way)->smbl = GPS_Util_Get_Short(p); + (*way)->smbl = GPS_Util_Get_Short(p); - return; + return; } @@ -1277,31 +1349,35 @@ static void GPS_D102_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D103_Get(GPS_PWay *way, UC *s) +static void GPS_D103_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 103; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 103; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->smbl = *p++; - (*way)->dspl = *p; + (*way)->smbl = *p++; + (*way)->dspl = *p; - return; + return; } @@ -1315,35 +1391,39 @@ static void GPS_D103_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D104_Get(GPS_PWay *way, UC *s) +static void GPS_D104_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 104; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 104; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*way)->dspl = *p; + (*way)->dspl = *p; - return; + return; } @@ -1357,28 +1437,28 @@ static void GPS_D104_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D105_Get(GPS_PWay *way, UC *s) +static void GPS_D105_Get(GPS_PWay* way, UC* s) { - UC *p; - UC *q; + UC* p; + UC* q; - p=s; + p=s; - (*way)->prot = 105; + (*way)->prot = 105; - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); - q = (UC *) (*way)->wpt_ident; - while((*q++ = *p++)); + q = (UC*)(*way)->wpt_ident; + while ((*q++ = *p++)); - return; + return; } @@ -1392,35 +1472,37 @@ static void GPS_D105_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -void GPS_D106_Get(GPS_PWay *way, UC *s) +void GPS_D106_Get(GPS_PWay* way, UC* s) { - UC *p; - UC *q; - int32 i; + UC* p; + UC* q; + int32 i; - p=s; + p=s; - (*way)->prot = 106; + (*way)->prot = 106; - (*way)->wpt_class = *p++; + (*way)->wpt_class = *p++; - for(i=0;i<13;++i) (*way)->subclass[i] = *p++; + for (i=0; i<13; ++i) { + (*way)->subclass[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); - q = (UC *) (*way)->wpt_ident; - while((*q++ = *p++)); - q = (UC *) (*way)->lnk_ident; - while((*q++ = *p++)); + q = (UC*)(*way)->wpt_ident; + while ((*q++ = *p++)); + q = (UC*)(*way)->lnk_ident; + while ((*q++ = *p++)); - return; + return; } @@ -1434,35 +1516,39 @@ void GPS_D106_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D107_Get(GPS_PWay *way, UC *s) +static void GPS_D107_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 107; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 107; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->smbl = *p++; - (*way)->dspl = *p++; + (*way)->smbl = *p++; + (*way)->dspl = *p++; - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*way)->colour = *p++; + (*way)->colour = *p++; - return; + return; } @@ -1476,60 +1562,66 @@ static void GPS_D107_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D108_Get(GPS_PWay *way, UC *s) +static void GPS_D108_Get(GPS_PWay* way, UC* s) { - UC *p; - UC *q; + UC* p; + UC* q; - int32 i; + int32 i; - p=s; + p=s; - (*way)->prot = 108; + (*way)->prot = 108; - (*way)->wpt_class = *p++; - (*way)->colour = *p++; - (*way)->dspl = *p++; - (*way)->attr = *p++; - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); - for(i=0;i<18;++i) (*way)->subclass[i] = *p++; + (*way)->wpt_class = *p++; + (*way)->colour = *p++; + (*way)->dspl = *p++; + (*way)->attr = *p++; + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + (*way)->subclass[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); - (*way)->dpth = GPS_Util_Get_Float(p); - p+=sizeof(float); - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<2;++i) (*way)->state[i] = *p++; - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - q = (UC *) (*way)->ident; - while((*q++ = *p++)); + q = (UC*)(*way)->ident; + while ((*q++ = *p++)); - q = (UC *) (*way)->cmnt; - while((*q++ = *p++)); + q = (UC*)(*way)->cmnt; + while ((*q++ = *p++)); - q = (UC *) (*way)->facility; - while((*q++ = *p++)); + q = (UC*)(*way)->facility; + while ((*q++ = *p++)); - q = (UC *) (*way)->city; - while((*q++ = *p++)); + q = (UC*)(*way)->city; + while ((*q++ = *p++)); - q = (UC *) (*way)->addr; - while((*q++ = *p++)); + q = (UC*)(*way)->addr; + while ((*q++ = *p++)); - q = (UC *) (*way)->cross_road; - while((*q++ = *p++)); + q = (UC*)(*way)->cross_road; + while ((*q++ = *p++)); - return; + return; } /* @funcstatic GPS_D109_Get ******************************************** @@ -1544,85 +1636,91 @@ static void GPS_D108_Get(GPS_PWay *way, UC *s) ** of temp, time, and wpt_cat stuck between ete and ident. Rather than ** duplicating the function, we just handle this at runtime. ************************************************************************/ -static void GPS_D109_Get(GPS_PWay *way, UC *s, int protoid) +static void GPS_D109_Get(GPS_PWay* way, UC* s, int protoid) { - UC *p; - UC *q; - - int32 i; - - p=s; - - (*way)->prot = protoid; - - p++; /* data packet type */ - (*way)->wpt_class = *p++; - (*way)->colour = *p & 0x1f; - (*way)->dspl = (*p++ >> 5) & 3; - (*way)->attr = *p++; - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); - for(i=0;i<18;++i) (*way)->subclass[i] = *p++; - - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*way)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); - (*way)->dpth = GPS_Util_Get_Float(p); - p+=sizeof(float); - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); - - for(i=0;i<2;++i) (*way)->state[i] = *p++; - for(i=0;i<2;++i) (*way)->cc[i] = *p++; - - p += 4; /* Skip over "outbound link ete in seconds */ - if (protoid == 110) { - float gps_temp; - int gps_time; - gps_temp = GPS_Util_Get_Float(p); - p+=4; - if (gps_temp <= 1.0e24) { - (*way)->temperature_populated = 1; - (*way)->temperature = gps_temp; - } + UC* p; + UC* q; + + int32 i; + + p=s; + + (*way)->prot = protoid; + + p++; /* data packet type */ + (*way)->wpt_class = *p++; + (*way)->colour = *p & 0x1f; + (*way)->dspl = (*p++ >> 5) & 3; + (*way)->attr = *p++; + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + (*way)->subclass[i] = *p++; + } + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } + + p += 4; /* Skip over "outbound link ete in seconds */ + if (protoid == 110) { + float gps_temp; + int gps_time; + gps_temp = GPS_Util_Get_Float(p); + p+=4; + if (gps_temp <= 1.0e24) { + (*way)->temperature_populated = 1; + (*way)->temperature = gps_temp; + } - gps_time = GPS_Util_Get_Uint(p); - p+=4; - /* The spec says that 0xffffffff is unknown, but the 60CSX with - * firmware 2.5.0 writes zero. - */ - if (gps_time != 0xffffffff && gps_time != 0) { - (*way)->time_populated = 1; - (*way)->time = GPS_Math_Gtime_To_Utime(gps_time); - } - (*way)->category = GPS_Util_Get_Short(p); - p += 2; + gps_time = GPS_Util_Get_Uint(p); + p+=4; + /* The spec says that 0xffffffff is unknown, but the 60CSX with + * firmware 2.5.0 writes zero. + */ + if (gps_time != 0xffffffff && gps_time != 0) { + (*way)->time_populated = 1; + (*way)->time = GPS_Math_Gtime_To_Utime(gps_time); } + (*way)->category = GPS_Util_Get_Short(p); + p += 2; + } - q = (UC *) (*way)->ident; - while((*q++ = *p++)); + q = (UC*)(*way)->ident; + while ((*q++ = *p++)); - q = (UC *) (*way)->cmnt; - while((*q++ = *p++)); + q = (UC*)(*way)->cmnt; + while ((*q++ = *p++)); - q = (UC *) (*way)->facility; - while((*q++ = *p++)); + q = (UC*)(*way)->facility; + while ((*q++ = *p++)); - q = (UC *) (*way)->city; - while((*q++ = *p++)); + q = (UC*)(*way)->city; + while ((*q++ = *p++)); - q = (UC *) (*way)->addr; - while((*q++ = *p++)); + q = (UC*)(*way)->addr; + while ((*q++ = *p++)); - q = (UC *) (*way)->cross_road; - while((*q++ = *p++)); + q = (UC*)(*way)->cross_road; + while ((*q++ = *p++)); - return; + return; } @@ -1635,33 +1733,45 @@ static void GPS_D109_Get(GPS_PWay *way, UC *s, int protoid) ** ** @return [void] ************************************************************************/ -static void GPS_D150_Get(GPS_PWay *way, UC *s) +static void GPS_D150_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; - - p=s; - - (*way)->prot = 150; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; - for(i=0;i<2;++i) (*way)->cc[i] = *p++; - (*way)->wpt_class = *p++; - - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); - - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; - - return; + UC* p; + int32 i; + + p=s; + + (*way)->prot = 150; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } + (*way)->wpt_class = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } + + return; } @@ -1675,43 +1785,55 @@ static void GPS_D150_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D151_Get(GPS_PWay *way, UC *s) +static void GPS_D151_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 151; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 151; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - ++p; + ++p; - (*way)->wpt_class = *p; + (*way)->wpt_class = *p; - return; + return; } @@ -1725,43 +1847,55 @@ static void GPS_D151_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D152_Get(GPS_PWay *way, UC *s) +static void GPS_D152_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 152; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 152; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - ++p; + ++p; - (*way)->wpt_class = *p; + (*way)->wpt_class = *p; - return; + return; } @@ -1774,45 +1908,57 @@ static void GPS_D152_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D154_Get(GPS_PWay *way, UC *s) +static void GPS_D154_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 154; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 154; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - ++p; + ++p; - (*way)->wpt_class = *p++; + (*way)->wpt_class = *p++; - (*way)->smbl = GPS_Util_Get_Short(p); + (*way)->smbl = GPS_Util_Get_Short(p); - return; + return; } @@ -1825,48 +1971,60 @@ static void GPS_D154_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D155_Get(GPS_PWay *way, UC *s) +static void GPS_D155_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 155; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 155; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - ++p; + ++p; - (*way)->wpt_class = *p++; + (*way)->wpt_class = *p++; - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*way)->dspl = *p; + (*way)->dspl = *p; - return; + return; } /* @@ -1879,21 +2037,21 @@ char gps_categories[16][17]; * Read descriptor s into category number N; */ static -void GPS_D120_Get(int cat_num, char *s) +void GPS_D120_Get(int cat_num, char* s) { - /* we're guaranteed to have no more than 16 chars plus a - * null terminator. - * - * If the unit returned no string, the user has not configured one, - * so mimic the behaviour of the 276/296. - */ - - if (*s) { - strncpy(gps_categories[cat_num], s, sizeof (gps_categories[0])); - } else { - snprintf(gps_categories[cat_num], sizeof (gps_categories[0]), - "Category %d", cat_num+1); - } + /* we're guaranteed to have no more than 16 chars plus a + * null terminator. + * + * If the unit returned no string, the user has not configured one, + * so mimic the behaviour of the 276/296. + */ + + if (*s) { + strncpy(gps_categories[cat_num], s, sizeof(gps_categories[0])); + } else { + snprintf(gps_categories[cat_num], sizeof(gps_categories[0]), + "Category %d", cat_num+1); + } } @@ -1907,24 +2065,24 @@ void GPS_D120_Get(int cat_num, char *s) ** ** @return [void] ************************************************************************/ -static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D100_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; + UC* p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - *len = 58; + *len = 58; - return; + return; } @@ -1938,30 +2096,30 @@ static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D101_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; + UC* p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+= sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); - *p = way->smbl; + *p = way->smbl; - *len = 63; + *len = 63; - return; + return; } @@ -1975,29 +2133,29 @@ static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D102_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; + UC* p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+= sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); - GPS_Util_Put_Short(p,(US) way->smbl); + GPS_Util_Put_Short(p,(US) way->smbl); - *len = 64; + *len = 64; - return; + return; } @@ -2011,28 +2169,28 @@ static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D103_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; + UC* p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - *p++ = (UC) way->smbl; - *p = (UC) way->dspl; + *p++ = (UC) way->smbl; + *p = (UC) way->dspl; - *len = 60; + *len = 60; - return; + return; } @@ -2046,36 +2204,36 @@ static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D104_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - - p = data; - - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - /* byonke confirms that sending lower case comment data to a III+ - * results in the comment being truncated there. So we uppercase - * the entire comment. - */ - copy_char_array(&p, way->cmnt, 40, UpperYes); + UC* p; - GPS_Util_Put_Float(p,way->dst); - p+= sizeof(float); + p = data; - GPS_Util_Put_Short(p, (int16) way->smbl); - p+=sizeof(int16); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + /* byonke confirms that sending lower case comment data to a III+ + * results in the comment being truncated there. So we uppercase + * the entire comment. + */ + copy_char_array(&p, way->cmnt, 40, UpperYes); - *p = 3; /* display symbol with waypoint name */ + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); - *len = 65; + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); - return; + *p = 3; /* display symbol with waypoint name */ + + *len = 65; + + return; } @@ -2089,28 +2247,28 @@ static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D105_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D105_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - UC *q; + UC* p; + UC* q; - p = data; + p = data; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); - GPS_Util_Put_Short(p, (int16) way->smbl); - p+=sizeof(int16); + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); - q = (UC *) way->wpt_ident; - while((*p++ = *q++)); + q = (UC*) way->wpt_ident; + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -2124,32 +2282,34 @@ static void GPS_D105_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D106_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - UC *q; - int32 i; + UC* p; + UC* q; + int32 i; - p = data; + p = data; - *p++ = way->wpt_class; - for(i=0;i<13;++i) *p++ = way->subclass[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); + *p++ = way->wpt_class; + for (i=0; i<13; ++i) { + *p++ = way->subclass[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); - GPS_Util_Put_Short(p, (int16) way->smbl); - p+=sizeof(int16); + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); - q = (UC *) way->wpt_ident; - while((*p++ = *q++)); - q = (UC *) way->lnk_ident; - while((*p++ = *q++)); + q = (UC*) way->wpt_ident; + while ((*p++ = *q++)); + q = (UC*) way->lnk_ident; + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -2163,32 +2323,32 @@ static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D107_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; + UC* p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - *p++ = way->smbl; - *p++ = way->dspl; + *p++ = way->smbl; + *p++ = way->dspl; - GPS_Util_Put_Float(p,way->dst); - p+= sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); - *p = way->colour; + *p = way->colour; - *len = 65; + *len = 65; - return; + return; } @@ -2203,64 +2363,70 @@ static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D108_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - UC *q; - - int32 i; - - p = data; - - *p++ = way->wpt_class; - *p++ = way->colour; - *p++ = way->dspl; - *p++ = 0x60; - GPS_Util_Put_Short(p,(US) way->smbl); - p+=sizeof(int16); - for(i=0;i<18;++i) *p++ = way->subclass[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - - if (way->alt_is_unknown) { - GPS_Util_Put_Float(p,(const float) 1.0e25); - } else { - GPS_Util_Put_Float(p,way->alt); - } - p+=sizeof(float); - GPS_Util_Put_Float(p,way->dpth); - p+=sizeof(float); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); - - for(i=0;i<2;++i) *p++ = way->state[i]; - for(i=0;i<2;++i) *p++ = way->cc[i]; - - - q = (UC *) way->ident; - i = XMIN(51, sizeof(way->ident)); - while((*p++ = *q++) && i--); - q = (UC *) way->cmnt; - i = XMIN(51, sizeof(way->cmnt)); - while((*p++ = *q++) && i--); - q = (UC *) way->facility; - i = XMIN(31, sizeof(way->facility)); - while((*p++ = *q++) && i--); - q = (UC *) way->city; - i = XMIN(25, sizeof(way->city)); - while((*p++ = *q++) && i--); - q = (UC *) way->addr; - i = XMIN(51, sizeof(way->addr)); - while((*p++ = *q++) && i--); - q = (UC *) way->cross_road; - i = XMIN(51, sizeof(way->cross_road)); - while((*p++ = *q++) && i--); - - *len = p-data; - - return; + UC* p; + UC* q; + + int32 i; + + p = data; + + *p++ = way->wpt_class; + *p++ = way->colour; + *p++ = way->dspl; + *p++ = 0x60; + GPS_Util_Put_Short(p,(US) way->smbl); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + *p++ = way->subclass[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + + if (way->alt_is_unknown) { + GPS_Util_Put_Float(p,(const float) 1.0e25); + } else { + GPS_Util_Put_Float(p,way->alt); + } + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dpth); + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + for (i=0; i<2; ++i) { + *p++ = way->state[i]; + } + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + + + q = (UC*) way->ident; + i = XMIN(51, sizeof(way->ident)); + while ((*p++ = *q++) && i--); + q = (UC*) way->cmnt; + i = XMIN(51, sizeof(way->cmnt)); + while ((*p++ = *q++) && i--); + q = (UC*) way->facility; + i = XMIN(31, sizeof(way->facility)); + while ((*p++ = *q++) && i--); + q = (UC*) way->city; + i = XMIN(25, sizeof(way->city)); + while ((*p++ = *q++) && i--); + q = (UC*) way->addr; + i = XMIN(51, sizeof(way->addr)); + while ((*p++ = *q++) && i--); + q = (UC*) way->cross_road; + i = XMIN(51, sizeof(way->cross_road)); + while ((*p++ = *q++) && i--); + + *len = p-data; + + return; } @@ -2275,85 +2441,95 @@ static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len) ** @return [void] ** D109's and D110's are so simlar, we handle themw with the same code. ************************************************************************/ -static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid) +static void GPS_D109_Send(UC* data, GPS_PWay way, int32* len, int protoid) { - UC *p; - UC *q; - - int32 i; - - p = data; - - *p++ = 1; /* data packet type; must be 1 for D109 and D110 */ - *p++ = way->wpt_class; - - *p++ = ((way->dspl & 3) << 5) | 0x1f; /* colour & display */ - - if (protoid == 109) { /* attr */ - *p++ = 0x70; - } else if (protoid == 110) { - *p++ = 0x80; + UC* p; + UC* q; + + int32 i; + + p = data; + + *p++ = 1; /* data packet type; must be 1 for D109 and D110 */ + *p++ = way->wpt_class; + + *p++ = ((way->dspl & 3) << 5) | 0x1f; /* colour & display */ + + if (protoid == 109) { /* attr */ + *p++ = 0x70; + } else if (protoid == 110) { + *p++ = 0x80; + } else { + GPS_Warning("Unknown protoid in GPS_D109_Send."); + } + GPS_Util_Put_Short(p,(US) way->smbl); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + *p++ = way->subclass[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + if (way->alt_is_unknown) { + GPS_Util_Put_Float(p,(const float) 1.0e25); + } else { + GPS_Util_Put_Float(p,way->alt); + } + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dpth); + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + for (i=0; i<2; ++i) { + *p++ = way->state[i]; + } + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + for (i=0; i<4; ++i) { + *p++ = 0xff; /* D109 silliness for ETE */ + } + if (protoid == 110) { + float temp = 1.0e25f; + + GPS_Util_Put_Float(p, temp); + p += 4; + + if (way->time_populated) { + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(way->time)); + p+=sizeof(uint32); } else { - GPS_Warning("Unknown protoid in GPS_D109_Send."); + for (i=0; i<4; ++i) { + *p++ = 0xff; /* unknown time*/ + } } - GPS_Util_Put_Short(p,(US) way->smbl); - p+=sizeof(int16); - for(i=0;i<18;++i) *p++ = way->subclass[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - if (way->alt_is_unknown) { - GPS_Util_Put_Float(p,(const float) 1.0e25); - } else { - GPS_Util_Put_Float(p,way->alt); - } - p+=sizeof(float); - GPS_Util_Put_Float(p,way->dpth); - p+=sizeof(float); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); - for(i=0;i<2;++i) *p++ = way->state[i]; - for(i=0;i<2;++i) *p++ = way->cc[i]; - for(i=0;i<4;++i) *p++ = 0xff; /* D109 silliness for ETE */ - if (protoid == 110) { - float temp = 1.0e25f; - - GPS_Util_Put_Float(p, temp); - p += 4; - - if (way->time_populated) { - GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(way->time)); - p+=sizeof(uint32); - } else { - for(i=0;i<4;++i) *p++ = 0xff; /* unknown time*/ - } - - GPS_Util_Put_Short(p, (US) way->category);; /* D110 category */ - p += 2; - } - - q = (UC *) way->ident; - i = XMIN(51, sizeof(way->ident)); - while((*p++ = *q++) && i--); - q = (UC *) way->cmnt; - i = XMIN(51, sizeof(way->cmnt)); - while((*p++ = *q++) && i--); - q = (UC *) way->facility; - i = XMIN(31, sizeof(way->facility)); - while((*p++ = *q++) && i--); - q = (UC *) way->city; - i = XMIN(25, sizeof(way->city)); - while((*p++ = *q++) && i--); - q = (UC *) way->addr; - i = XMIN(51, sizeof(way->addr)); - while((*p++ = *q++) && i--); - q = (UC *) way->cross_road; - i = XMIN(51, sizeof(way->cross_road)); - while((*p++ = *q++) && i--); - *len = p-data; - return; + GPS_Util_Put_Short(p, (US) way->category);; /* D110 category */ + p += 2; + } + + q = (UC*) way->ident; + i = XMIN(51, sizeof(way->ident)); + while ((*p++ = *q++) && i--); + q = (UC*) way->cmnt; + i = XMIN(51, sizeof(way->cmnt)); + while ((*p++ = *q++) && i--); + q = (UC*) way->facility; + i = XMIN(31, sizeof(way->facility)); + while ((*p++ = *q++) && i--); + q = (UC*) way->city; + i = XMIN(25, sizeof(way->city)); + while ((*p++ = *q++) && i--); + q = (UC*) way->addr; + i = XMIN(51, sizeof(way->addr)); + while ((*p++ = *q++) && i--); + q = (UC*) way->cross_road; + i = XMIN(51, sizeof(way->cross_road)); + while ((*p++ = *q++) && i--); + *len = p-data; + return; } @@ -2367,35 +2543,39 @@ static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid) ** ** @return [void] ************************************************************************/ -static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D150_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - int32 i; + UC* p; + int32 i; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - for(i=0;i<2;++i) *p++ = way->cc[i]; + copy_char_array(&p, way->ident, 6, UpperYes); + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } - if(way->wpt_class == 7) way->wpt_class = 0; - *p++ = way->wpt_class; + if (way->wpt_class == 7) { + way->wpt_class = 0; + } + *p++ = way->wpt_class; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->cmnt, 40, UpperYes); - *len = 115; + *len = 115; - return; + return; } @@ -2409,41 +2589,45 @@ static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D151_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - int32 i; + UC* p; + int32 i; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - for(i=0;i<2;++i) *p++ = way->cc[i]; - *p++ = 0; + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + *p++ = 0; - if(way->wpt_class == 3) way->wpt_class = 0; - *p = way->wpt_class; + if (way->wpt_class == 3) { + way->wpt_class = 0; + } + *p = way->wpt_class; - *len = 124; + *len = 124; - return; + return; } @@ -2458,41 +2642,45 @@ static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D152_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - int32 i; + UC* p; + int32 i; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - for(i=0;i<2;++i) *p++ = way->cc[i]; - *p++ = 0; + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + *p++ = 0; - if(way->wpt_class == 5) way->wpt_class = 0; - *p = way->wpt_class; + if (way->wpt_class == 5) { + way->wpt_class = 0; + } + *p = way->wpt_class; - *len = 124; + *len = 124; - return; + return; } @@ -2506,44 +2694,48 @@ static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D154_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - int32 i; + UC* p; + int32 i; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - for(i=0;i<2;++i) *p++ = way->cc[i]; - *p++ = 0; + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + *p++ = 0; - if(way->wpt_class == 9) way->wpt_class = 0; - *p++ = way->wpt_class; + if (way->wpt_class == 9) { + way->wpt_class = 0; + } + *p++ = way->wpt_class; - GPS_Util_Put_Short(p,(int16)way->smbl); + GPS_Util_Put_Short(p,(int16)way->smbl); - *len = 126; + *len = 126; - return; + return; } @@ -2558,45 +2750,45 @@ static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D155_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; + UC* p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - copy_char_array(&p, way->cc, 2, UpperYes); - *p++ = 0; + copy_char_array(&p, way->cc, 2, UpperYes); + *p++ = 0; - /* Ignore wpt_class; our D155 points are always user type which is "4". */ - *p++ = 4; + /* Ignore wpt_class; our D155 points are always user type which is "4". */ + *p++ = 4; - GPS_Util_Put_Short(p,(int16)way->smbl); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(int16)way->smbl); + p+=sizeof(int16); - *p = way->dspl; + *p = way->dspl; - *len = 127; + *len = 127; - return; + return; } @@ -2610,168 +2802,172 @@ static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [int32] number of waypoint entries ************************************************************************/ -int32 GPS_A200_Get(const char *port, GPS_PWay **way) +int32 GPS_A200_Get(const char* port, GPS_PWay** way) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) - { - GPS_Error("A200_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - - for(i=0;itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) - { - switch(gps_rte_hdr_type) - { - case pD200: - GPS_D200_Get(&((*way)[i]),rec->data); - break; - case pD201: - GPS_D201_Get(&((*way)[i]),rec->data); - break; - case pD202: - GPS_D202_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A200_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - continue; - } - - if(rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) - { - GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); - return FRAMING_ERROR; - } - - (*way)[i]->isrte = 0; - (*way)[i]->islink = 0; - - switch(gps_rte_type) - { - case pD100: - GPS_D100_Get(&((*way)[i]),rec->data); - break; - case pD101: - GPS_D101_Get(&((*way)[i]),rec->data); - break; - case pD102: - GPS_D102_Get(&((*way)[i]),rec->data); - break; - case pD103: - GPS_D103_Get(&((*way)[i]),rec->data); - break; - case pD104: - GPS_D104_Get(&((*way)[i]),rec->data); - break; - case pD105: - GPS_D105_Get(&((*way)[i]),rec->data); - break; - case pD106: - GPS_D106_Get(&((*way)[i]),rec->data); - break; - case pD107: - GPS_D107_Get(&((*way)[i]),rec->data); - break; - case pD108: - GPS_D108_Get(&((*way)[i]),rec->data); - break; - case pD109: - GPS_D109_Get(&((*way)[i]),rec->data,109); - break; - case pD110: - GPS_D109_Get(&((*way)[i]),rec->data,110); - break; - case pD150: - GPS_D150_Get(&((*way)[i]),rec->data); - break; - case pD151: - GPS_D151_Get(&((*way)[i]),rec->data); - break; - case pD152: - GPS_D152_Get(&((*way)[i]),rec->data); - break; - case pD154: - GPS_D154_Get(&((*way)[i]),rec->data); - break; - case pD155: - GPS_D155_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A200_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (*way)[i-1]->prot = (*way)[i]->prot; - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A200_GET: Error transferring routes"); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A200_GET: Route entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*way)=(GPS_PWay*)malloc(n*sizeof(GPS_PWay)))) { + GPS_Error("A200_Get: Insufficient memory"); + return MEMORY_ERROR; } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + for (i=0; itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) { + switch (gps_rte_hdr_type) { + case pD200: + GPS_D200_Get(&((*way)[i]),rec->data); + break; + case pD201: + GPS_D201_Get(&((*way)[i]),rec->data); + break; + case pD202: + GPS_D202_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + continue; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) { + GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); + return FRAMING_ERROR; + } + + (*way)[i]->isrte = 0; + (*way)[i]->islink = 0; + + switch (gps_rte_type) { + case pD100: + GPS_D100_Get(&((*way)[i]),rec->data); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i-1]->prot = (*way)[i]->prot; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A200_GET: Error transferring routes"); + return FRAMING_ERROR; + } - if(!GPS_Device_Off(fd)) - return gps_errno; + if (i != n) { + GPS_Error("A200_GET: Route entry number mismatch"); + return FRAMING_ERROR; + } - return n; + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return n; } @@ -2785,186 +2981,188 @@ int32 GPS_A200_Get(const char *port, GPS_PWay **way) ** ** @return [int32] number of waypoint entries ************************************************************************/ -int32 GPS_A201_Get(const char *port, GPS_PWay **way) +int32 GPS_A201_Get(const char* port, GPS_PWay** way) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) - { - GPS_Error("A201_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - - for(i=0;itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) - { - switch(gps_rte_hdr_type) - { - case pD200: - GPS_D200_Get(&((*way)[i]),rec->data); - break; - case pD201: - GPS_D201_Get(&((*way)[i]),rec->data); - break; - case pD202: - GPS_D202_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A201_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (*way)[i]->islink = 0; - continue; - } - - - if(rec->type == LINK_ID[gps_link_type].Pid_Rte_Link_Data) - { - switch(gps_rte_link_type) - { - case pD210: - GPS_D210_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A201_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (*way)[i]->isrte = 0; - (*way)[i]->islink = 1; - continue; - } - - if(rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) - { - GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); - return FRAMING_ERROR; - } - - (*way)[i]->isrte = 0; - (*way)[i]->islink = 0; - - switch(gps_rte_type) - { - case pD100: - GPS_D100_Get(&((*way)[i]),rec->data); - break; - case pD101: - GPS_D101_Get(&((*way)[i]),rec->data); - break; - case pD102: - GPS_D102_Get(&((*way)[i]),rec->data); - break; - case pD103: - GPS_D103_Get(&((*way)[i]),rec->data); - break; - case pD104: - GPS_D104_Get(&((*way)[i]),rec->data); - break; - case pD105: - GPS_D105_Get(&((*way)[i]),rec->data); - break; - case pD106: - GPS_D106_Get(&((*way)[i]),rec->data); - break; - case pD107: - GPS_D107_Get(&((*way)[i]),rec->data); - break; - case pD108: - GPS_D108_Get(&((*way)[i]),rec->data); - break; - case pD109: - GPS_D109_Get(&((*way)[i]),rec->data,109); - break; - case pD110: - GPS_D109_Get(&((*way)[i]),rec->data,110); - break; - case pD150: - GPS_D150_Get(&((*way)[i]),rec->data); - break; - case pD151: - GPS_D151_Get(&((*way)[i]),rec->data); - break; - case pD152: - GPS_D152_Get(&((*way)[i]),rec->data); - break; - case pD154: - GPS_D154_Get(&((*way)[i]),rec->data); - break; - case pD155: - GPS_D155_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A200_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (*way)[i-1]->prot = (*way)[i]->prot; - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A200_GET: Error transferring routes"); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A200_GET: Route entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*way)=(GPS_PWay*)malloc(n*sizeof(GPS_PWay)))) { + GPS_Error("A201_Get: Insufficient memory"); + return MEMORY_ERROR; } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + + for (i=0; itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) { + switch (gps_rte_hdr_type) { + case pD200: + GPS_D200_Get(&((*way)[i]),rec->data); + break; + case pD201: + GPS_D201_Get(&((*way)[i]),rec->data); + break; + case pD202: + GPS_D202_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A201_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i]->islink = 0; + continue; + } + + + if (rec->type == LINK_ID[gps_link_type].Pid_Rte_Link_Data) { + switch (gps_rte_link_type) { + case pD210: + GPS_D210_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A201_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i]->isrte = 0; + (*way)[i]->islink = 1; + continue; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) { + GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); + return FRAMING_ERROR; + } + + (*way)[i]->isrte = 0; + (*way)[i]->islink = 0; + + switch (gps_rte_type) { + case pD100: + GPS_D100_Get(&((*way)[i]),rec->data); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i-1]->prot = (*way)[i]->prot; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A200_GET: Error transferring routes"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A200_GET: Route entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return n; + return n; } @@ -2979,141 +3177,138 @@ int32 GPS_A201_Get(const char *port, GPS_PWay **way) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n) +int32 GPS_A200_Send(const char* port, GPS_PWay* way, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - US method; - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route start data not acknowledged"); - return FRAMING_ERROR; - } - - - for(i=0;iisrte) - { - method = LINK_ID[gps_link_type].Pid_Rte_Hdr; - - switch(gps_rte_hdr_type) - { - case pD200: - GPS_D200_Send(data,way[i],&len); - break; - case pD201: - GPS_D201_Send(data,way[i],&len); - break; - case pD202: - GPS_D202_Send(data,way[i],&len); - break; - default: - GPS_Error("A200_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - else - { - method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; - - switch(gps_rte_type) - { - case pD100: - GPS_D100_Send(data,way[i],&len); - break; - case pD101: - GPS_D101_Send(data,way[i],&len); - break; - case pD102: - GPS_D102_Send(data,way[i],&len); - break; - case pD103: - GPS_D103_Send(data,way[i],&len); - break; - case pD104: - GPS_D104_Send(data,way[i],&len); - break; - case pD105: - GPS_D105_Send(data,way[i],&len); - break; - case pD106: - GPS_D106_Send(data,way[i],&len); - break; - case pD107: - GPS_D107_Send(data,way[i],&len); - break; - case pD108: - GPS_D108_Send(data,way[i],&len); - break; - case pD150: - GPS_D150_Send(data,way[i],&len); - break; - case pD151: - GPS_D151_Send(data,way[i],&len); - break; - case pD152: - GPS_D152_Send(data,way[i],&len); - break; - case pD154: - GPS_D154_Send(data,way[i],&len); - break; - case pD155: - GPS_D155_Send(data,way[i],&len); - break; - default: - GPS_Error("A200_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - - - GPS_Make_Packet(&tra, method, data, len); - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route packet not acknowledged"); - return FRAMING_ERROR; - } - } - - GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route complete data not acknowledged"); - return FRAMING_ERROR; + UC data[GPS_ARB_LEN]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + US method; + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route start data not acknowledged"); + return FRAMING_ERROR; + } + + + for (i=0; iisrte) { + method = LINK_ID[gps_link_type].Pid_Rte_Hdr; + + switch (gps_rte_hdr_type) { + case pD200: + GPS_D200_Send(data,way[i],&len); + break; + case pD201: + GPS_D201_Send(data,way[i],&len); + break; + case pD202: + GPS_D202_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } else { + method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; + + switch (gps_rte_type) { + case pD100: + GPS_D100_Send(data,way[i],&len); + break; + case pD101: + GPS_D101_Send(data,way[i],&len); + break; + case pD102: + GPS_D102_Send(data,way[i],&len); + break; + case pD103: + GPS_D103_Send(data,way[i],&len); + break; + case pD104: + GPS_D104_Send(data,way[i],&len); + break; + case pD105: + GPS_D105_Send(data,way[i],&len); + break; + case pD106: + GPS_D106_Send(data,way[i],&len); + break; + case pD107: + GPS_D107_Send(data,way[i],&len); + break; + case pD108: + GPS_D108_Send(data,way[i],&len); + break; + case pD150: + GPS_D150_Send(data,way[i],&len); + break; + case pD151: + GPS_D151_Send(data,way[i],&len); + break; + case pD152: + GPS_D152_Send(data,way[i],&len); + break; + case pD154: + GPS_D154_Send(data,way[i],&len); + break; + case pD155: + GPS_D155_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + GPS_Make_Packet(&tra, method, data, len); - return 1; + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route packet not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } @@ -3128,161 +3323,155 @@ int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n) +int32 GPS_A201_Send(const char* port, GPS_PWay* way, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - US method; - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route start data not acknowledged"); - return FRAMING_ERROR; - } - - - for(i=0;iisrte) - { - method = LINK_ID[gps_link_type].Pid_Rte_Hdr; - - switch(gps_rte_hdr_type) - { - case pD200: - GPS_D200_Send(data,way[i],&len); - break; - case pD201: - GPS_D201_Send(data,way[i],&len); - break; - case pD202: - GPS_D202_Send(data,way[i],&len); - break; - default: - GPS_Error("A200_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - else if(way[i]->islink) - { - method = LINK_ID[gps_link_type].Pid_Rte_Link_Data; - - switch(gps_rte_link_type) - { - case pD210: - GPS_D210_Send(data,way[i],&len); - break; - default: - GPS_Error("A201_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - else - { - method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; - - switch(gps_rte_type) - { - case pD100: - GPS_D100_Send(data,way[i],&len); - break; - case pD101: - GPS_D101_Send(data,way[i],&len); - break; - case pD102: - GPS_D102_Send(data,way[i],&len); - break; - case pD103: - GPS_D103_Send(data,way[i],&len); - break; - case pD104: - GPS_D104_Send(data,way[i],&len); - break; - case pD105: - GPS_D105_Send(data,way[i],&len); - break; - case pD106: - GPS_D106_Send(data,way[i],&len); - break; - case pD107: - GPS_D107_Send(data,way[i],&len); - break; - case pD108: - GPS_D108_Send(data,way[i],&len); - break; - case pD109: - GPS_D109_Send(data,way[i],&len, 109); - break; - case pD110: - GPS_D109_Send(data,way[i],&len, 110); - break; - case pD150: - GPS_D150_Send(data,way[i],&len); - break; - case pD151: - GPS_D151_Send(data,way[i],&len); - break; - case pD152: - GPS_D152_Send(data,way[i],&len); - break; - case pD154: - GPS_D154_Send(data,way[i],&len); - break; - case pD155: - GPS_D155_Send(data,way[i],&len); - break; - default: - GPS_Error("A200_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - - - GPS_Make_Packet(&tra, method, data, len); - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route packet not acknowledged"); - return FRAMING_ERROR; - } - } - - GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route complete data not acknowledged"); - return FRAMING_ERROR; + UC data[GPS_ARB_LEN]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + US method; + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route start data not acknowledged"); + return FRAMING_ERROR; + } + + + for (i=0; iisrte) { + method = LINK_ID[gps_link_type].Pid_Rte_Hdr; + + switch (gps_rte_hdr_type) { + case pD200: + GPS_D200_Send(data,way[i],&len); + break; + case pD201: + GPS_D201_Send(data,way[i],&len); + break; + case pD202: + GPS_D202_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } else if (way[i]->islink) { + method = LINK_ID[gps_link_type].Pid_Rte_Link_Data; + + switch (gps_rte_link_type) { + case pD210: + GPS_D210_Send(data,way[i],&len); + break; + default: + GPS_Error("A201_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } else { + method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; + + switch (gps_rte_type) { + case pD100: + GPS_D100_Send(data,way[i],&len); + break; + case pD101: + GPS_D101_Send(data,way[i],&len); + break; + case pD102: + GPS_D102_Send(data,way[i],&len); + break; + case pD103: + GPS_D103_Send(data,way[i],&len); + break; + case pD104: + GPS_D104_Send(data,way[i],&len); + break; + case pD105: + GPS_D105_Send(data,way[i],&len); + break; + case pD106: + GPS_D106_Send(data,way[i],&len); + break; + case pD107: + GPS_D107_Send(data,way[i],&len); + break; + case pD108: + GPS_D108_Send(data,way[i],&len); + break; + case pD109: + GPS_D109_Send(data,way[i],&len, 109); + break; + case pD110: + GPS_D109_Send(data,way[i],&len, 110); + break; + case pD150: + GPS_D150_Send(data,way[i],&len); + break; + case pD151: + GPS_D151_Send(data,way[i],&len); + break; + case pD152: + GPS_D152_Send(data,way[i],&len); + break; + case pD154: + GPS_D154_Send(data,way[i],&len); + break; + case pD155: + GPS_D155_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + GPS_Make_Packet(&tra, method, data, len); - return 1; + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route packet not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } @@ -3298,13 +3487,13 @@ int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n) ** ** @return [void] ************************************************************************/ -static void GPS_D200_Get(GPS_PWay *way, UC *s) +static void GPS_D200_Get(GPS_PWay* way, UC* s) { - (*way)->rte_prot = 200; - (*way)->rte_num = *s; - (*way)->isrte = 1; + (*way)->rte_prot = 200; + (*way)->rte_num = *s; + (*way)->isrte = 1; - return; + return; } @@ -3318,19 +3507,21 @@ static void GPS_D200_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D201_Get(GPS_PWay *way, UC *s) +static void GPS_D201_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->rte_prot = 201; - (*way)->rte_num = *p++; - (*way)->isrte = 1; - for(i=0;i<20;++i) (*way)->rte_cmnt[i] = *p++; + (*way)->rte_prot = 201; + (*way)->rte_num = *p++; + (*way)->isrte = 1; + for (i=0; i<20; ++i) { + (*way)->rte_cmnt[i] = *p++; + } - return; + return; } @@ -3344,23 +3535,23 @@ static void GPS_D201_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D202_Get(GPS_PWay *way, UC *s) +static void GPS_D202_Get(GPS_PWay* way, UC* s) { - UC *p; - UC *q; + UC* p; + UC* q; - p=s; + p=s; - (*way)->rte_prot = 202; + (*way)->rte_prot = 202; #if 0 - /* D202 has only a null terminated string for rte_ident */ - (*way)->rte_num = *p++; + /* D202 has only a null terminated string for rte_ident */ + (*way)->rte_num = *p++; #endif - (*way)->isrte = 1; - q = (UC *) (*way)->rte_ident; - while((*q++=*p++)); + (*way)->isrte = 1; + q = (UC*)(*way)->rte_ident; + while ((*q++=*p++)); - return; + return; } @@ -3374,21 +3565,23 @@ static void GPS_D202_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D210_Get(GPS_PWay *way, UC *s) +static void GPS_D210_Get(GPS_PWay* way, UC* s) { - UC *p; - UC *q; - int32 i; + UC* p; + UC* q; + int32 i; - p=s; + p=s; - (*way)->rte_link_class = GPS_Util_Get_Short(p); - p+=sizeof(int16); - for(i=0;i<18;++i) (*way)->rte_link_subclass[i] = *p++; - q = (UC *) (*way)->rte_link_ident; - while((*q++=*p++)); + (*way)->rte_link_class = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + (*way)->rte_link_subclass[i] = *p++; + } + q = (UC*)(*way)->rte_link_ident; + while ((*q++=*p++)); - return; + return; } @@ -3403,13 +3596,13 @@ static void GPS_D210_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D200_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D200_Send(UC* data, GPS_PWay way, int32* len) { - *data = way->rte_num; - *len = 1; + *data = way->rte_num; + *len = 1; - return; + return; } @@ -3424,17 +3617,17 @@ static void GPS_D200_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D201_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D201_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; + UC* p; - p = data; + p = data; - *p++ = way->rte_num; - copy_char_array(&p, way->rte_cmnt, 20, UpperYes); - *len = 21; + *p++ = way->rte_num; + copy_char_array(&p, way->rte_cmnt, 20, UpperYes); + *len = 21; - return; + return; } @@ -3449,19 +3642,19 @@ static void GPS_D201_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D202_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D202_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - UC *q; + UC* p; + UC* q; - p = data; - q = (UC *) way->rte_ident; + p = data; + q = (UC*) way->rte_ident; - while((*p++ = *q++)); + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -3476,24 +3669,26 @@ static void GPS_D202_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D210_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - UC *q; - int32 i; + UC* p; + UC* q; + int32 i; - p = data; + p = data; - GPS_Util_Put_Short(p,(US) way->rte_link_class); - p+=sizeof(int16); - for(i=0;i<18;++i) *p++ = way->rte_link_subclass[i]; + GPS_Util_Put_Short(p,(US) way->rte_link_class); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + *p++ = way->rte_link_subclass[i]; + } - q = (UC *) way->rte_link_ident; - while((*p++ = *q++)); + q = (UC*) way->rte_link_ident; + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -3507,83 +3702,90 @@ static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [int32] number of track entries ************************************************************************/ -int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb) +int32 GPS_A300_Get(const char* port, GPS_PTrack** trk, pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - int32 ret; - - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - /* Only those GPS' with L001 can send track data */ - if(!LINK_ID[gps_link_type].Pid_Trk_Data) - { - GPS_Warning("A300 protocol unsupported"); - return GPS_UNSUPPORTED; - } - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*trk)=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack)))) - { - GPS_Error("A300_Get: Insufficient memory"); - return MEMORY_ERROR; - } - for(i=0;idata); + + if (n) + if (!((*trk)=(GPS_PTrack*)malloc(n*sizeof(GPS_PTrack)))) { + GPS_Error("A300_Get: Insufficient memory"); + return MEMORY_ERROR; + } + for (i=0; itype == LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - break; - } + GPS_PPacket tra; + GPS_PPacket rec; + static UC data[2]; + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Runs); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + for (;;) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + if (rec->type == LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + break; + } + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); return 0; } @@ -3642,178 +3849,180 @@ drain_run_cmd(gpsdevh *fd) ** ** @return [int32] number of track entries ************************************************************************/ -int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb, int protoid) +int32 GPS_A301_Get(const char* port, GPS_PTrack** trk, pcb_fn cb, int protoid) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - US Pid_Trk_Data, Pid_Trk_Hdr, Cmnd_Transfer_Trk; - int32 trk_type, trk_hdr_type; - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - /* A301 and A302 are similar except for all these protocol IDs */ - switch (protoid) - { - case 301: - Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Trk_Data; - Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Trk_Hdr; - Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk; - trk_type = gps_trk_type; - trk_hdr_type = gps_trk_hdr_type; - break; - case 302: - Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Course_Trk_Data; - Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Course_Trk_Hdr; - Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Tracks; - trk_type = gps_run_crs_trk_type; - trk_hdr_type = gps_run_crs_trk_hdr_type; - break; - default: - GPS_Error("A301_Get: Bad protocol ID %d", protoid); - return GPS_UNSUPPORTED; - } - - /* Only those GPS' with L001 can send track data */ - if(!Pid_Trk_Data) - { - GPS_Warning("A301 protocol unsupported"); - return GPS_UNSUPPORTED; - } - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if (protoid == 301 && trk_type == pD304 && gps_run_transfer != -1) { - drain_run_cmd(fd); - } - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, Cmnd_Transfer_Trk); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*trk)=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack)))) - { - GPS_Error("A301_Get: Insufficient memory"); - return MEMORY_ERROR; - } - for(i=0;itype == Pid_Trk_Hdr) - { - switch(trk_hdr_type) - { - case pD310: - case pD312: - GPS_D310_Get(&((*trk)[i]),rec->data); - break; - case pD311: - GPS_D311_Get(&((*trk)[i]),rec->data); - break; - default: - GPS_Error("A301_Get: Unknown track protocol"); - return PROTOCOL_ERROR; - } - (*trk)[i]->ishdr = 1; - continue; - } - - if(rec->type != Pid_Trk_Data) - { - GPS_Error("A301_Get: Non-Pid_Trk_Data"); - return FRAMING_ERROR; - } - - (*trk)[i]->ishdr = 0; - - switch(trk_type) - { - case pD300: - GPS_D300b_Get(&((*trk)[i]),rec->data); - break; - case pD301: - GPS_D301b_Get(&((*trk)[i]),rec->data); - break; - case pD302: - GPS_D302b_Get(&((*trk)[i]),rec->data); - break; - case pD303: - case pD304: - GPS_D303b_Get(&((*trk)[i]),rec->data); - /* Fitness devices don't send track segment markers, so we have - * to create them ourselves. We do so at the beginning of the - * track or if the device signals a pause by sending two - * invalid points in a row. - */ - if (i>0) - { - if ((*trk)[i-1]->ishdr || - (Is_Trackpoint_Invalid((*trk)[i-1]) && - Is_Trackpoint_Invalid((*trk)[i]))) - { - (*trk)[i]->tnew = 1; - } - } - break; - default: - GPS_Error("A301_GET: Unknown track protocol"); - return PROTOCOL_ERROR; - } - /* Cheat and don't _really_ pass the trkpt back */ - if (cb) - cb(n, NULL); - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A301_Get: Error transferring tracks"); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A301_GET: Track entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + US Pid_Trk_Data, Pid_Trk_Hdr, Cmnd_Transfer_Trk; + int32 trk_type, trk_hdr_type; + + if (gps_trk_transfer == -1) { + return GPS_UNSUPPORTED; + } + + /* A301 and A302 are similar except for all these protocol IDs */ + switch (protoid) { + case 301: + Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Trk_Data; + Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Trk_Hdr; + Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk; + trk_type = gps_trk_type; + trk_hdr_type = gps_trk_hdr_type; + break; + case 302: + Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Course_Trk_Data; + Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Course_Trk_Hdr; + Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Tracks; + trk_type = gps_run_crs_trk_type; + trk_hdr_type = gps_run_crs_trk_hdr_type; + break; + default: + GPS_Error("A301_Get: Bad protocol ID %d", protoid); + return GPS_UNSUPPORTED; + } + + /* Only those GPS' with L001 can send track data */ + if (!Pid_Trk_Data) { + GPS_Warning("A301 protocol unsupported"); + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (protoid == 301 && trk_type == pD304 && gps_run_transfer != -1) { + drain_run_cmd(fd); + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, Cmnd_Transfer_Trk); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*trk)=(GPS_PTrack*)malloc(n*sizeof(GPS_PTrack)))) { + GPS_Error("A301_Get: Insufficient memory"); + return MEMORY_ERROR; + } + for (i=0; itype == Pid_Trk_Hdr) { + switch (trk_hdr_type) { + case pD310: + case pD312: + GPS_D310_Get(&((*trk)[i]),rec->data); + break; + case pD311: + GPS_D311_Get(&((*trk)[i]),rec->data); + break; + default: + GPS_Error("A301_Get: Unknown track protocol"); + return PROTOCOL_ERROR; + } + (*trk)[i]->ishdr = 1; + continue; + } + + if (rec->type != Pid_Trk_Data) { + GPS_Error("A301_Get: Non-Pid_Trk_Data"); + return FRAMING_ERROR; + } - if(!GPS_Device_Off(fd)) - return gps_errno; + (*trk)[i]->ishdr = 0; - return n; + switch (trk_type) { + case pD300: + GPS_D300b_Get(&((*trk)[i]),rec->data); + break; + case pD301: + GPS_D301b_Get(&((*trk)[i]),rec->data); + break; + case pD302: + GPS_D302b_Get(&((*trk)[i]),rec->data); + break; + case pD303: + case pD304: + GPS_D303b_Get(&((*trk)[i]),rec->data); + /* Fitness devices don't send track segment markers, so we have + * to create them ourselves. We do so at the beginning of the + * track or if the device signals a pause by sending two + * invalid points in a row. + */ + if (i>0) { + if ((*trk)[i-1]->ishdr || + (Is_Trackpoint_Invalid((*trk)[i-1]) && + Is_Trackpoint_Invalid((*trk)[i]))) { + (*trk)[i]->tnew = 1; + } + } + break; + default: + GPS_Error("A301_GET: Unknown track protocol"); + return PROTOCOL_ERROR; + } + /* Cheat and don't _really_ pass the trkpt back */ + if (cb) { + cb(n, NULL); + } + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A301_Get: Error transferring tracks"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A301_GET: Track entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return n; } @@ -3827,85 +4036,86 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb, int protoid) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n) +int32 GPS_A300_Send(const char* port, GPS_PTrack* trk, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - /* Only those GPS' with L001 can send track data */ - if(!LINK_ID[gps_link_type].Pid_Trk_Data) - { - GPS_Warning("A300 protocol unsupported"); - return GPS_UNSUPPORTED; - } - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A300_Send: Track start data not acknowledged"); - return FRAMING_ERROR; - } - - for(i=0;iishdr) - { - method = Pid_Trk_Hdr; - - switch(trk_hdr_type) - { - case pD310: - case pD312: - GPS_D310_Send(data,trk[i],&len); - break; - case pD311: - GPS_D311_Send(data,trk[i],&len); - break; - default: - GPS_Error("A301_Send: Unknown track protocol %d", trk_hdr_type); - return PROTOCOL_ERROR; - } - } - else - { - method = Pid_Trk_Data; - - switch(trk_type) - { - case pD300: - GPS_D300_Send(data,trk[i],&len); - break; - case pD301: - GPS_D301_Send(data,trk[i],&len,301); - break; - case pD302: - GPS_D301_Send(data,trk[i],&len,302); - break; - case pD303: - case pD304: - GPS_D303_Send(data,trk[i],&len,(trk_type==pD303) ? 303 : 304); - break; - default: - GPS_Error("A301_Send: Unknown track protocol"); - return PROTOCOL_ERROR; - } - } - - GPS_Make_Packet(&tra, method, data, len); - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A301_Send: Track packet not acknowledged"); - return FRAMING_ERROR; - } - } - - GPS_Util_Put_Short(data, Cmnd_Transfer_Trk); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A301_Send: Track complete data not acknowledged"); - return FRAMING_ERROR; + UC data[GPS_ARB_LEN]; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + US method; + US Pid_Trk_Data, Pid_Trk_Hdr, Cmnd_Transfer_Trk; + int32 trk_type, trk_hdr_type; + + if (gps_trk_transfer == -1) { + return GPS_UNSUPPORTED; + } + + /* A301 and A302 are similar except for all these protocol IDs */ + switch (protoid) { + case 301: + Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Trk_Data; + Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Trk_Hdr; + Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk; + trk_type = gps_trk_type; + trk_hdr_type = gps_trk_hdr_type; + break; + case 302: + Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Course_Trk_Data; + Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Course_Trk_Hdr; + Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Tracks; + trk_type = gps_run_crs_trk_type; + trk_hdr_type = gps_run_crs_trk_hdr_type; + break; + default: + GPS_Error("A301_Send: Bad protocol ID %d", protoid); + return GPS_UNSUPPORTED; + } + + /* Only those GPS' with L001 can send track data */ + if (!Pid_Trk_Data) { + GPS_Warning("A301 protocol unsupported"); + return GPS_UNSUPPORTED; + } + + if (protoid != 302 && !GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A301_Send: Track start data not acknowledged"); + return FRAMING_ERROR; + } + + + for (i=0; iishdr) { + method = Pid_Trk_Hdr; + + switch (trk_hdr_type) { + case pD310: + case pD312: + GPS_D310_Send(data,trk[i],&len); + break; + case pD311: + GPS_D311_Send(data,trk[i],&len); + break; + default: + GPS_Error("A301_Send: Unknown track protocol %d", trk_hdr_type); + return PROTOCOL_ERROR; + } + } else { + method = Pid_Trk_Data; + + switch (trk_type) { + case pD300: + GPS_D300_Send(data,trk[i],&len); + break; + case pD301: + GPS_D301_Send(data,trk[i],&len,301); + break; + case pD302: + GPS_D301_Send(data,trk[i],&len,302); + break; + case pD303: + case pD304: + GPS_D303_Send(data,trk[i],&len,(trk_type==pD303) ? 303 : 304); + break; + default: + GPS_Error("A301_Send: Unknown track protocol"); + return PROTOCOL_ERROR; + } } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Make_Packet(&tra, method, data, len); - if(protoid != 302 && !GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } - return 1; + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A301_Send: Track packet not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data, Cmnd_Transfer_Trk); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A301_Send: Track complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (protoid != 302 && !GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } @@ -4075,43 +4281,46 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n, int protoid, ** ** @return [int32] number of entries read ************************************************************************/ -int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *fd) +int32 GPS_D300_Get(GPS_PTrack* trk, int32 entries, gpsdevh* fd) { - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - for(i=0;idata, &trk[i]); + for (i=0; idata, &trk[i]); + } - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("D300_GET: Error transferring track log"); - return FRAMING_ERROR; - } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - - return i; + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("D300_GET: Error transferring track log"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + return i; } @@ -4125,11 +4334,11 @@ int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *fd) ** ** @return [void] ************************************************************************/ -void GPS_D300b_Get(GPS_PTrack *trk, UC *data) +void GPS_D300b_Get(GPS_PTrack* trk, UC* data) { - GPS_A300_Translate(data, trk); - return; + GPS_A300_Translate(data, trk); + return; } @@ -4143,35 +4352,36 @@ void GPS_D300b_Get(GPS_PTrack *trk, UC *data) ** ** @return [void] ************************************************************************/ -void GPS_D301b_Get(GPS_PTrack *trk, UC *data) +void GPS_D301b_Get(GPS_PTrack* trk, UC* data) { - UC *p; - uint32 t; + UC* p; + uint32 t; - p=data; + p=data; - (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - t = GPS_Util_Get_Uint(p); - if(!t || t==0x7fffffff || t==0xffffffff) - (*trk)->Time=0; - else - (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + t = GPS_Util_Get_Uint(p); + if (!t || t==0x7fffffff || t==0xffffffff) { + (*trk)->Time=0; + } else { + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + } + p+=sizeof(uint32); - (*trk)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*trk)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*trk)->dpth = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*trk)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*trk)->tnew = *p; + (*trk)->tnew = *p; - return; + return; } /* @func GPS_D302b_Get ****************************************************** @@ -4183,47 +4393,48 @@ void GPS_D301b_Get(GPS_PTrack *trk, UC *data) ** ** @return [void] ************************************************************************/ -void GPS_D302b_Get(GPS_PTrack *trk, UC *data) +void GPS_D302b_Get(GPS_PTrack* trk, UC* data) { - UC *p; - uint32 t; - double gps_temp; + UC* p; + uint32 t; + double gps_temp; - p=data; + p=data; - (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - t = GPS_Util_Get_Uint(p); - if(!t || t==0x7fffffff || t==0xffffffff) - (*trk)->Time=0; - else - (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + t = GPS_Util_Get_Uint(p); + if (!t || t==0x7fffffff || t==0xffffffff) { + (*trk)->Time=0; + } else { + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + } + p+=sizeof(uint32); - (*trk)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*trk)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*trk)->dpth = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*trk)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); - /* The only difference between 302 and 301 is the presence of temp - * in the middle. Nice planning, eh? - */ - gps_temp = GPS_Util_Get_Float(p); - if (gps_temp <= 1.0e24) { - (*trk)->temperature_populated = 1; - (*trk)->temperature = gps_temp; - } + /* The only difference between 302 and 301 is the presence of temp + * in the middle. Nice planning, eh? + */ + gps_temp = GPS_Util_Get_Float(p); + if (gps_temp <= 1.0e24) { + (*trk)->temperature_populated = 1; + (*trk)->temperature = gps_temp; + } - p+=sizeof(float); + p+=sizeof(float); - (*trk)->tnew = *p; + (*trk)->tnew = *p; - return; + return; } @@ -4236,83 +4447,87 @@ void GPS_D302b_Get(GPS_PTrack *trk, UC *data) ** ** @return [void] ************************************************************************/ -void GPS_D303b_Get(GPS_PTrack *trk, UC *data) +void GPS_D303b_Get(GPS_PTrack* trk, UC* data) { - UC *p; - uint32 t; - uint32 raw_lat, raw_lon; - int lat_undefined, lon_undefined; - p=data; - - /* Latitude and longitude are sometimes invalid (0x7fffffff or - * maybe 0xffffffff?) I guess this makes sense if the device is - * reporting heart rate and time anyway. I presume that latitude - * and longitude are defined or left undefined together? - */ - raw_lat = GPS_Util_Get_Int(p); - lat_undefined = !raw_lat || raw_lat==0x7fffffff || raw_lat==0xffffffff; - if (lat_undefined) - (*trk)->lat=0; - else - (*trk)->lat = GPS_Math_Semi_To_Deg(raw_lat); - p+=sizeof(int32); - - raw_lon = GPS_Util_Get_Int(p); - lon_undefined = !raw_lon || raw_lon==0x7fffffff || raw_lon==0xffffffff; - if (lon_undefined) - (*trk)->lon=0; - else - (*trk)->lon = GPS_Math_Semi_To_Deg(raw_lon); - p+=sizeof(int32); - - /* - * Let the caller decide if it wants to toss trackpionts with only - * heart rate and/or time data. - */ - if (lat_undefined || lon_undefined) { - (*trk)->no_latlon = 1; + UC* p; + uint32 t; + uint32 raw_lat, raw_lon; + int lat_undefined, lon_undefined; + p=data; + + /* Latitude and longitude are sometimes invalid (0x7fffffff or + * maybe 0xffffffff?) I guess this makes sense if the device is + * reporting heart rate and time anyway. I presume that latitude + * and longitude are defined or left undefined together? + */ + raw_lat = GPS_Util_Get_Int(p); + lat_undefined = !raw_lat || raw_lat==0x7fffffff || raw_lat==0xffffffff; + if (lat_undefined) { + (*trk)->lat=0; + } else { + (*trk)->lat = GPS_Math_Semi_To_Deg(raw_lat); + } + p+=sizeof(int32); + + raw_lon = GPS_Util_Get_Int(p); + lon_undefined = !raw_lon || raw_lon==0x7fffffff || raw_lon==0xffffffff; + if (lon_undefined) { + (*trk)->lon=0; + } else { + (*trk)->lon = GPS_Math_Semi_To_Deg(raw_lon); + } + p+=sizeof(int32); + + /* + * Let the caller decide if it wants to toss trackpionts with only + * heart rate and/or time data. + */ + if (lat_undefined || lon_undefined) { + (*trk)->no_latlon = 1; + } + + if (lat_undefined != lon_undefined) { + GPS_Warning("GPS_D303b_Get: assumption (lat_undefined == lon_undefined) violated"); + } + + t = GPS_Util_Get_Uint(p); + + if (!t || t==0x7fffffff || t==0xffffffff) { + (*trk)->Time=0; + } else { + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + } + p+=sizeof(uint32); + + (*trk)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + + /* Heartrate is reported as 0 if there is no signal from + * a heartrate monitor. + * 303 and 304 are identical until now. + */ + switch (gps_trk_type) { + case pD304: + (*trk)->distance = GPS_Util_Get_Float(p); + (*trk)->distance_populated = ((*trk)->distance <= 1e24); + p+=sizeof(float); /* A float indicating number of meters travelled. */ + + (*trk)->heartrate = (*p++); + /* crank cadence, RPM, 0xff if invalid. */ + if (*p != 0xff) { + (*trk)->cadence = (*p); } + p++; - if (lat_undefined != lon_undefined) - GPS_Warning("GPS_D303b_Get: assumption (lat_undefined == lon_undefined) violated"); - - t = GPS_Util_Get_Uint(p); - - if(!t || t==0x7fffffff || t==0xffffffff) - (*trk)->Time=0; - else - (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + (*trk)->wsensor_pres = (*p++); - (*trk)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); + break; + case pD303: + (*trk)->heartrate = *p++; + break; + } - /* Heartrate is reported as 0 if there is no signal from - * a heartrate monitor. - * 303 and 304 are identical until now. - */ - switch (gps_trk_type) { - case pD304: - (*trk)->distance = GPS_Util_Get_Float(p); - (*trk)->distance_populated = ((*trk)->distance <= 1e24); - p+=sizeof(float); /* A float indicating number of meters travelled. */ - - (*trk)->heartrate = (*p++); - /* crank cadence, RPM, 0xff if invalid. */ - if (*p != 0xff) { - (*trk)->cadence = (*p); - } - p++; - - (*trk)->wsensor_pres = (*p++); - - break; - case pD303: - (*trk)->heartrate = *p++; - break; - } - - return; + return; } @@ -4325,21 +4540,21 @@ void GPS_D303b_Get(GPS_PTrack *trk, UC *data) ** ** @return [void] ************************************************************************/ -void GPS_D310_Get(GPS_PTrack *trk, UC *s) +void GPS_D310_Get(GPS_PTrack* trk, UC* s) { - UC *p; - UC *q; + UC* p; + UC* q; - p=s; + p=s; - (*trk)->dspl = *p++; - (*trk)->colour = *p++; + (*trk)->dspl = *p++; + (*trk)->colour = *p++; - q = (UC *) (*trk)->trk_ident; + q = (UC*)(*trk)->trk_ident; - while((*q++ = *p++)); + while ((*q++ = *p++)); - return; + return; } /* @func GPS_D311_Get ****************************************************** @@ -4351,18 +4566,18 @@ void GPS_D310_Get(GPS_PTrack *trk, UC *s) ** ** @return [void] ************************************************************************/ -void GPS_D311_Get(GPS_PTrack *trk, UC *s) +void GPS_D311_Get(GPS_PTrack* trk, UC* s) { - UC *p; - short identifier; + UC* p; + short identifier; - p=s; + p=s; - /* Forerunner */ - identifier = GPS_Util_Get_Short(s); - sprintf((*trk)->trk_ident, "%d", identifier); + /* Forerunner */ + identifier = GPS_Util_Get_Short(s); + sprintf((*trk)->trk_ident, "%d", identifier); - return; + return; } @@ -4376,16 +4591,16 @@ void GPS_D311_Get(GPS_PTrack *trk, UC *s) ** ** @return [void] ************************************************************************/ -void GPS_D300_Send(UC *data, GPS_PTrack trk, int32 *len) +void GPS_D300_Send(UC* data, GPS_PTrack trk, int32* len) { - UC *p; + UC* p; - p = data; - GPS_A300_Encode(p,trk); + p = data; + GPS_A300_Encode(p,trk); - *len = 13; + *len = 13; - return; + return; } @@ -4401,31 +4616,31 @@ void GPS_D300_Send(UC *data, GPS_PTrack trk, int32 *len) ** ** @return [void] ************************************************************************/ -void GPS_D301_Send(UC *data, GPS_PTrack trk, int32 *len, int type) +void GPS_D301_Send(UC* data, GPS_PTrack trk, int32* len, int type) { - UC *p; + UC* p; - p = data; - GPS_A300_Encode(p,trk); - p = data+12; + p = data; + GPS_A300_Encode(p,trk); + p = data+12; - GPS_Util_Put_Float(p,trk->alt); - p+=sizeof(float); - GPS_Util_Put_Float(p,trk->dpth); - p+=sizeof(float); + GPS_Util_Put_Float(p,trk->alt); + p+=sizeof(float); + GPS_Util_Put_Float(p,trk->dpth); + p+=sizeof(float); - if (type == 302) { - /* Temperature */ - GPS_Util_Put_Float(p, 1.0e25f); - p+=sizeof(float); - } + if (type == 302) { + /* Temperature */ + GPS_Util_Put_Float(p, 1.0e25f); + p+=sizeof(float); + } - *p = trk->tnew; - p+=sizeof(UC); + *p = trk->tnew; + p+=sizeof(UC); - *len = p-data; + *len = p-data; - return; + return; } @@ -4440,36 +4655,36 @@ void GPS_D301_Send(UC *data, GPS_PTrack trk, int32 *len, int type) ** ** @return [void] ************************************************************************/ -void GPS_D303_Send(UC *data, GPS_PTrack trk, int32 *len, int protoid) +void GPS_D303_Send(UC* data, GPS_PTrack trk, int32* len, int protoid) { - UC *p; + UC* p; - p = data; - GPS_A300_Encode(p,trk); - p = data+12; + p = data; + GPS_A300_Encode(p,trk); + p = data+12; - GPS_Util_Put_Float(p,trk->alt); + GPS_Util_Put_Float(p,trk->alt); + p+=sizeof(float); + + if (protoid == 304) { + GPS_Util_Put_Float(p, trk->distance_populated ? trk->distance : 1e25); p+=sizeof(float); + } - if (protoid == 304) { - GPS_Util_Put_Float(p, trk->distance_populated ? trk->distance : 1e25); - p+=sizeof(float); - } + *p = trk->heartrate; + p+=sizeof(char); - *p = trk->heartrate; + if (protoid == 304) { + *p = trk->cadence > 0 ? trk->cadence : 0xff; p+=sizeof(char); - if (protoid == 304) { - *p = trk->cadence > 0 ? trk->cadence : 0xff; - p+=sizeof(char); - - *p = trk->wsensor_pres; - p+=sizeof(char); - } + *p = trk->wsensor_pres; + p+=sizeof(char); + } - *len = p-data; + *len = p-data; - return; + return; } /* @func GPS_D311_Send ************************************************** @@ -4482,16 +4697,16 @@ void GPS_D303_Send(UC *data, GPS_PTrack trk, int32 *len, int protoid) ** ** @return [void] ************************************************************************/ -void GPS_D311_Send(UC *data, GPS_PTrack trk, int32 *len) +void GPS_D311_Send(UC* data, GPS_PTrack trk, int32* len) { - UC *p; + UC* p; - p = data; - GPS_Util_Put_Short(p,strtoul(trk->trk_ident, NULL, 0)); - p += 2; - *len = p-data; + p = data; + GPS_Util_Put_Short(p,strtoul(trk->trk_ident, NULL, 0)); + p += 2; + *len = p-data; - return; + return; } /* @func GPS_D310_Send ************************************************** @@ -4504,22 +4719,22 @@ void GPS_D311_Send(UC *data, GPS_PTrack trk, int32 *len) ** ** @return [void] ************************************************************************/ -void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len) +void GPS_D310_Send(UC* data, GPS_PTrack trk, int32* len) { - UC *p; - UC *q; + UC* p; + UC* q; - p = data; + p = data; - *p++ = trk->dspl; - *p++ = trk->colour; + *p++ = trk->dspl; + *p++ = trk->colour; - q = (UC *) trk->trk_ident; - while((*p++ = *q++)); + q = (UC*) trk->trk_ident; + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -4532,29 +4747,30 @@ void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_A300_Translate(UC *s, GPS_PTrack *trk) +static void GPS_A300_Translate(UC* s, GPS_PTrack* trk) { - UC *p; - uint32 t; + UC* p; + uint32 t; - p=s; + p=s; - (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - t = GPS_Util_Get_Uint(p); - if(!t || t==0x7fffffff || t==0xffffffff) - (*trk)->Time=0; - else - (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + t = GPS_Util_Get_Uint(p); + if (!t || t==0x7fffffff || t==0xffffffff) { + (*trk)->Time=0; + } else { + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + } + p+=sizeof(uint32); - (*trk)->tnew = *p; + (*trk)->tnew = *p; - return; + return; } @@ -4568,27 +4784,27 @@ static void GPS_A300_Translate(UC *s, GPS_PTrack *trk) ** ** @return [void] ************************************************************************/ -static void GPS_A300_Encode(UC *s, GPS_PTrack trk) +static void GPS_A300_Encode(UC* s, GPS_PTrack trk) { - UC *p; + UC* p; - p=s; + p=s; - /* Note: lat/lon == 0x7fffffff is only valid for D303/D304, but our - * caller shouldn't set no_latlon unless one of these protocols actually - * is in use */ - GPS_Util_Put_Int(p,trk->no_latlon ? 0x7fffffff : GPS_Math_Deg_To_Semi(trk->lat)); - p+=sizeof(int32); + /* Note: lat/lon == 0x7fffffff is only valid for D303/D304, but our + * caller shouldn't set no_latlon unless one of these protocols actually + * is in use */ + GPS_Util_Put_Int(p,trk->no_latlon ? 0x7fffffff : GPS_Math_Deg_To_Semi(trk->lat)); + p+=sizeof(int32); - GPS_Util_Put_Int(p,trk->no_latlon ? 0x7fffffff : GPS_Math_Deg_To_Semi(trk->lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,trk->no_latlon ? 0x7fffffff : GPS_Math_Deg_To_Semi(trk->lon)); + p+=sizeof(int32); - GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(trk->Time)); - p+=sizeof(uint32); + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(trk->Time)); + p+=sizeof(uint32); - *p = (UC) trk->tnew; + *p = (UC) trk->tnew; - return; + return; } @@ -4602,155 +4818,163 @@ static void GPS_A300_Encode(UC *s, GPS_PTrack trk) ** ** @return [int32] number of waypoint entries ************************************************************************/ -int32 GPS_A400_Get(const char *port, GPS_PWay **way) +int32 GPS_A400_Get(const char* port, GPS_PWay** way) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - - if(gps_prx_waypt_transfer == -1) - return GPS_UNSUPPORTED; - - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Prx); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Device_Chars_Ready(fd)) - { - GPS_Warning("A400 (ppx) protocol not supported"); - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - - if(!GPS_Device_Off(fd)) - return gps_errno; - - return GPS_UNSUPPORTED; - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) - { - GPS_Error("A400_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - - for(i=0;idata); - break; - case pD101: - GPS_D101_Get(&((*way)[i]),rec->data); - break; - case pD102: - GPS_D102_Get(&((*way)[i]),rec->data); - break; - case pD403: - GPS_D403_Get(&((*way)[i]),rec->data); - break; - case pD104: - GPS_D104_Get(&((*way)[i]),rec->data); - break; - case pD105: - GPS_D105_Get(&((*way)[i]),rec->data); - break; - case pD106: - GPS_D106_Get(&((*way)[i]),rec->data); - break; - case pD107: - GPS_D107_Get(&((*way)[i]),rec->data); - break; - case pD108: - GPS_D108_Get(&((*way)[i]),rec->data); - break; - case pD109: - GPS_D109_Get(&((*way)[i]),rec->data,109); - break; - case pD110: - GPS_D109_Get(&((*way)[i]),rec->data,110); - break; - case pD450: - GPS_D450_Get(&((*way)[i]),rec->data); - break; - case pD151: - GPS_D151_Get(&((*way)[i]),rec->data); - break; - case pD152: - GPS_D152_Get(&((*way)[i]),rec->data); - break; - case pD154: - GPS_D154_Get(&((*way)[i]),rec->data); - break; - case pD155: - GPS_D155_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A400_GET: Unknown prx waypoint protocol"); - return PROTOCOL_ERROR; - } - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A400_GET: Error transferring prx waypoints"); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A400_GET: Prx waypoint entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + if (gps_prx_waypt_transfer == -1) { + return GPS_UNSUPPORTED; + } + + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Prx); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Device_Chars_Ready(fd)) { + GPS_Warning("A400 (ppx) protocol not supported"); + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + if (!GPS_Device_Off(fd)) { + return gps_errno; } + return GPS_UNSUPPORTED; + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*way)=(GPS_PWay*)malloc(n*sizeof(GPS_PWay)))) { + GPS_Error("A400_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + + for (i=0; idata); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD403: + GPS_D403_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD450: + GPS_D450_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A400_GET: Unknown prx waypoint protocol"); + return PROTOCOL_ERROR; + } + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A400_GET: Error transferring prx waypoints"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A400_GET: Prx waypoint entry number mismatch"); + return FRAMING_ERROR; + } + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return n; + return n; } @@ -4765,119 +4989,121 @@ int32 GPS_A400_Get(const char *port, GPS_PWay **way) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n) +int32 GPS_A400_Send(const char* port, GPS_PWay* way, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(gps_prx_waypt_transfer == -1) - return GPS_UNSUPPORTED; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A400_Send: Prx start data not acknowledgedn"); - return FRAMING_ERROR; - } - - - for(i=0;iprot = 400; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 400; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst=GPS_Util_Get_Float(p); + (*way)->dst=GPS_Util_Get_Float(p); - return; + return; } @@ -4927,32 +5157,36 @@ static void GPS_D400_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D403_Get(GPS_PWay *way, UC *s) +static void GPS_D403_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 403; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 403; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->smbl = *p++; - (*way)->dspl = *p++; + (*way)->smbl = *p++; + (*way)->dspl = *p++; - (*way)->dst=GPS_Util_Get_Float(p); + (*way)->dst=GPS_Util_Get_Float(p); - return; + return; } @@ -4965,39 +5199,51 @@ static void GPS_D403_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D450_Get(GPS_PWay *way, UC *s) +static void GPS_D450_Get(GPS_PWay* way, UC* s) { - UC *p; - int32 i; + UC* p; + int32 i; - p=s; + p=s; - (*way)->prot = 450; + (*way)->prot = 450; - (*way)->idx = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->idx = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<6;++i) (*way)->ident[i] = *p++; - for(i=0;i<2;++i) (*way)->cc[i] = *p++; - (*way)->wpt_class = *p++; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } + (*way)->wpt_class = *p++; - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst=GPS_Util_Get_Float(p); + (*way)->dst=GPS_Util_Get_Float(p); - return; + return; } @@ -5011,27 +5257,31 @@ static void GPS_D450_Get(GPS_PWay *way, UC *s) ** ** @return [void] ************************************************************************/ -static void GPS_D400_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D400_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - int32 i; + UC* p; + int32 i; - p = data; + p = data; - for(i=0;i<6;++i) *p++ = way->ident[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - for(i=0;i<40;++i) *p++ = way->cmnt[i]; + for (i=0; i<6; ++i) { + *p++ = way->ident[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + for (i=0; i<40; ++i) { + *p++ = way->cmnt[i]; + } - GPS_Util_Put_Float(p,way->dst); + GPS_Util_Put_Float(p,way->dst); - *len = 62; + *len = 62; - return; + return; } @@ -5045,30 +5295,34 @@ static void GPS_D400_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D403_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D403_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - int32 i; + UC* p; + int32 i; - p = data; + p = data; - for(i=0;i<6;++i) *p++ = way->ident[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - for(i=0;i<40;++i) *p++ = way->cmnt[i]; + for (i=0; i<6; ++i) { + *p++ = way->ident[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + for (i=0; i<40; ++i) { + *p++ = way->cmnt[i]; + } - *p++ = way->smbl; - *p = way->dspl; + *p++ = way->smbl; + *p = way->dspl; - GPS_Util_Put_Float(p,way->dst); + GPS_Util_Put_Float(p,way->dst); - *len = 64; + *len = 64; - return; + return; } @@ -5082,39 +5336,51 @@ static void GPS_D403_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [void] ************************************************************************/ -static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len) +static void GPS_D450_Send(UC* data, GPS_PWay way, int32* len) { - UC *p; - int32 i; + UC* p; + int32 i; - p = data; + p = data; - GPS_Util_Put_Short(p,(US) way->idx); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->idx); + p+=sizeof(int16); - for(i=0;i<6;++i) *p++ = way->ident[i]; - for(i=0;i<2;++i) *p++ = way->cc[i]; - *p++ = way->wpt_class; + for (i=0; i<6; ++i) { + *p++ = way->ident[i]; + } + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + *p++ = way->wpt_class; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - for(i=0;i<24;++i) *p++ = way->city[i]; - for(i=0;i<2;++i) *p++ = way->state[i]; - for(i=0;i<30;++i) *p++ = way->name[i]; - for(i=0;i<40;++i) *p++ = way->cmnt[i]; + for (i=0; i<24; ++i) { + *p++ = way->city[i]; + } + for (i=0; i<2; ++i) { + *p++ = way->state[i]; + } + for (i=0; i<30; ++i) { + *p++ = way->name[i]; + } + for (i=0; i<40; ++i) { + *p++ = way->cmnt[i]; + } - GPS_Util_Put_Float(p,way->dst); + GPS_Util_Put_Float(p,way->dst); - *len = 121; + *len = 121; - return; + return; } @@ -5128,102 +5394,112 @@ static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [int32] number of almanac entries ************************************************************************/ -int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm) +int32 GPS_A500_Get(const char* port, GPS_PAlmanac** alm) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_almanac_transfer == -1) - return GPS_UNSUPPORTED; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Alm); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - if(n) - if(!((*alm)=(GPS_PAlmanac *)malloc(n*sizeof(GPS_PAlmanac)))) - { - GPS_Error("A500_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata, &((*alm)[i])); - break; - case pD501: - GPS_A500_Translate(recpkt->data, &((*alm)[i])); - (*alm)[i]->hlth=recpkt->data[42]; - break; - case pD550: - (*alm)[i]->svid = recpkt->data[0]; - GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); - break; - case pD551: - (*alm)[i]->svid = recpkt->data[0]; - GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); - (*alm)[i]->hlth = recpkt->data[43]; - break; - default: - GPS_Error("A500_GET: Unknown almanac protocol"); - return PROTOCOL_ERROR; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_almanac_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Alm); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + if (n) + if (!((*alm)=(GPS_PAlmanac*)malloc(n*sizeof(GPS_PAlmanac)))) { + GPS_Error("A500_Get: Insufficient memory"); + return MEMORY_ERROR; } - /* Cheat and don't _really_ pass the trkpt back */ -/* cb(n, NULL);*/ - } - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A500_Get: Error transferring almanac"); - return FRAMING_ERROR; + for (i=0; idata, &((*alm)[i])); + break; + case pD501: + GPS_A500_Translate(recpkt->data, &((*alm)[i])); + (*alm)[i]->hlth=recpkt->data[42]; + break; + case pD550: + (*alm)[i]->svid = recpkt->data[0]; + GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); + break; + case pD551: + (*alm)[i]->svid = recpkt->data[0]; + GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); + (*alm)[i]->hlth = recpkt->data[43]; + break; + default: + GPS_Error("A500_GET: Unknown almanac protocol"); + return PROTOCOL_ERROR; + } + /* Cheat and don't _really_ pass the trkpt back */ + /* cb(n, NULL);*/ + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A500_Get: Error transferring almanac"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A500_GET: Almanac entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return n; } @@ -5237,173 +5513,178 @@ int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) +int32 GPS_A500_Send(const char* port, GPS_PAlmanac* alm, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - int32 timesent; - int32 posnsent; - int32 ret; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A500_Send: Almanac start data not acknowledged"); - return FRAMING_ERROR; - } - - - for(i=0;itype == LINK_ID[gps_link_type].Pid_Command_Data && - GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. - Cmnd_Transfer_Time) - { - GPS_User("INFO: GPS time request. Sending...."); - ret = GPS_Rqst_Send_Time(fd,gps_save_time); - if(ret < 0) return ret; - timesent=1; - } + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Almanac_Data, + data, len); + + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A500_Send: Almanac Pid_Almanac_Data not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Alm); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A500_Send: Almanac complete data not acknowledged"); + return FRAMING_ERROR; + } + + timesent=posnsent=0; + + /* + * Allow GPS a little while to decide whether it wants to ask for + * the time. Note that the time sent is held in gps_save_time + * global + */ + if (GPS_Device_Wait(fd)) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; } + if (rec->type == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Time) { + GPS_User("INFO: GPS time request. Sending...."); + ret = GPS_Rqst_Send_Time(fd,gps_save_time); + if (ret < 0) { + return ret; + } + timesent=1; + } + } - /* - * Allow GPS a little while to decide whether it wants to ask for - * the position. Note that the posn sent is held in gps_save_lat - * and gps_save_lon global! - */ - if(GPS_Device_Wait(fd)) - { - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type == LINK_ID[gps_link_type].Pid_Command_Data && - GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. - Cmnd_Transfer_Posn) - { - GPS_User("INFO: GPS position request. Sending...."); - ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); - if(ret < 0) return ret; - posnsent=1; - } + + /* + * Allow GPS a little while to decide whether it wants to ask for + * the position. Note that the posn sent is held in gps_save_lat + * and gps_save_lon global! + */ + if (GPS_Device_Wait(fd)) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; } - if(!timesent) - { - ret = GPS_Rqst_Send_Time(fd,gps_save_time); - if(ret < 0) return ret; + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; } + if (rec->type == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Posn) { + GPS_User("INFO: GPS position request. Sending...."); + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if (ret < 0) { + return ret; + } + posnsent=1; + } + } - if(!posnsent) - { - ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); - if(ret < 0) return ret; + if (!timesent) { + ret = GPS_Rqst_Send_Time(fd,gps_save_time); + if (ret < 0) { + return ret; } + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + if (!posnsent) { + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if (ret < 0) { + return ret; + } + } - if(!GPS_Device_Off(fd)) - return gps_errno; - return 1; + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } /* @funcstatic GPS_A500_Translate *************************************** @@ -5415,46 +5696,46 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) ** ** @return [void] ************************************************************************/ -static void GPS_A500_Translate(UC *s, GPS_PAlmanac *alm) +static void GPS_A500_Translate(UC* s, GPS_PAlmanac* alm) { - UC *p; + UC* p; - p=s; + p=s; - (*alm)->wn = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*alm)->wn = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*alm)->toa = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->toa = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->af0 = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->af0 = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->af1 = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->af1 = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->e = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->e = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->sqrta = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->sqrta = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->m0 = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->m0 = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->w = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->w = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->omg0 = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->omg0 = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->odot = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->odot = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->i = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->i = GPS_Util_Get_Float(p); + p+=sizeof(float); - return; + return; } @@ -5467,14 +5748,14 @@ static void GPS_A500_Translate(UC *s, GPS_PAlmanac *alm) ** ** @return [void] ************************************************************************/ -static void GPS_D500_Send(UC *data, GPS_PAlmanac alm) +static void GPS_D500_Send(UC* data, GPS_PAlmanac alm) { - UC *p; + UC* p; - p = data; - GPS_A500_Encode(p,alm); + p = data; + GPS_A500_Encode(p,alm); - return; + return; } @@ -5488,15 +5769,15 @@ static void GPS_D500_Send(UC *data, GPS_PAlmanac alm) ** ** @return [void] ************************************************************************/ -static void GPS_D501_Send(UC *data, GPS_PAlmanac alm) +static void GPS_D501_Send(UC* data, GPS_PAlmanac alm) { - UC *p; + UC* p; - p=data; - p[42] = alm->hlth; - GPS_A500_Encode(p,alm); + p=data; + p[42] = alm->hlth; + GPS_A500_Encode(p,alm); - return; + return; } @@ -5510,15 +5791,15 @@ static void GPS_D501_Send(UC *data, GPS_PAlmanac alm) ** ** @return [void] ************************************************************************/ -static void GPS_D550_Send(UC *data, GPS_PAlmanac alm) +static void GPS_D550_Send(UC* data, GPS_PAlmanac alm) { - UC *p; + UC* p; - p = data; - *p = alm->svid; - GPS_A500_Encode(p+1,alm); + p = data; + *p = alm->svid; + GPS_A500_Encode(p+1,alm); - return; + return; } @@ -5532,16 +5813,16 @@ static void GPS_D550_Send(UC *data, GPS_PAlmanac alm) ** ** @return [void] ************************************************************************/ -static void GPS_D551_Send(UC *data, GPS_PAlmanac alm) +static void GPS_D551_Send(UC* data, GPS_PAlmanac alm) { - UC *p; + UC* p; - p = data; - *p = alm->svid; - GPS_A500_Encode(p+1,alm); - p[43] = alm->hlth; + p = data; + *p = alm->svid; + GPS_A500_Encode(p+1,alm); + p[43] = alm->hlth; - return; + return; } @@ -5555,45 +5836,45 @@ static void GPS_D551_Send(UC *data, GPS_PAlmanac alm) ** ** @return [void] ************************************************************************/ -static void GPS_A500_Encode(UC *s, GPS_PAlmanac alm) +static void GPS_A500_Encode(UC* s, GPS_PAlmanac alm) { - UC *p; + UC* p; - p=s; + p=s; - GPS_Util_Put_Short(p,alm->wn); - p+=sizeof(int16); + GPS_Util_Put_Short(p,alm->wn); + p+=sizeof(int16); - GPS_Util_Put_Float(p,alm->toa); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->toa); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->af0); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->af0); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->af1); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->af1); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->e); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->e); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->sqrta); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->sqrta); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->m0); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->m0); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->w); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->w); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->omg0); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->omg0); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->odot); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->odot); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->i); + GPS_Util_Put_Float(p,alm->i); - return; + return; } @@ -5605,51 +5886,57 @@ static void GPS_A500_Encode(UC *s, GPS_PAlmanac alm) ** ** @return [time_t] GPS time as unix system time, -ve if error ************************************************************************/ -time_t GPS_A600_Get(const char *port) +time_t GPS_A600_Get(const char* port) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - time_t ret; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Time); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - switch(gps_date_time_type) - { - case pD600: - ret = GPS_D600_Get(rec); - break; - default: - GPS_Error("A600_Get: Unknown data/time protocol"); - return PROTOCOL_ERROR; - } - - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - - if(!GPS_Device_Off(fd)) - return gps_errno; - - return ret; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + time_t ret; + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Time); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + switch (gps_date_time_type) { + case pD600: + ret = GPS_D600_Get(rec); + break; + default: + GPS_Error("A600_Get: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return ret; } @@ -5665,75 +5952,82 @@ time_t GPS_A600_Get(const char *port) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A600_Send(const char *port, time_t Time) +int32 GPS_A600_Send(const char* port, time_t Time) { - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 posnsent=0; - int32 ret=0; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - switch(gps_date_time_type) - { - case pD600: - GPS_D600_Send(&tra,Time); - break; - default: - GPS_Error("A600_Send: Unknown data/time protocol"); - return PROTOCOL_ERROR; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 posnsent=0; + int32 ret=0; + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + switch (gps_date_time_type) { + case pD600: + GPS_D600_Send(&tra,Time); + break; + default: + GPS_Error("A600_Send: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + if (!GPS_Write_Packet(fd,tra)) { + return gps_error; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_error; + } + + + /* + * Allow GPS a little while to decide whether it wants to ask for + * the position. Note that the posn sent is held in gps_save_lat + * and gps_save_lon globals! + */ + if (GPS_Device_Wait(fd)) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; } - if(!GPS_Write_Packet(fd,tra)) - return gps_error; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_error; - + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } - /* - * Allow GPS a little while to decide whether it wants to ask for - * the position. Note that the posn sent is held in gps_save_lat - * and gps_save_lon globals! - */ - if(GPS_Device_Wait(fd)) - { - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type == LINK_ID[gps_link_type].Pid_Command_Data && - GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. - Cmnd_Transfer_Posn) - { - GPS_User("INFO: GPS position request. Sending...."); - ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); - if(ret < 0) return ret; - posnsent=1; - } + if (rec->type == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Posn) { + GPS_User("INFO: GPS position request. Sending...."); + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if (ret < 0) { + return ret; + } + posnsent=1; } + } - if(!posnsent) - { - ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); - if(ret < 0) return ret; + if (!posnsent) { + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if (ret < 0) { + return ret; } + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -5750,21 +6044,21 @@ int32 GPS_A600_Send(const char *port, time_t Time) ************************************************************************/ time_t GPS_D600_Get(GPS_PPacket packet) { - UC *p; - static struct tm ts; + UC* p; + static struct tm ts; - p = packet->data; + p = packet->data; - ts.tm_mon = *p++ - 1; - ts.tm_mday = *p++; - ts.tm_year = (int32) GPS_Util_Get_Short(p) - 1900; - p+=2; - ts.tm_hour = (int32) GPS_Util_Get_Short(p); - p+=2; - ts.tm_min = *p++; - ts.tm_sec = *p++; + ts.tm_mon = *p++ - 1; + ts.tm_mday = *p++; + ts.tm_year = (int32) GPS_Util_Get_Short(p) - 1900; + p+=2; + ts.tm_hour = (int32) GPS_Util_Get_Short(p); + p+=2; + ts.tm_min = *p++; + ts.tm_sec = *p++; - return mktime(&ts); + return mktime(&ts); } @@ -5777,30 +6071,30 @@ time_t GPS_D600_Get(GPS_PPacket packet) ** ** @return [void] ************************************************************************/ -void GPS_D600_Send(GPS_PPacket *packet, time_t Time) +void GPS_D600_Send(GPS_PPacket* packet, time_t Time) { - UC data[10]; - UC *p; - struct tm *ts; + UC data[10]; + UC* p; + struct tm* ts; - p = data; + p = data; - ts = localtime(&Time); - *p++ = ts->tm_mon+1; - *p++ = ts->tm_mday; + ts = localtime(&Time); + *p++ = ts->tm_mon+1; + *p++ = ts->tm_mday; - GPS_Util_Put_Short(p,(US) (ts->tm_year+1900)); - p+=2; - GPS_Util_Put_Short(p,(US) ts->tm_hour); - p+=2; + GPS_Util_Put_Short(p,(US)(ts->tm_year+1900)); + p+=2; + GPS_Util_Put_Short(p,(US) ts->tm_hour); + p+=2; - *p++ = ts->tm_min; - *p = ts->tm_sec; + *p++ = ts->tm_min; + *p = ts->tm_sec; - GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Date_Time_Data, - data,8); + GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Date_Time_Data, + data,8); - return; + return; } @@ -5816,51 +6110,57 @@ void GPS_D600_Send(GPS_PPacket *packet, time_t Time) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A700_Get(const char *port, double *lat, double *lon) +int32 GPS_A700_Get(const char* port, double* lat, double* lon) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Posn); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - switch(gps_position_type) - { - case pD700: - GPS_D700_Get(rec, lat, lon); - break; - default: - GPS_Error("A700_Get: Unknown position protocol"); - return PROTOCOL_ERROR; - } - - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - - if(!GPS_Device_Off(fd)) - return gps_errno; - - return 1; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Posn); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + switch (gps_position_type) { + case pD700: + GPS_D700_Get(rec, lat, lon); + break; + default: + GPS_Error("A700_Get: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } @@ -5875,42 +6175,46 @@ int32 GPS_A700_Get(const char *port, double *lat, double *lon) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A700_Send(const char *port, double lat, double lon) +int32 GPS_A700_Send(const char* port, double lat, double lon) { - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; - if(!GPS_Device_On(port, &fd)) - return gps_errno; + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - switch(gps_position_type) - { - case pD700: - GPS_D700_Send(&tra,lat,lon); - break; - default: - GPS_Error("A700_Send: Unknown position protocol"); - return PROTOCOL_ERROR; - } + switch (gps_position_type) { + case pD700: + GPS_D700_Send(&tra,lat,lon); + break; + default: + GPS_Error("A700_Send: Unknown position protocol"); + return PROTOCOL_ERROR; + } - if(!GPS_Write_Packet(fd,tra)) - return 0; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return 0; + if (!GPS_Write_Packet(fd,tra)) { + return 0; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return 0; + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -5925,23 +6229,23 @@ int32 GPS_A700_Send(const char *port, double lat, double lon) ** ** @return [void] ************************************************************************/ -void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon) +void GPS_D700_Get(GPS_PPacket packet, double* lat, double* lon) { - UC *p; - double t; + UC* p; + double t; - p = packet->data; + p = packet->data; - t = GPS_Util_Get_Double(p); - *lat = GPS_Math_Rad_To_Deg(t); + t = GPS_Util_Get_Double(p); + *lat = GPS_Math_Rad_To_Deg(t); - p += sizeof(double); + p += sizeof(double); - t = GPS_Util_Get_Double(p); - *lon = GPS_Math_Rad_To_Deg(t); + t = GPS_Util_Get_Double(p); + *lon = GPS_Math_Rad_To_Deg(t); - return; + return; } @@ -5955,24 +6259,24 @@ void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon) ** ** @return [void] ************************************************************************/ -void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon) +void GPS_D700_Send(GPS_PPacket* packet, double lat, double lon) { - UC data[16]; - UC *p; + UC data[16]; + UC* p; - lat = GPS_Math_Deg_To_Rad(lat); - lon = GPS_Math_Deg_To_Rad(lon); + lat = GPS_Math_Deg_To_Rad(lat); + lon = GPS_Math_Deg_To_Rad(lon); - p = data; + p = data; - GPS_Util_Put_Double(p,lat); - p+=sizeof(double); - GPS_Util_Put_Double(p,lon); + GPS_Util_Put_Double(p,lat); + p+=sizeof(double); + GPS_Util_Put_Double(p,lon); - GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Position_Data, - data,16); + GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Position_Data, + data,16); - return; + return; } @@ -5986,35 +6290,37 @@ void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A800_On(const char *port, gpsdevh **fd) +int32 GPS_A800_On(const char* port, gpsdevh** fd) { - static UC data[2]; - GPS_PPacket tra; - GPS_PPacket rec; - - if(!GPS_Device_On(port, fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Start_Pvt_Data); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(*fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(*fd, &tra, &rec)) - { - GPS_Error("A800_on: Pvt start data not acknowledged"); - return FRAMING_ERROR; - } - - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - - return 1; + static UC data[2]; + GPS_PPacket tra; + GPS_PPacket rec; + + if (!GPS_Device_On(port, fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Start_Pvt_Data); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(*fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(*fd, &tra, &rec)) { + GPS_Error("A800_on: Pvt start data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + return 1; } @@ -6028,36 +6334,37 @@ int32 GPS_A800_On(const char *port, gpsdevh **fd) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A800_Off(const char *port, gpsdevh **fd) +int32 GPS_A800_Off(const char* port, gpsdevh** fd) { - static UC data[2]; - GPS_PPacket tra; - GPS_PPacket rec; + static UC data[2]; + GPS_PPacket tra; + GPS_PPacket rec; - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Stop_Pvt_Data); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(*fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(*fd, &tra, &rec)) - { - GPS_Error("A800_Off: Not acknowledged"); - return FRAMING_ERROR; - } + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Stop_Pvt_Data); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(*fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(*fd, &tra, &rec)) { + GPS_Error("A800_Off: Not acknowledged"); + return FRAMING_ERROR; + } - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); // if(!GPS_Device_Off(*fd)) // return gps_errno; - return 1; + return 1; } @@ -6070,49 +6377,49 @@ int32 GPS_A800_Off(const char *port, gpsdevh **fd) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet) +int32 GPS_A800_Get(gpsdevh** fd, GPS_PPvt_Data* packet) { - GPS_PPacket tra; - GPS_PPacket rec; + GPS_PPacket tra; + GPS_PPacket rec; - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - if(!GPS_Packet_Read(*fd, &rec)) { - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - return gps_errno; - } - - if(!GPS_Send_Ack(*fd, &tra, &rec)) { - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - return gps_errno; - } - - if (rec->type != LINK_ID[gps_link_type].Pid_Pvt_Data) { - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - return 0; - } + if (!GPS_Packet_Read(*fd, &rec)) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return gps_errno; + } - switch(gps_pvt_type) - { - case pD800: - GPS_D800_Get(rec,packet); - break; - default: - GPS_Error("A800_GET: Unknown pvt protocol"); - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - return PROTOCOL_ERROR; - } + if (!GPS_Send_Ack(*fd, &tra, &rec)) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return gps_errno; + } + if (rec->type != LINK_ID[gps_link_type].Pid_Pvt_Data) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return 0; + } + + switch (gps_pvt_type) { + case pD800: + GPS_D800_Get(rec,packet); + break; + default: + GPS_Error("A800_GET: Unknown pvt protocol"); GPS_Packet_Del(&rec); GPS_Packet_Del(&tra); + return PROTOCOL_ERROR; + } - return 1; + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + return 1; } @@ -6126,54 +6433,54 @@ int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet) ** ** @return [void] ************************************************************************/ -void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt) +void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data* pvt) { - UC *p; + UC* p; - p = packet->data; + p = packet->data; - (*pvt)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->epe = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->epe = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->eph = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->eph = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->epv = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->epv = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->fix = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*pvt)->fix = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*pvt)->tow = GPS_Util_Get_Double(p); - p+=sizeof(double); + (*pvt)->tow = GPS_Util_Get_Double(p); + p+=sizeof(double); - (*pvt)->lat = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); - p+=sizeof(double); + (*pvt)->lat = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); + p+=sizeof(double); - (*pvt)->lon = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); - p+=sizeof(double); + (*pvt)->lon = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); + p+=sizeof(double); - (*pvt)->east = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->east = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->north = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->north = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->up = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->up = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->msl_hght = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->msl_hght = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->leap_scnds = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*pvt)->leap_scnds = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*pvt)->wn_days = GPS_Util_Get_Int(p); + (*pvt)->wn_days = GPS_Util_Get_Int(p); - return; + return; } /* @func GPS_A906_Get ****************************************************** @@ -6186,92 +6493,102 @@ void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt) ** @return [int32] number of lap entries ************************************************************************/ -int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb) +int32 GPS_A906_Get(const char* port, GPS_PLap** lap, pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_lap_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Laps); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - if(n) - if(!((*lap)=(GPS_PLap *)malloc(n*sizeof(GPS_PLap)))) - { - GPS_Error("A906_Get: Insufficient memory"); - return MEMORY_ERROR; - } + static UC data[2]; + gpsdevh* fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_lap_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Laps); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + if (n) + if (!((*lap)=(GPS_PLap*)malloc(n*sizeof(GPS_PLap)))) { + GPS_Error("A906_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + for (i=0; idata); + break; + default: + GPS_Error("A906_Get: Unknown Lap protocol %d\n", gps_lap_type); + return PROTOCOL_ERROR; + } - for(i=0;idata); - break; - default: - GPS_Error("A906_Get: Unknown Lap protocol %d\n", gps_lap_type); - return PROTOCOL_ERROR; - } - - /* Cheat and don't _really_ pass the trkpt back */ - cb(n, NULL); - } - - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A906_Get: Error transferring laps"); - return FRAMING_ERROR; - } - - if(i != n) { - GPS_Error("A906_GET: Lap entry number mismatch"); - return FRAMING_ERROR; - } - - GPS_Packet_Del(&trapkt); - GPS_Packet_Del(&recpkt); - - if (!GPS_Device_Off(fd)) - return gps_errno; - return n; + /* Cheat and don't _really_ pass the trkpt back */ + cb(n, NULL); + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A906_Get: Error transferring laps"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A906_GET: Lap entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return n; } /* @func GPS_D1011b_Get ****************************************************** @@ -6283,95 +6600,95 @@ int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb) ** ** @return [void] ************************************************************************/ -void GPS_D1011b_Get(GPS_PLap *Lap, UC *p) +void GPS_D1011b_Get(GPS_PLap* Lap, UC* p) { - uint32 t; - - /* Lap index (not in D906) */ - switch(gps_lap_type) { - case pD906: - (*Lap)->index = -1; - break; - case pD1001: - (*Lap)->index = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); - break; - case pD1011: - case pD1015: - (*Lap)->index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); - p+=sizeof(uint16); /*unused*/ - break; - default: - break; - } - - t = GPS_Util_Get_Uint(p); - (*Lap)->start_time = GPS_Math_Gtime_To_Utime((time_t)t); + uint32 t; + + /* Lap index (not in D906) */ + switch (gps_lap_type) { + case pD906: + (*Lap)->index = -1; + break; + case pD1001: + (*Lap)->index = GPS_Util_Get_Uint(p); p+=sizeof(uint32); - - (*Lap)->total_time = GPS_Util_Get_Int(p); - p+=sizeof(int32); - - (*Lap)->total_distance = GPS_Util_Get_Float(p); + break; + case pD1011: + case pD1015: + (*Lap)->index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); + p+=sizeof(uint16); /*unused*/ + break; + default: + break; + } + + t = GPS_Util_Get_Uint(p); + (*Lap)->start_time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); + + (*Lap)->total_time = GPS_Util_Get_Int(p); + p+=sizeof(int32); + + (*Lap)->total_distance = GPS_Util_Get_Float(p); + p+=sizeof(float); + if (gps_lap_type != pD906) { + (*Lap)->max_speed = GPS_Util_Get_Float(p); p+=sizeof(float); - if(gps_lap_type != pD906){ - (*Lap)->max_speed = GPS_Util_Get_Float(p); - p+=sizeof(float); - } - - (*Lap)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*Lap)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*Lap)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*Lap)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*Lap)->calories = GPS_Util_Get_Short(p); - p+=sizeof(int16); - - /* Track index, only in D906*/ - if(gps_lap_type == pD906){ - (*Lap)->track_index = *p++; - p++; /*Unused*/ - - /*Last field, no more to do */ - return; - } else { - (*Lap)->track_index = -1; - } - - (*Lap)->avg_heart_rate = *p++; - (*Lap)->max_heart_rate = *p++; - (*Lap)->intensity = *p++; - - switch(gps_lap_type) { - case pD1001: - /*No more fields */ - return; - case pD1011: - case pD1015: - (*Lap)->avg_cadence = *p++; - (*Lap)->trigger_method = *p++; - break; - default: - /*pD906 already returned*/ - break; - } + } + + (*Lap)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*Lap)->calories = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + /* Track index, only in D906*/ + if (gps_lap_type == pD906) { + (*Lap)->track_index = *p++; + p++; /*Unused*/ + + /*Last field, no more to do */ + return; + } else { + (*Lap)->track_index = -1; + } - if (gps_lap_type==pD1015) { - /*some unknown fields like 04 dc 44 ff ff */ - /* (*Lap)->unk1015_1 = *p++; normally 4? - (*Lap)->unk1015_2 = GPS_Util_Get_Short(p);wkt related , ffff otherwise - p+=sizeof(int16); - (*Lap)->unk1015_3 = GPS_Util_Get_Short(p);ffff ? - p+=sizeof(int16); - */ - } + (*Lap)->avg_heart_rate = *p++; + (*Lap)->max_heart_rate = *p++; + (*Lap)->intensity = *p++; + switch (gps_lap_type) { + case pD1001: + /*No more fields */ return; + case pD1011: + case pD1015: + (*Lap)->avg_cadence = *p++; + (*Lap)->trigger_method = *p++; + break; + default: + /*pD906 already returned*/ + break; + } + + if (gps_lap_type==pD1015) { + /*some unknown fields like 04 dc 44 ff ff */ + /* (*Lap)->unk1015_1 = *p++; normally 4? + (*Lap)->unk1015_2 = GPS_Util_Get_Short(p);wkt related , ffff otherwise + p+=sizeof(int16); + (*Lap)->unk1015_3 = GPS_Util_Get_Short(p);ffff ? + p+=sizeof(int16); + */ + } + + return; } @@ -6394,96 +6711,106 @@ void GPS_D1011b_Get(GPS_PLap *Lap, UC *p) ************************************************************************/ int32 GPS_A1006_Get - (const char *port, - GPS_PCourse **crs, - pcb_fn cb) +(const char* port, + GPS_PCourse** crs, + pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_course_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Courses); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - - if(n) - if(!((*crs)=(GPS_PCourse *)malloc(n*sizeof(GPS_PCourse)))) - { - GPS_Error("A1006_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata); - break; - default: - GPS_Error("A1006_Get: Unknown Course protocol %d\n", - gps_course_type); - return PROTOCOL_ERROR; - } - - // Cheat and don't _really_ pass the crs back - if (cb) { - cb(n, NULL); - } + static UC data[2]; + gpsdevh* fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_course_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Courses); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + + if (n) + if (!((*crs)=(GPS_PCourse*)malloc(n*sizeof(GPS_PCourse)))) { + GPS_Error("A1006_Get: Insufficient memory"); + return MEMORY_ERROR; } - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A1006_Get: Error transferring courses"); - return FRAMING_ERROR; + for (i=0; idata); + break; + default: + GPS_Error("A1006_Get: Unknown Course protocol %d\n", + gps_course_type); + return PROTOCOL_ERROR; + } - if (!GPS_Device_Off(fd)) - return gps_errno; - return n; + // Cheat and don't _really_ pass the crs back + if (cb) { + cb(n, NULL); + } + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A1006_Get: Error transferring courses"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A1006_GET: Course entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return n; } @@ -6502,71 +6829,71 @@ int32 GPS_A1006_Get ** ** @return [int32] success ************************************************************************/ -int32 GPS_A1006_Send(const char *port, - GPS_PCourse *crs, +int32 GPS_A1006_Send(const char* port, + GPS_PCourse* crs, int32 n_crs, - gpsdevh *fd) + gpsdevh* fd) { - UC data[GPS_ARB_LEN]; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n_crs); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A1006_Send: Course start data not acknowledged"); - return FRAMING_ERROR; - } - - for(i=0;iindex = GPS_Util_Get_Short(p); - p+=sizeof(uint16); - p+=sizeof(uint16); // unused - for(i=0;i<16;++i) - (*crs)->course_name[i] = *p++; - (*crs)->track_index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); + int i; + (*crs)->index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); + p+=sizeof(uint16); // unused + for (i=0; i<16; ++i) { + (*crs)->course_name[i] = *p++; + } + (*crs)->track_index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); } @@ -6602,26 +6930,28 @@ void GPS_D1006_Get(GPS_PCourse *crs, UC *p) ** ** @return [void] ************************************************************************/ -void GPS_D1006_Send(UC *data, GPS_PCourse crs, int32 *len) +void GPS_D1006_Send(UC* data, GPS_PCourse crs, int32* len) { - UC *p; - int j; - p = data; + UC* p; + int j; + p = data; - GPS_Util_Put_Short(p, (US) crs->index); - p += 2; + GPS_Util_Put_Short(p, (US) crs->index); + p += 2; - GPS_Util_Put_Uint(p,0); - p+=sizeof(uint16); + GPS_Util_Put_Uint(p,0); + p+=sizeof(uint16); - for(j=0;j<16;++j) *p++ = crs->course_name[j]; + for (j=0; j<16; ++j) { + *p++ = crs->course_name[j]; + } - GPS_Util_Put_Short(p, (US) crs->track_index); - p += 2; + GPS_Util_Put_Short(p, (US) crs->track_index); + p += 2; - *len = p-data; + *len = p-data; - return; + return; } @@ -6635,93 +6965,103 @@ void GPS_D1006_Send(UC *data, GPS_PCourse crs, int32 *len) ** @return [int32] number of lap entries ************************************************************************/ -int32 GPS_A1007_Get(const char *port, GPS_PCourse_Lap **clp, pcb_fn cb) +int32 GPS_A1007_Get(const char* port, GPS_PCourse_Lap** clp, pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_course_lap_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Laps); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - - if(n) - if(!((*clp)=(GPS_PCourse_Lap *)malloc(n*sizeof(GPS_PCourse_Lap)))) - { - GPS_Error("A1007_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata); - break; - default: - GPS_Error("A1007_Get: Unknown Course Lap protocol %d\n", - gps_course_lap_type); - return PROTOCOL_ERROR; - } - - /* Cheat and don't _really_ pass the trkpt back */ - if (cb) { - cb(n, NULL); - } + static UC data[2]; + gpsdevh* fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_course_lap_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Laps); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + + if (n) + if (!((*clp)=(GPS_PCourse_Lap*)malloc(n*sizeof(GPS_PCourse_Lap)))) { + GPS_Error("A1007_Get: Insufficient memory"); + return MEMORY_ERROR; } - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A1007_Get: Error transferring course laps"); - return FRAMING_ERROR; + for (i=0; idata); + break; + default: + GPS_Error("A1007_Get: Unknown Course Lap protocol %d\n", + gps_course_lap_type); + return PROTOCOL_ERROR; + } - if (!GPS_Device_Off(fd)) - return gps_errno; - return n; + /* Cheat and don't _really_ pass the trkpt back */ + if (cb) { + cb(n, NULL); + } + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A1007_Get: Error transferring course laps"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A1007_GET: Course Lap entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return n; } @@ -6740,71 +7080,71 @@ int32 GPS_A1007_Get(const char *port, GPS_PCourse_Lap **clp, pcb_fn cb) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A1007_Send(const char *port, - GPS_PCourse_Lap *clp, +int32 GPS_A1007_Send(const char* port, + GPS_PCourse_Lap* clp, int32 n_clp, - gpsdevh *fd) + gpsdevh* fd) { - UC data[GPS_ARB_LEN]; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n_clp); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A1007_Send: CourseLap start data not acknowledged"); - return FRAMING_ERROR; - } - - for(i=0;icourse_index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); + (*clp)->course_index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); - (*clp)->lap_index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); + (*clp)->lap_index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); - (*clp)->total_time = GPS_Util_Get_Int(p); - p+=sizeof(uint32); + (*clp)->total_time = GPS_Util_Get_Int(p); + p+=sizeof(uint32); - (*clp)->total_dist = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*clp)->total_dist = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*clp)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*clp)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*clp)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*clp)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*clp)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*clp)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*clp)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*clp)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*clp)->avg_heart_rate = *p++; - (*clp)->max_heart_rate = *p++; - (*clp)->intensity = *p++; - (*clp)->avg_cadence = *p++; + (*clp)->avg_heart_rate = *p++; + (*clp)->max_heart_rate = *p++; + (*clp)->intensity = *p++; + (*clp)->avg_cadence = *p++; - return; + return; } @@ -6859,44 +7199,44 @@ void GPS_D1007_Get(GPS_PCourse_Lap *clp, UC *p) ** ** @return [void] ************************************************************************/ -void GPS_D1007_Send(UC *data, GPS_PCourse_Lap clp, int32 *len) +void GPS_D1007_Send(UC* data, GPS_PCourse_Lap clp, int32* len) { - UC *p; - p = data; + UC* p; + p = data; - GPS_Util_Put_Short(p, (US) clp->course_index); - p += 2; + GPS_Util_Put_Short(p, (US) clp->course_index); + p += 2; - GPS_Util_Put_Short(p, (US) clp->lap_index); - p += 2; + GPS_Util_Put_Short(p, (US) clp->lap_index); + p += 2; - GPS_Util_Put_Uint(p, clp->total_time); - p+=sizeof(int32); + GPS_Util_Put_Uint(p, clp->total_time); + p+=sizeof(int32); - GPS_Util_Put_Float(p,clp->total_dist); - p+= sizeof(float); + GPS_Util_Put_Float(p,clp->total_dist); + p+= sizeof(float); - GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->begin_lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->begin_lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->begin_lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->begin_lon)); + p+=sizeof(int32); - GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->end_lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->end_lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->end_lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->end_lon)); + p+=sizeof(int32); - *p++ = clp->avg_heart_rate; + *p++ = clp->avg_heart_rate; - *p++ = clp->max_heart_rate; + *p++ = clp->max_heart_rate; - *p++ = clp->intensity; + *p++ = clp->intensity; - *p++ = clp->avg_cadence; + *p++ = clp->avg_cadence; - *len = p-data; + *len = p-data; - return; + return; } @@ -6910,93 +7250,103 @@ void GPS_D1007_Send(UC *data, GPS_PCourse_Lap clp, int32 *len) ** @return [int32] number of course point entries ************************************************************************/ -int32 GPS_A1008_Get(const char *port, GPS_PCourse_Point **cpt, pcb_fn cb) +int32 GPS_A1008_Get(const char* port, GPS_PCourse_Point** cpt, pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_course_point_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Points); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - - if(n) - if(!((*cpt)=(GPS_PCourse_Point *)malloc(n*sizeof(GPS_PCourse_Point)))) - { - GPS_Error("A1008_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata); - break; - default: - GPS_Error("A1008_Get: Unknown Course Point protocol %d\n", - gps_course_point_type); - return PROTOCOL_ERROR; - } - - /* Cheat and don't _really_ pass the trkpt back */ - if (cb) { - cb(n, NULL); - } + static UC data[2]; + gpsdevh* fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_course_point_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Points); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + + if (n) + if (!((*cpt)=(GPS_PCourse_Point*)malloc(n*sizeof(GPS_PCourse_Point)))) { + GPS_Error("A1008_Get: Insufficient memory"); + return MEMORY_ERROR; } - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A1008_Get: Error transferring course points"); - return FRAMING_ERROR; + for (i=0; idata); + break; + default: + GPS_Error("A1008_Get: Unknown Course Point protocol %d\n", + gps_course_point_type); + return PROTOCOL_ERROR; + } - if (!GPS_Device_Off(fd)) - return gps_errno; - return n; + /* Cheat and don't _really_ pass the trkpt back */ + if (cb) { + cb(n, NULL); + } + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A1008_Get: Error transferring course points"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A1008_GET: Course Point entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return n; } @@ -7016,71 +7366,71 @@ int32 GPS_A1008_Get(const char *port, GPS_PCourse_Point **cpt, pcb_fn cb) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A1008_Send(const char *port, - GPS_PCourse_Point *cpt, +int32 GPS_A1008_Send(const char* port, + GPS_PCourse_Point* cpt, int32 n_cpt, - gpsdevh *fd) + gpsdevh* fd) { - UC data[GPS_ARB_LEN]; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n_cpt); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("GPS_A1008_Send: Coursepoint start data not acknowledged"); - return FRAMING_ERROR; - } - - for(i=0;iname[i] = *p++; - p++; //unused - (*cpt)->course_index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); - p+=sizeof(uint16); // unused + for (i=0; i<11; ++i) { + (*cpt)->name[i] = *p++; + } + p++; //unused + (*cpt)->course_index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); + p+=sizeof(uint16); // unused - t = GPS_Util_Get_Uint(p); - (*cpt)->track_point_time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + t = GPS_Util_Get_Uint(p); + (*cpt)->track_point_time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); - (*cpt)->point_type = *p++; + (*cpt)->point_type = *p++; } @@ -7124,31 +7475,33 @@ void GPS_D1012_Get(GPS_PCourse_Point *cpt, UC *p) ** ** @return [void] ************************************************************************/ -void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len) +void GPS_D1012_Send(UC* data, GPS_PCourse_Point cpt, int32* len) { - UC *p; - int j; - p = data; + UC* p; + int j; + p = data; - for(j=0;j<11;++j) *p++ = cpt->name[j]; + for (j=0; j<11; ++j) { + *p++ = cpt->name[j]; + } - GPS_Util_Put_Uint(p,0); - p++; + GPS_Util_Put_Uint(p,0); + p++; - GPS_Util_Put_Short(p, (US) cpt->course_index); - p += 2; + GPS_Util_Put_Short(p, (US) cpt->course_index); + p += 2; - GPS_Util_Put_Uint(p,0); - p+=sizeof(uint16); + GPS_Util_Put_Uint(p,0); + p+=sizeof(uint16); - GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(cpt->track_point_time)); - p+=sizeof(uint32); + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(cpt->track_point_time)); + p+=sizeof(uint32); - *p++ = cpt->point_type; + *p++ = cpt->point_type; - *len = p-data; + *len = p-data; - return; + return; } @@ -7162,51 +7515,59 @@ void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len) ** @return [int32] success ************************************************************************/ -int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits) +int32 GPS_A1009_Get(const char* port, GPS_PCourse_Limits limits) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - - if (gps_course_limits_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Limits); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - switch(gps_course_limits_type) { - case pD1013: - GPS_D1013_Get(limits,recpkt->data); - break; - default: - GPS_Error("A1009_Get: Unknown Course Limits protocol %d\n", - gps_course_limits_type); - return PROTOCOL_ERROR; - } - - GPS_Packet_Del(&trapkt); - GPS_Packet_Del(&recpkt); - - if (!GPS_Device_Off(fd)) - return gps_errno; - return 1; + static UC data[2]; + gpsdevh* fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + + if (gps_course_limits_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Limits); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + switch (gps_course_limits_type) { + case pD1013: + GPS_D1013_Get(limits,recpkt->data); + break; + default: + GPS_Error("A1009_Get: Unknown Course Limits protocol %d\n", + gps_course_limits_type); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return 1; } @@ -7219,19 +7580,19 @@ int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits) ** ** @return [void] ************************************************************************/ -void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p) +void GPS_D1013_Get(GPS_PCourse_Limits limits, UC* p) { - limits->max_courses = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + limits->max_courses = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); - limits->max_course_laps = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + limits->max_course_laps = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); - limits->max_course_pnt = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + limits->max_course_pnt = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); - limits->max_course_trk_pnt = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + limits->max_course_trk_pnt = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); } @@ -7239,121 +7600,207 @@ void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p) * It's unfortunate that these aren't constant and therefore switchable, * but they really are runtime variable. Sigh. */ -const char * -Get_Pkt_Type(US p, US d0, const char **xinfo) +const char* +Get_Pkt_Type(US p, US d0, const char** xinfo) { - *xinfo = NULL; + *xinfo = NULL; #define LT LINK_ID[gps_link_type] - if (p == LT.Pid_Ack_Byte) - return "ACK"; - if (p == LT.Pid_Command_Data) { - switch (d0) { - case 0: *xinfo = "Abort"; break; - case 1: *xinfo = "Xfer Alm"; break; - case 2: *xinfo = "Xfer Posn"; break; - case 3: *xinfo = "Xfer Prx"; break; - case 4: *xinfo = "Xfer Rte"; break; - case 5: *xinfo = "Xfer Time"; break; - case 6: *xinfo = "Xfer Trk"; break; - case 7: *xinfo = "Xfer Wpt"; break; - case 8: *xinfo = "Power Down"; break; - case 49: *xinfo = "Xfer PVT Start"; break; - case 50: *xinfo = "Xfer PVT Stop"; break; - case 92: *xinfo = "Flight Records"; break; - case 117: *xinfo = "Xfer Laps"; break; - case 121: *xinfo = "Xfer Categories"; break; - case 450: *xinfo = "Xfer Runs"; break; - case 451: *xinfo = "Xfer Workouts"; break; - case 452: *xinfo = "Xfer Wkt Occurrences"; break; - case 453: *xinfo = "Xfer User Profile "; break; - case 454: *xinfo = "Xfer Wkt Limits"; break; - case 561: *xinfo = "Xfer Courses"; break; - case 562: *xinfo = "Xfer Course Laps"; break; - case 563: *xinfo = "Xfer Course Point"; break; - case 564: *xinfo = "Xfer Course Tracks"; break; - case 565: *xinfo = "Xfer Course Limits"; break; - - default: *xinfo = "Unknown"; - } - return "CMDDAT"; - } - if (p == LT.Pid_Protocol_Array) - return "PRTARR"; - if (p == LT.Pid_Product_Rqst) - return "PRDREQ"; - if (p == LT.Pid_Product_Data) - return "PRDDAT"; - if (p == LT.Pid_Ext_Product_Data) - return "PRDEDA"; - - if (p == LT.Pid_Xfer_Cmplt) - return "XFRCMP"; - if (p == LT.Pid_Date_Time_Data) - return "DATTIM"; - if (p == LT.Pid_Position_Data) - return "POS"; - if (p == LT.Pid_Prx_Wpt_Data) - return "WPT"; - if (p == LT.Pid_Nak_Byte) - return "NAK"; - if (p == LT.Pid_Records) - return "RECORD"; - if (p == LT.Pid_Rte_Hdr) - return "RTEHDR"; - if (p == LT.Pid_Rte_Wpt_Data) - return "RTEWPT"; - if (p == LT.Pid_Almanac_Data) - return "RALMAN"; - if (p == LT.Pid_Trk_Data) - return "TRKDAT"; - if (p == LT.Pid_Wpt_Data) - return "WPTDAT"; - if (p == LT.Pid_Pvt_Data) - return "PVTDAT"; - if (p == LT.Pid_Rte_Link_Data) - return "LNKDAT"; - if (p == LT.Pid_Trk_Hdr) - return "TRKHDR"; - - if (p == LT.Pid_FlightBook_Record) - return "FLIBOO"; - if (p == LT.Pid_Lap) - return "LAPDAT"; - if (p == LT.Pid_Wpt_Cat) - return "WPTCAT"; - if (p == LT.Pid_Run) - return "RUNDAT"; - if (p == LT.Pid_Workout) - return "WKTDAT"; - if (p == LT.Pid_Workout_Occurrence) - return "WKTOCC"; - if (p == LT.Pid_Fitness_User_Profile) - return "UPROFI"; - if (p == LT.Pid_Workout_Limits) - return "WKTLIM"; - if (p == LT.Pid_Course) - return "CRSDAT"; - if (p == LT.Pid_Course_Lap) - return "CRSLAP"; - if (p == LT.Pid_Course_Point) - return "CRSPOI"; - if (p == LT.Pid_Course_Trk_Hdr) - return "CRSTHD"; - if (p == LT.Pid_Course_Trk_Data) - return "CRSTDA"; - if (p == LT.Pid_Course_Limits) - return "CRSLIM"; - if (p == LT.Pid_Trk2_Hdr) - return "TRKHD2"; - - if (p == GUSB_REQUEST_BULK) - return "REQBLK"; - if (p == GUSB_SESSION_START) - return "SESREQ"; - if (p == GUSB_SESSION_ACK) - return "SESACK"; - - return "UNKNOWN"; + if (p == LT.Pid_Ack_Byte) { + return "ACK"; + } + if (p == LT.Pid_Command_Data) { + switch (d0) { + case 0: + *xinfo = "Abort"; + break; + case 1: + *xinfo = "Xfer Alm"; + break; + case 2: + *xinfo = "Xfer Posn"; + break; + case 3: + *xinfo = "Xfer Prx"; + break; + case 4: + *xinfo = "Xfer Rte"; + break; + case 5: + *xinfo = "Xfer Time"; + break; + case 6: + *xinfo = "Xfer Trk"; + break; + case 7: + *xinfo = "Xfer Wpt"; + break; + case 8: + *xinfo = "Power Down"; + break; + case 49: + *xinfo = "Xfer PVT Start"; + break; + case 50: + *xinfo = "Xfer PVT Stop"; + break; + case 92: + *xinfo = "Flight Records"; + break; + case 117: + *xinfo = "Xfer Laps"; + break; + case 121: + *xinfo = "Xfer Categories"; + break; + case 450: + *xinfo = "Xfer Runs"; + break; + case 451: + *xinfo = "Xfer Workouts"; + break; + case 452: + *xinfo = "Xfer Wkt Occurrences"; + break; + case 453: + *xinfo = "Xfer User Profile "; + break; + case 454: + *xinfo = "Xfer Wkt Limits"; + break; + case 561: + *xinfo = "Xfer Courses"; + break; + case 562: + *xinfo = "Xfer Course Laps"; + break; + case 563: + *xinfo = "Xfer Course Point"; + break; + case 564: + *xinfo = "Xfer Course Tracks"; + break; + case 565: + *xinfo = "Xfer Course Limits"; + break; + + default: + *xinfo = "Unknown"; + } + return "CMDDAT"; + } + if (p == LT.Pid_Protocol_Array) { + return "PRTARR"; + } + if (p == LT.Pid_Product_Rqst) { + return "PRDREQ"; + } + if (p == LT.Pid_Product_Data) { + return "PRDDAT"; + } + if (p == LT.Pid_Ext_Product_Data) { + return "PRDEDA"; + } + + if (p == LT.Pid_Xfer_Cmplt) { + return "XFRCMP"; + } + if (p == LT.Pid_Date_Time_Data) { + return "DATTIM"; + } + if (p == LT.Pid_Position_Data) { + return "POS"; + } + if (p == LT.Pid_Prx_Wpt_Data) { + return "WPT"; + } + if (p == LT.Pid_Nak_Byte) { + return "NAK"; + } + if (p == LT.Pid_Records) { + return "RECORD"; + } + if (p == LT.Pid_Rte_Hdr) { + return "RTEHDR"; + } + if (p == LT.Pid_Rte_Wpt_Data) { + return "RTEWPT"; + } + if (p == LT.Pid_Almanac_Data) { + return "RALMAN"; + } + if (p == LT.Pid_Trk_Data) { + return "TRKDAT"; + } + if (p == LT.Pid_Wpt_Data) { + return "WPTDAT"; + } + if (p == LT.Pid_Pvt_Data) { + return "PVTDAT"; + } + if (p == LT.Pid_Rte_Link_Data) { + return "LNKDAT"; + } + if (p == LT.Pid_Trk_Hdr) { + return "TRKHDR"; + } + + if (p == LT.Pid_FlightBook_Record) { + return "FLIBOO"; + } + if (p == LT.Pid_Lap) { + return "LAPDAT"; + } + if (p == LT.Pid_Wpt_Cat) { + return "WPTCAT"; + } + if (p == LT.Pid_Run) { + return "RUNDAT"; + } + if (p == LT.Pid_Workout) { + return "WKTDAT"; + } + if (p == LT.Pid_Workout_Occurrence) { + return "WKTOCC"; + } + if (p == LT.Pid_Fitness_User_Profile) { + return "UPROFI"; + } + if (p == LT.Pid_Workout_Limits) { + return "WKTLIM"; + } + if (p == LT.Pid_Course) { + return "CRSDAT"; + } + if (p == LT.Pid_Course_Lap) { + return "CRSLAP"; + } + if (p == LT.Pid_Course_Point) { + return "CRSPOI"; + } + if (p == LT.Pid_Course_Trk_Hdr) { + return "CRSTHD"; + } + if (p == LT.Pid_Course_Trk_Data) { + return "CRSTDA"; + } + if (p == LT.Pid_Course_Limits) { + return "CRSLIM"; + } + if (p == LT.Pid_Trk2_Hdr) { + return "TRKHD2"; + } + + if (p == GUSB_REQUEST_BULK) { + return "REQBLK"; + } + if (p == GUSB_SESSION_START) { + return "SESREQ"; + } + if (p == GUSB_SESSION_ACK) { + return "SESACK"; + } + + return "UNKNOWN"; } @@ -7370,13 +7817,13 @@ Get_Pkt_Type(US p, US d0, const char **xinfo) ************************************************************************/ static UC Is_Trackpoint_Invalid(GPS_PTrack trk) { - /* FIXME: We should have more *_is_unknown fields instead of - * checking for special values here (e.g. cadence = 0 would be - * perfectly valid, but GPS_D303b_Get() chose to use it to mark - * nonexistent cadence data. - */ - return trk->no_latlon && trk->distance > 1e24 && - !trk->heartrate && !trk->cadence; + /* FIXME: We should have more *_is_unknown fields instead of + * checking for special values here (e.g. cadence = 0 would be + * perfectly valid, but GPS_D303b_Get() chose to use it to mark + * nonexistent cadence data. + */ + return trk->no_latlon && trk->distance > 1e24 && + !trk->heartrate && !trk->cadence; } @@ -7387,45 +7834,40 @@ static UC Is_Trackpoint_Invalid(GPS_PTrack trk) ** @param [r] trk [GPS_PTrack **] track ** @param [r] n [int32 *] Number of trackpoints ************************************************************************/ -void GPS_Prepare_Track_For_Device(GPS_PTrack **trk, int32 *n) +void GPS_Prepare_Track_For_Device(GPS_PTrack** trk, int32* n) { - int32 i, j; - - /* D303/304 marks track segments with two consecutive invalid track - * points instead of the tnew flag. Create them unless we're at the - * beginning of a track or there are already invalid track points - * (because the track was downloaded using D303/304). This needs to be - * done here because it will change the number of track points. - */ - if (gps_trk_type == pD303 || gps_trk_type == pD304) - { - for(i=0;i<*n;++i) - { - if ((*trk)[i]->tnew && i>0 && !(*trk)[i]->ishdr && !(*trk)[i-1]->ishdr) - { - /* Create invalid points based on the data from the point - * marked with tnew and the one before it. - */ - for (j=i-1; j<=i; j++) - { - if (!Is_Trackpoint_Invalid((*trk)[j])) - { - GPS_PTrack trkpt = GPS_Track_New(); - *trkpt = *((*trk)[j]); - trkpt->no_latlon = 1; - trkpt->alt = (float) 1e25; - trkpt->distance_populated = 0; - trkpt->heartrate = 0; - trkpt->cadence = 0xff; - *trk = xrealloc(*trk, (*n+1) * sizeof(GPS_PTrack)); - memmove(&(*trk)[i+1], &(*trk)[i], (*n-i) * sizeof(GPS_PTrack)); - (*trk)[i] = trkpt; - i++; - j++; - (*n)++; - } - } - } - } + int32 i, j; + + /* D303/304 marks track segments with two consecutive invalid track + * points instead of the tnew flag. Create them unless we're at the + * beginning of a track or there are already invalid track points + * (because the track was downloaded using D303/304). This needs to be + * done here because it will change the number of track points. + */ + if (gps_trk_type == pD303 || gps_trk_type == pD304) { + for (i=0; i<*n; ++i) { + if ((*trk)[i]->tnew && i>0 && !(*trk)[i]->ishdr && !(*trk)[i-1]->ishdr) { + /* Create invalid points based on the data from the point + * marked with tnew and the one before it. + */ + for (j=i-1; j<=i; j++) { + if (!Is_Trackpoint_Invalid((*trk)[j])) { + GPS_PTrack trkpt = GPS_Track_New(); + *trkpt = *((*trk)[j]); + trkpt->no_latlon = 1; + trkpt->alt = (float) 1e25; + trkpt->distance_populated = 0; + trkpt->heartrate = 0; + trkpt->cadence = 0xff; + *trk = (struct GPS_STrack**) xrealloc(*trk, (*n+1) * sizeof(GPS_PTrack)); + memmove(&(*trk)[i+1], &(*trk)[i], (*n-i) * sizeof(GPS_PTrack)); + (*trk)[i] = trkpt; + i++; + j++; + (*n)++; + } + } + } } + } } diff --git a/gpsbabel/jeeps/gpsapp.h b/gpsbabel/jeeps/gpsapp.h index 6d1ee33cc..6f88fcc6b 100644 --- a/gpsbabel/jeeps/gpsapp.h +++ b/gpsbabel/jeeps/gpsapp.h @@ -9,112 +9,112 @@ extern "C" #include "gps.h" -int32 GPS_Init(const char *port); - -int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int ct, GPS_PWay *)); -int32 GPS_A101_Get(const char *port); -int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)); - -int32 GPS_A200_Get(const char *port, GPS_PWay **way); -int32 GPS_A201_Get(const char *port, GPS_PWay **way); -int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n); -int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n); - -int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb); -int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb, int protoid); -int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n); -int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n, int protoid, - gpsdevh *fd); - -int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *h); -void GPS_D300b_Get(GPS_PTrack *trk, UC *data); -void GPS_D301b_Get(GPS_PTrack *trk, UC *data); -void GPS_D302b_Get(GPS_PTrack *trk, UC *data); -void GPS_D303b_Get(GPS_PTrack *trk, UC *data); /*D304*/ -void GPS_D310_Get(GPS_PTrack *trk, UC *s); -void GPS_D311_Get(GPS_PTrack *trk, UC *s); -void GPS_D300_Send(UC *data, GPS_PTrack trk, int32 *len); -void GPS_D301_Send(UC *data, GPS_PTrack trk, int32 *len, int type); -void GPS_D303_Send(UC *data, GPS_PTrack trk, int32 *len, int protoid); -void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len); -void GPS_D311_Send(UC *data, GPS_PTrack trk, int32 *len); - -int32 GPS_A400_Get(const char *port, GPS_PWay **way); -int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n); - -int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm); -int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n); - -time_t GPS_A600_Get(const char *port); -time_t GPS_D600_Get(GPS_PPacket packet); -int32 GPS_A600_Send(const char *port, time_t Time); -void GPS_D600_Send(GPS_PPacket *packet, time_t Time); - -int32 GPS_A700_Get(const char *port, double *lat, double *lon); -int32 GPS_A700_Send(const char *port, double lat, double lon); -void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon); -void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon); - -int32 GPS_A800_On(const char *port, gpsdevh **fd); -int32 GPS_A800_Off(const char *port, gpsdevh **fd); -int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet); -void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt); - -int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb); -void GPS_D1011b_Get(GPS_PLap *Lap,UC *data); /*D906 D1001 D1015*/ - -int32 GPS_A1006_Get(const char *port, GPS_PCourse **crs, pcb_fn cb); -int32 GPS_A1006_Send(const char *port, GPS_PCourse *crs, int32 n_crs, - gpsdevh *fd); -void GPS_D1006_Get(GPS_PCourse *crs, UC *p); -void GPS_D1006_Send(UC *data, GPS_PCourse crs, int32 *len); - -int32 GPS_A1007_Get(const char *port, GPS_PCourse_Lap **clp, pcb_fn cb); -int32 GPS_A1007_Send(const char *port, GPS_PCourse_Lap *clp, int32 n_clp, - gpsdevh *fd); -void GPS_D1007_Get(GPS_PCourse_Lap *clp, UC *p); -void GPS_D1007_Send(UC *data, GPS_PCourse_Lap clp, int32 *len); - -int32 GPS_A1008_Get(const char *port, GPS_PCourse_Point **cpt, pcb_fn cb); -int32 GPS_A1008_Send(const char *port, GPS_PCourse_Point *cpt, int32 n_cpt, - gpsdevh *fd); -void GPS_D1012_Get(GPS_PCourse_Point *cpt, UC *p); -void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len); - -int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits); -void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p); - -/* Unhandled documented protocols, as of: - Garmin Device Interface Specification, May 19, 2006, Drawing Number: 001-00063-00 Rev. C -A650 FlightBook Transfer Protocol -A1000 Run Transfer Protocol - Capability A1000: D1009 - D1000 D1010 -A1002 Workout Transfer Protocol - Capability A1002: D1008 - D1002 - Capability A1003: D1003 -A1004 Fitness User Profile Transfer Protocol - Capability A1004: D1004 -A1005 Workout Limits Transfer Protocol - Capability A1005: D1005 -*/ -/* Unimplemted and Undocumented, as listed from the following device/sw: - GF305 3.70 - -Capability A601: D601 -Capability A801: D801 - -Capability A902: -Capability A903: -Capability A907: D907 D908 D909 D910 -Capability A918: D918 -Capability A1013: D1014 -*/ - -const char * Get_Pkt_Type(US p, US d0, const char **xinfo); - -void GPS_Prepare_Track_For_Device(GPS_PTrack **trk, int32 *n); + int32 GPS_Init(const char* port); + + int32 GPS_A100_Get(const char* port, GPS_PWay** way, int (*cb)(int ct, GPS_PWay*)); + int32 GPS_A101_Get(const char* port); + int32 GPS_A100_Send(const char* port, GPS_PWay* way, int32 n, int (*cb)(GPS_PWay*)); + + int32 GPS_A200_Get(const char* port, GPS_PWay** way); + int32 GPS_A201_Get(const char* port, GPS_PWay** way); + int32 GPS_A200_Send(const char* port, GPS_PWay* way, int32 n); + int32 GPS_A201_Send(const char* port, GPS_PWay* way, int32 n); + + int32 GPS_A300_Get(const char* port, GPS_PTrack** trk, pcb_fn cb); + int32 GPS_A301_Get(const char* port, GPS_PTrack** trk, pcb_fn cb, int protoid); + int32 GPS_A300_Send(const char* port, GPS_PTrack* trk, int32 n); + int32 GPS_A301_Send(const char* port, GPS_PTrack* trk, int32 n, int protoid, + gpsdevh* fd); + + int32 GPS_D300_Get(GPS_PTrack* trk, int32 entries, gpsdevh* h); + void GPS_D300b_Get(GPS_PTrack* trk, UC* data); + void GPS_D301b_Get(GPS_PTrack* trk, UC* data); + void GPS_D302b_Get(GPS_PTrack* trk, UC* data); + void GPS_D303b_Get(GPS_PTrack* trk, UC* data); /*D304*/ + void GPS_D310_Get(GPS_PTrack* trk, UC* s); + void GPS_D311_Get(GPS_PTrack* trk, UC* s); + void GPS_D300_Send(UC* data, GPS_PTrack trk, int32* len); + void GPS_D301_Send(UC* data, GPS_PTrack trk, int32* len, int type); + void GPS_D303_Send(UC* data, GPS_PTrack trk, int32* len, int protoid); + void GPS_D310_Send(UC* data, GPS_PTrack trk, int32* len); + void GPS_D311_Send(UC* data, GPS_PTrack trk, int32* len); + + int32 GPS_A400_Get(const char* port, GPS_PWay** way); + int32 GPS_A400_Send(const char* port, GPS_PWay* way, int32 n); + + int32 GPS_A500_Get(const char* port, GPS_PAlmanac** alm); + int32 GPS_A500_Send(const char* port, GPS_PAlmanac* alm, int32 n); + + time_t GPS_A600_Get(const char* port); + time_t GPS_D600_Get(GPS_PPacket packet); + int32 GPS_A600_Send(const char* port, time_t Time); + void GPS_D600_Send(GPS_PPacket* packet, time_t Time); + + int32 GPS_A700_Get(const char* port, double* lat, double* lon); + int32 GPS_A700_Send(const char* port, double lat, double lon); + void GPS_D700_Get(GPS_PPacket packet, double* lat, double* lon); + void GPS_D700_Send(GPS_PPacket* packet, double lat, double lon); + + int32 GPS_A800_On(const char* port, gpsdevh** fd); + int32 GPS_A800_Off(const char* port, gpsdevh** fd); + int32 GPS_A800_Get(gpsdevh** fd, GPS_PPvt_Data* packet); + void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data* pvt); + + int32 GPS_A906_Get(const char* port, GPS_PLap** lap, pcb_fn cb); + void GPS_D1011b_Get(GPS_PLap* Lap,UC* data); /*D906 D1001 D1015*/ + + int32 GPS_A1006_Get(const char* port, GPS_PCourse** crs, pcb_fn cb); + int32 GPS_A1006_Send(const char* port, GPS_PCourse* crs, int32 n_crs, + gpsdevh* fd); + void GPS_D1006_Get(GPS_PCourse* crs, UC* p); + void GPS_D1006_Send(UC* data, GPS_PCourse crs, int32* len); + + int32 GPS_A1007_Get(const char* port, GPS_PCourse_Lap** clp, pcb_fn cb); + int32 GPS_A1007_Send(const char* port, GPS_PCourse_Lap* clp, int32 n_clp, + gpsdevh* fd); + void GPS_D1007_Get(GPS_PCourse_Lap* clp, UC* p); + void GPS_D1007_Send(UC* data, GPS_PCourse_Lap clp, int32* len); + + int32 GPS_A1008_Get(const char* port, GPS_PCourse_Point** cpt, pcb_fn cb); + int32 GPS_A1008_Send(const char* port, GPS_PCourse_Point* cpt, int32 n_cpt, + gpsdevh* fd); + void GPS_D1012_Get(GPS_PCourse_Point* cpt, UC* p); + void GPS_D1012_Send(UC* data, GPS_PCourse_Point cpt, int32* len); + + int32 GPS_A1009_Get(const char* port, GPS_PCourse_Limits limits); + void GPS_D1013_Get(GPS_PCourse_Limits limits, UC* p); + + /* Unhandled documented protocols, as of: + Garmin Device Interface Specification, May 19, 2006, Drawing Number: 001-00063-00 Rev. C + A650 FlightBook Transfer Protocol + A1000 Run Transfer Protocol + Capability A1000: D1009 + D1000 D1010 + A1002 Workout Transfer Protocol + Capability A1002: D1008 + D1002 + Capability A1003: D1003 + A1004 Fitness User Profile Transfer Protocol + Capability A1004: D1004 + A1005 Workout Limits Transfer Protocol + Capability A1005: D1005 + */ + /* Unimplemted and Undocumented, as listed from the following device/sw: + GF305 3.70 + + Capability A601: D601 + Capability A801: D801 + + Capability A902: + Capability A903: + Capability A907: D907 D908 D909 D910 + Capability A918: D918 + Capability A1013: D1014 + */ + + const char* Get_Pkt_Type(US p, US d0, const char** xinfo); + + void GPS_Prepare_Track_For_Device(GPS_PTrack** trk, int32* n); #endif diff --git a/gpsbabel/jeeps/gpscom.c b/gpsbabel/jeeps/gpscom.c index 1e9f0eaeb..629be721e 100644 --- a/gpsbabel/jeeps/gpscom.c +++ b/gpsbabel/jeeps/gpscom.c @@ -2,23 +2,23 @@ ** @source JEEPS command functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @modified Copyright (C) 2005, 2006 Robert Lipe ** @modified Copyright (C) 2007 Achim Schumacher ** @modified Copyright (C) 2010 Martin Buck ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -36,43 +36,47 @@ ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Off(const char *port) +int32 GPS_Command_Off(const char* port) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - - GPS_Util_Little(); - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Turn_Off_Pwr); - - /* robertl - LINK_ID isn't set yet. Hardcode it to Garmin spec value */ - GPS_Make_Packet(&tra, 10, /* LINK_ID[gps_link_type].Pid_Command_Data, */ - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Device_Chars_Ready(fd)) - { - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - GPS_User("Power off command acknowledged"); + static UC data[2]; + gpsdevh* fd; + GPS_PPacket tra; + GPS_PPacket rec; + + GPS_Util_Little(); + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Turn_Off_Pwr); + + /* robertl - LINK_ID isn't set yet. Hardcode it to Garmin spec value */ + GPS_Make_Packet(&tra, 10, /* LINK_ID[gps_link_type].Pid_Command_Data, */ + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Device_Chars_Ready(fd)) { + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; } + GPS_User("Power off command acknowledged"); + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -86,35 +90,34 @@ int32 GPS_Command_Off(const char *port) ** @return [int32] number of waypoint entries ************************************************************************/ -int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way, pcb_fn cb) +int32 GPS_Command_Get_Waypoint(const char* port, GPS_PWay** way, pcb_fn cb) { - int32 ret=0; - - /* - * It's a bit tacky to do this up front without ticking the - * progress meter, but this come in pretty quickly... - */ - if (gps_category_transfer) { - ret = GPS_A101_Get(port); - if (!ret) { -fatal("blah"); - return PROTOCOL_ERROR; - } - + int32 ret=0; + + /* + * It's a bit tacky to do this up front without ticking the + * progress meter, but this come in pretty quickly... + */ + if (gps_category_transfer) { + ret = GPS_A101_Get(port); + if (!ret) { + fatal("blah"); + return PROTOCOL_ERROR; } - switch(gps_waypt_transfer) - { - case pA100: - ret = GPS_A100_Get(port,way, cb); - break; - default: - GPS_Error("Get_Waypoint: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } + } + + switch (gps_waypt_transfer) { + case pA100: + ret = GPS_A100_Get(port,way, cb); + break; + default: + GPS_Error("Get_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } - return ret; -} + return ret; +} @@ -129,22 +132,21 @@ fatal("blah"); ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **)) +int32 GPS_Command_Send_Waypoint(const char* port, GPS_PWay* way, int32 n, int (*cb)(struct GPS_SWay**)) { - int32 ret=0; - - switch(gps_waypt_transfer) - { - case pA100: - ret = GPS_A100_Send(port, way, n, cb); - break; - default: - GPS_Error("Send_Waypoint: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + switch (gps_waypt_transfer) { + case pA100: + ret = GPS_A100_Send(port, way, n, cb); + break; + default: + GPS_Error("Send_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} /* @func GPS_Command_Get_Route ************************************** @@ -157,25 +159,24 @@ int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (* ** @return [int32] number of waypoint entries ************************************************************************/ -int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way) +int32 GPS_Command_Get_Route(const char* port, GPS_PWay** way) { - int32 ret=0; - - switch(gps_route_transfer) - { - case pA200: - ret = GPS_A200_Get(port,way); - break; - case pA201: - ret = GPS_A201_Get(port,way); - break; - default: - GPS_Error("Get_Route: Unknown route protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + switch (gps_route_transfer) { + case pA200: + ret = GPS_A200_Get(port,way); + break; + case pA201: + ret = GPS_A201_Get(port,way); + break; + default: + GPS_Error("Get_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -190,26 +191,25 @@ int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n) +int32 GPS_Command_Send_Route(const char* port, GPS_PWay* way, int32 n) { - int32 ret=0; - - - switch(gps_route_transfer) - { - case pA200: - ret = GPS_A200_Send(port, way, n); - break; - case pA201: - ret = GPS_A201_Send(port, way, n); - break; - default: - GPS_Error("Send_Route: Unknown route protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + + switch (gps_route_transfer) { + case pA200: + ret = GPS_A200_Send(port, way, n); + break; + case pA201: + ret = GPS_A201_Send(port, way, n); + break; + default: + GPS_Error("Send_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} /* @func GPS_Command_Get_Track *************************************** @@ -222,29 +222,29 @@ int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n) ** @return [int32] number of track entries ************************************************************************/ -int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, pcb_fn cb) +int32 GPS_Command_Get_Track(const char* port, GPS_PTrack** trk, pcb_fn cb) { - int32 ret=0; - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_trk_transfer) - { - case pA300: - ret = GPS_A300_Get(port,trk,cb); - break; - case pA301: - case pA302: - ret = GPS_A301_Get(port,trk,cb,301); - break; - default: - GPS_Error("Get_Track: Unknown track protocol %d\n", gps_trk_transfer); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + if (gps_trk_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_trk_transfer) { + case pA300: + ret = GPS_A300_Get(port,trk,cb); + break; + case pA301: + case pA302: + ret = GPS_A301_Get(port,trk,cb,301); + break; + default: + GPS_Error("Get_Track: Unknown track protocol %d\n", gps_trk_transfer); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -259,34 +259,34 @@ int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, pcb_fn cb) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n, int eraset) +int32 GPS_Command_Send_Track(const char* port, GPS_PTrack* trk, int32 n, int eraset) { - int32 ret=0; - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_trk_transfer) - { - case pA300: - ret = GPS_A300_Send(port, trk, n); - break; - case pA301: - ret = GPS_A301_Send(port, trk, n, 301, NULL); - break; - case pA302: - /* Units with A302 don't support track upload, so we convert the - * track to a course on the fly and send that instead - */ - ret = GPS_Command_Send_Track_As_Course(port, trk, n, NULL, 0, eraset); - break; - default: - GPS_Error("Send_Track: Unknown track protocol %d.", gps_trk_transfer); - break; - } - - return ret; -} + int32 ret=0; + + if (gps_trk_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_trk_transfer) { + case pA300: + ret = GPS_A300_Send(port, trk, n); + break; + case pA301: + ret = GPS_A301_Send(port, trk, n, 301, NULL); + break; + case pA302: + /* Units with A302 don't support track upload, so we convert the + * track to a course on the fly and send that instead + */ + ret = GPS_Command_Send_Track_As_Course(port, trk, n, NULL, 0, eraset); + break; + default: + GPS_Error("Send_Track: Unknown track protocol %d.", gps_trk_transfer); + break; + } + + return ret; +} /* @func GPS_Command_Get_Proximity ************************************** @@ -299,25 +299,25 @@ int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n, int era ** @return [int32] number of waypoint entries ************************************************************************/ -int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way) +int32 GPS_Command_Get_Proximity(const char* port, GPS_PWay** way) { - int32 ret=0; - - if(gps_prx_waypt_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_prx_waypt_transfer) - { - case pA400: - ret = GPS_A400_Get(port,way); - break; - default: - GPS_Error("Get_Proximity: Unknown proximity protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + if (gps_prx_waypt_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_prx_waypt_transfer) { + case pA400: + ret = GPS_A400_Get(port,way); + break; + default: + GPS_Error("Get_Proximity: Unknown proximity protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -332,27 +332,27 @@ int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n) +int32 GPS_Command_Send_Proximity(const char* port, GPS_PWay* way, int32 n) { - int32 ret=0; + int32 ret=0; - if(gps_prx_waypt_transfer == -1) - return GPS_UNSUPPORTED; + if (gps_prx_waypt_transfer == -1) { + return GPS_UNSUPPORTED; + } - switch(gps_prx_waypt_transfer) - { - case pA400: - ret = GPS_A400_Send(port, way, n); - break; - default: - GPS_Error("Send_Proximity: Unknown proximity protocol"); - break; - } + switch (gps_prx_waypt_transfer) { + case pA400: + ret = GPS_A400_Send(port, way, n); + break; + default: + GPS_Error("Send_Proximity: Unknown proximity protocol"); + break; + } - return ret; -} + return ret; +} @@ -366,25 +366,25 @@ int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n) ** @return [int32] number of almanac entries ************************************************************************/ -int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm) +int32 GPS_Command_Get_Almanac(const char* port, GPS_PAlmanac** alm) { - int32 ret=0; - - if(gps_almanac_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_almanac_transfer) - { - case pA500: - ret = GPS_A500_Get(port,alm); - break; - default: - GPS_Error("Get_Almanac: Unknown almanac protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + if (gps_almanac_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_almanac_transfer) { + case pA500: + ret = GPS_A500_Get(port,alm); + break; + default: + GPS_Error("Get_Almanac: Unknown almanac protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -399,25 +399,25 @@ int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n) +int32 GPS_Command_Send_Almanac(const char* port, GPS_PAlmanac* alm, int32 n) { - int32 ret=0; - - if(gps_almanac_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_almanac_transfer) - { - case pA500: - ret = GPS_A500_Send(port, alm, n); - break; - default: - GPS_Error("Send_Almanac: Unknown almanac protocol"); - break; - } - - return ret; -} + int32 ret=0; + + if (gps_almanac_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_almanac_transfer) { + case pA500: + ret = GPS_A500_Send(port, alm, n); + break; + default: + GPS_Error("Send_Almanac: Unknown almanac protocol"); + break; + } + + return ret; +} @@ -430,28 +430,27 @@ int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n) ** @return [time_t] unix-style time ************************************************************************/ -time_t GPS_Command_Get_Time(const char *port) +time_t GPS_Command_Get_Time(const char* port) { - time_t ret=0; - - switch(gps_date_time_transfer) - { - case pA600: - ret = GPS_A600_Get(port); - break; - /* - * If the unit doesn't support it (i.e. a C320 in charging mode), + time_t ret=0; + + switch (gps_date_time_transfer) { + case pA600: + ret = GPS_A600_Get(port); + break; + /* + * If the unit doesn't support it (i.e. a C320 in charging mode), * but don't treat as error; return as zero. */ - case -1: - return 0; - default: - GPS_Error("Get_Time: Unknown date/time protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + case -1: + return 0; + default: + GPS_Error("Get_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -465,22 +464,21 @@ time_t GPS_Command_Get_Time(const char *port) ** @return [int32] true if OK ************************************************************************/ -int32 GPS_Command_Send_Time(const char *port, time_t Time) +int32 GPS_Command_Send_Time(const char* port, time_t Time) { - time_t ret=0; - - switch(gps_date_time_transfer) - { - case pA600: - ret = GPS_A600_Send(port, Time); - break; - default: - GPS_Error("Send_Time: Unknown date/time protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + time_t ret=0; + + switch (gps_date_time_transfer) { + case pA600: + ret = GPS_A600_Send(port, Time); + break; + default: + GPS_Error("Send_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -496,29 +494,28 @@ int32 GPS_Command_Send_Time(const char *port, time_t Time) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon) +int32 GPS_Command_Get_Position(const char* port, double* lat, double* lon) { - int32 ret=0; - - switch(gps_position_transfer) - { - case pA700: - ret = GPS_A700_Get(port,lat,lon); - break; - /* - * If the unit doesn't support it (i.e. a C320 in charging mode), - * zero lat/lon, but don't treat as error. + int32 ret=0; + + switch (gps_position_transfer) { + case pA700: + ret = GPS_A700_Get(port,lat,lon); + break; + /* + * If the unit doesn't support it (i.e. a C320 in charging mode), + * zero lat/lon, but don't treat as error. */ - case -1: - *lat = *lon = 0.0; - break; - default: - GPS_Error("Get_Position: Unknown position protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + case -1: + *lat = *lon = 0.0; + break; + default: + GPS_Error("Get_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -533,23 +530,22 @@ int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Send_Position(const char *port, double lat, double lon) +int32 GPS_Command_Send_Position(const char* port, double lat, double lon) { - int32 ret=0; - - switch(gps_position_transfer) - { - case pA700: - ret = GPS_A700_Send(port, lat, lon); - break; - default: - GPS_Error("Send_Position: Unknown position protocol"); - return PROTOCOL_ERROR; - } + int32 ret=0; + + switch (gps_position_transfer) { + case pA700: + ret = GPS_A700_Send(port, lat, lon); + break; + default: + GPS_Error("Send_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} - return ret; -} - /* @func GPS_Command_Pvt_On ******************************************** ** @@ -561,28 +557,28 @@ int32 GPS_Command_Send_Position(const char *port, double lat, double lon) ** @return [int32] success if supported and GPS starts sending ************************************************************************/ -int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd) +int32 GPS_Command_Pvt_On(const char* port, gpsdevh** fd) { - int32 ret=0; + int32 ret=0; - if(gps_pvt_transfer == -1) - return GPS_UNSUPPORTED; + if (gps_pvt_transfer == -1) { + return GPS_UNSUPPORTED; + } - switch(gps_pvt_transfer) - { - case pA800: - ret = GPS_A800_On(port,fd); - break; - default: - GPS_Error("Pvt_On: Unknown position protocol"); - return PROTOCOL_ERROR; - } + switch (gps_pvt_transfer) { + case pA800: + ret = GPS_A800_On(port,fd); + break; + default: + GPS_Error("Pvt_On: Unknown position protocol"); + return PROTOCOL_ERROR; + } - return ret; -} + return ret; +} @@ -596,26 +592,26 @@ int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd) +int32 GPS_Command_Pvt_Off(const char* port, gpsdevh** fd) { - int32 ret=0; - - - if(gps_pvt_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_pvt_transfer) - { - case pA800: - ret = GPS_A800_Off(port,fd); - break; - default: - GPS_Error("Pvt_Off: Unknown position protocol"); - return PROTOCOL_ERROR; - } + int32 ret=0; - return ret; -} + + if (gps_pvt_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_pvt_transfer) { + case pA800: + ret = GPS_A800_Off(port,fd); + break; + default: + GPS_Error("Pvt_Off: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -629,27 +625,27 @@ int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt) +int32 GPS_Command_Pvt_Get(gpsdevh** fd, GPS_PPvt_Data* pvt) { - int32 ret=0; + int32 ret=0; - if(gps_pvt_transfer == -1) - return GPS_UNSUPPORTED; + if (gps_pvt_transfer == -1) { + return GPS_UNSUPPORTED; + } - (*pvt)->fix = 0; + (*pvt)->fix = 0; - switch(gps_pvt_transfer) - { - case pA800: - ret = GPS_A800_Get(fd,pvt); - break; - default: - GPS_Error("Pvt_Get: Unknown position protocol"); - return PROTOCOL_ERROR; - } + switch (gps_pvt_transfer) { + case pA800: + ret = GPS_A800_Get(fd,pvt); + break; + default: + GPS_Error("Pvt_Get: Unknown position protocol"); + return PROTOCOL_ERROR; + } - return ret; -} + return ret; +} /* @func GPS_Command_Get_Lap *************************************** ** @@ -661,25 +657,25 @@ int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt) ** @return [int32] number of lap entries ************************************************************************/ -int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, pcb_fn cb) +int32 GPS_Command_Get_Lap(const char* port, GPS_PLap** lap, pcb_fn cb) { - int32 ret=0; - - if(gps_lap_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_lap_transfer) - { - case pA906: - ret = GPS_A906_Get(port,lap, cb); - break; - default: - GPS_Error("Get_Lap: Unknown lap protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + if (gps_lap_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_lap_transfer) { + case pA906: + ret = GPS_A906_Get(port,lap, cb); + break; + default: + GPS_Error("Get_Lap: Unknown lap protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} /* @func GPS_Command_Get_Course *************************************** ** @@ -699,67 +695,64 @@ int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, pcb_fn cb) ** @return [int32] number of course entries ************************************************************************/ int32 GPS_Command_Get_Course - (const char *port, - GPS_PCourse **crs, - GPS_PCourse_Lap **clp, - GPS_PTrack **trk, - GPS_PCourse_Point **cpt, - int32 *n_clp, - int32 *n_trk, - int32 *n_cpt, - pcb_fn cb) +(const char* port, + GPS_PCourse** crs, + GPS_PCourse_Lap** clp, + GPS_PTrack** trk, + GPS_PCourse_Point** cpt, + int32* n_clp, + int32* n_trk, + int32* n_cpt, + pcb_fn cb) { - int32 ret=0; - - if(gps_course_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_course_transfer) - { - case pA1006: - ret = GPS_A1006_Get(port,crs,cb); - break; - default: - GPS_Error("Get_Course: Unknown course protocol"); - return PROTOCOL_ERROR; - } - - switch(gps_course_lap_transfer) - { - case pA1007: - *n_clp = GPS_A1007_Get(port,clp, 0); - break; - default: - GPS_Error("Get_Course: Unknown course lap protocol"); - return PROTOCOL_ERROR; - } - - switch(gps_course_trk_transfer) - { - case pA1012: - GPS_Error("Get_Course: Not implemented track protocol %d\n", - gps_trk_transfer); - break; - case pA302: - *n_trk = GPS_A301_Get(port,trk,cb,302); - break; - default: - GPS_Error("Get_Course: Unknown course track protocol %d\n", - gps_trk_transfer); - return PROTOCOL_ERROR; - } - - switch(gps_course_point_transfer) - { - case pA1008: - *n_cpt = GPS_A1008_Get(port,cpt, 0); - break; - default: - GPS_Error("Get_Course: Unknown course point protocol"); - return PROTOCOL_ERROR; - } - - return ret; + int32 ret=0; + + if (gps_course_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_course_transfer) { + case pA1006: + ret = GPS_A1006_Get(port,crs,cb); + break; + default: + GPS_Error("Get_Course: Unknown course protocol"); + return PROTOCOL_ERROR; + } + + switch (gps_course_lap_transfer) { + case pA1007: + *n_clp = GPS_A1007_Get(port,clp, 0); + break; + default: + GPS_Error("Get_Course: Unknown course lap protocol"); + return PROTOCOL_ERROR; + } + + switch (gps_course_trk_transfer) { + case pA1012: + GPS_Error("Get_Course: Not implemented track protocol %d\n", + gps_trk_transfer); + break; + case pA302: + *n_trk = GPS_A301_Get(port,trk,cb,302); + break; + default: + GPS_Error("Get_Course: Unknown course track protocol %d\n", + gps_trk_transfer); + return PROTOCOL_ERROR; + } + + switch (gps_course_point_transfer) { + case pA1008: + *n_cpt = GPS_A1008_Get(port,cpt, 0); + break; + default: + GPS_Error("Get_Course: Unknown course point protocol"); + return PROTOCOL_ERROR; + } + + return ret; } @@ -782,113 +775,110 @@ int32 GPS_Command_Get_Course ** @return [int32] Success ************************************************************************/ int32 GPS_Command_Send_Course - (const char *port, - GPS_PCourse *crs, - GPS_PCourse_Lap *clp, - GPS_PTrack *trk, - GPS_PCourse_Point *cpt, - int32 n_crs, - int32 n_clp, - int32 n_trk, - int32 n_cpt) +(const char* port, + GPS_PCourse* crs, + GPS_PCourse_Lap* clp, + GPS_PTrack* trk, + GPS_PCourse_Point* cpt, + int32 n_crs, + int32 n_clp, + int32 n_trk, + int32 n_cpt) { - gpsdevh *fd; - GPS_OCourse_Limits limits; - int32 ret; - int32 ret_crs=0; - int32 ret_clp=0; - int32 ret_trk=0; - int32 ret_cpt=0; - - if(gps_course_transfer == -1 || gps_course_limits_transfer == -1) - return GPS_UNSUPPORTED; - - /* Check course limits to make sure we're not exceeding the device's - * capacity. - */ - switch(gps_course_limits_transfer) - { - case pA1009: - ret = GPS_A1009_Get(port,&limits); - break; - default: - GPS_Error("Send_Course: Unknown course limitsprotocol"); - return PROTOCOL_ERROR; - } - - if (n_crs > limits.max_courses - || n_clp > limits.max_course_laps - || n_trk > limits.max_course_trk_pnt - || n_cpt > limits.max_course_pnt) - { - GPS_Error("Course upload would exceed device capacity:"); - GPS_Error("# of courses: %d, max: %d", n_crs, limits.max_courses); - GPS_Error("# of laps: %d, max: %d", n_clp, limits.max_course_laps); - GPS_Error("# of track points: %d, max: %d", n_trk, limits.max_course_trk_pnt); - GPS_Error("# of course points: %d, max: %d", n_cpt, limits.max_course_pnt); - return GPS_UNSUPPORTED; - } - - /* Initialize device communication: - * In contrast to other transfer protocols, this has to be handled here; - * shutting off communication in between the different parts - * could lead to data corruption on the device because all the courses - * and their associated lap and track data have to be sent in one - * transaction. - */ - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - switch(gps_course_transfer) - { - case pA1006: - ret_crs = GPS_A1006_Send(port,crs,n_crs,fd); - break; - default: - GPS_Error("Send_Course: Unknown course protocol"); - return PROTOCOL_ERROR; - } - - switch(gps_course_lap_transfer) - { - case pA1007: - ret_clp = GPS_A1007_Send(port,clp,n_clp,fd); - break; - default: - GPS_Error("Send_Course: Unknown course lap protocol"); - return PROTOCOL_ERROR; - } - - switch(gps_course_trk_transfer) - { - case pA1012: - GPS_Error("Send_Course: Not implemented track protocol %d\n", - gps_trk_transfer); - break; - case pA302: - ret_trk = GPS_A301_Send(port,trk,n_trk,302,fd); - break; - default: - GPS_Error("Send_Course: Unknown course track protocol %d\n", - gps_trk_transfer); - return PROTOCOL_ERROR; - } - - switch(gps_course_point_transfer) - { - case pA1008: - ret_cpt = GPS_A1008_Send(port,cpt,n_cpt,fd); - break; - default: - GPS_Error("Send_Course: Unknown course point protocol"); - return PROTOCOL_ERROR; - } - - if(!GPS_Device_Off(fd)) - return gps_errno; - - - return ret_crs * ret_clp * ret_trk * ret_cpt; + gpsdevh* fd; + GPS_OCourse_Limits limits; + int32 ret; + int32 ret_crs=0; + int32 ret_clp=0; + int32 ret_trk=0; + int32 ret_cpt=0; + + if (gps_course_transfer == -1 || gps_course_limits_transfer == -1) { + return GPS_UNSUPPORTED; + } + + /* Check course limits to make sure we're not exceeding the device's + * capacity. + */ + switch (gps_course_limits_transfer) { + case pA1009: + ret = GPS_A1009_Get(port,&limits); + break; + default: + GPS_Error("Send_Course: Unknown course limitsprotocol"); + return PROTOCOL_ERROR; + } + + if (n_crs > limits.max_courses + || n_clp > limits.max_course_laps + || n_trk > limits.max_course_trk_pnt + || n_cpt > limits.max_course_pnt) { + GPS_Error("Course upload would exceed device capacity:"); + GPS_Error("# of courses: %d, max: %d", n_crs, limits.max_courses); + GPS_Error("# of laps: %d, max: %d", n_clp, limits.max_course_laps); + GPS_Error("# of track points: %d, max: %d", n_trk, limits.max_course_trk_pnt); + GPS_Error("# of course points: %d, max: %d", n_cpt, limits.max_course_pnt); + return GPS_UNSUPPORTED; + } + + /* Initialize device communication: + * In contrast to other transfer protocols, this has to be handled here; + * shutting off communication in between the different parts + * could lead to data corruption on the device because all the courses + * and their associated lap and track data have to be sent in one + * transaction. + */ + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + switch (gps_course_transfer) { + case pA1006: + ret_crs = GPS_A1006_Send(port,crs,n_crs,fd); + break; + default: + GPS_Error("Send_Course: Unknown course protocol"); + return PROTOCOL_ERROR; + } + + switch (gps_course_lap_transfer) { + case pA1007: + ret_clp = GPS_A1007_Send(port,clp,n_clp,fd); + break; + default: + GPS_Error("Send_Course: Unknown course lap protocol"); + return PROTOCOL_ERROR; + } + + switch (gps_course_trk_transfer) { + case pA1012: + GPS_Error("Send_Course: Not implemented track protocol %d\n", + gps_trk_transfer); + break; + case pA302: + ret_trk = GPS_A301_Send(port,trk,n_trk,302,fd); + break; + default: + GPS_Error("Send_Course: Unknown course track protocol %d\n", + gps_trk_transfer); + return PROTOCOL_ERROR; + } + + switch (gps_course_point_transfer) { + case pA1008: + ret_cpt = GPS_A1008_Send(port,cpt,n_cpt,fd); + break; + default: + GPS_Error("Send_Course: Unknown course point protocol"); + return PROTOCOL_ERROR; + } + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + + return ret_crs * ret_clp * ret_trk * ret_cpt; } @@ -901,19 +891,20 @@ int32 GPS_Command_Send_Course ** ** @return [uint32] course index ************************************************************************/ -static uint32 Unique_Course_Index(GPS_PCourse *crs, int n_crs) +static uint32 Unique_Course_Index(GPS_PCourse* crs, int n_crs) { - uint32 idx; - int i; - - for (idx=0; ; idx++) - { - for (i=0; iindex==idx) - break; /* Already have this index */ - if (i>=n_crs) - return idx; /* Found unused index */ + uint32 idx; + int i; + + for (idx=0; ; idx++) { + for (i=0; iindex==idx) { + break; /* Already have this index */ + } + if (i>=n_crs) { + return idx; /* Found unused index */ } + } } @@ -927,19 +918,20 @@ static uint32 Unique_Course_Index(GPS_PCourse *crs, int n_crs) ** ** @return [uint32] track index ************************************************************************/ -static uint32 Unique_Track_Index(GPS_PCourse *crs, int n_crs) +static uint32 Unique_Track_Index(GPS_PCourse* crs, int n_crs) { - uint32 idx; - int i; - - for (idx=0; ; idx++) - { - for (i=0; itrack_index==idx) - break; /* Already have this index */ - if (i>=n_crs) - return idx; /* Found unused index */ + uint32 idx; + int i; + + for (idx=0; ; idx++) { + for (i=0; itrack_index==idx) { + break; /* Already have this index */ + } + if (i>=n_crs) { + return idx; /* Found unused index */ } + } } @@ -959,76 +951,75 @@ static uint32 Unique_Track_Index(GPS_PCourse *crs, int n_crs) ** @return [void] ************************************************************************/ static void -Calculate_Course_Lap_Data(GPS_PCourse_Lap clp, GPS_PTrack *ctk, +Calculate_Course_Lap_Data(GPS_PCourse_Lap clp, GPS_PTrack* ctk, int ctk_start, int ctk_end) { - int i; - double heartrate_sum = 0, cadence_sum = 0; - int heartrate_sum_time = 0, cadence_sum_time = 0; - double time_synth_speed = 10.0 * 1000 / 3600; /* speed in m/s */ - - if (ctk_start && ctk_end && !ctk[ctk_start]->Time) - ctk[ctk_start]->Time = GPS_Time_Now(); - else - time_synth_speed = 0; - - clp->total_dist = 0; - clp->avg_heart_rate = 0; - clp->max_heart_rate = 0; - clp->intensity = 0; - clp->avg_cadence = 0xff; - for (i=ctk_start; i <= ctk_end; i++) - { - if (ctk[i]->heartrate && ctk[i]->heartrate > clp->max_heart_rate) - clp->max_heart_rate = ctk[i]->heartrate; - if (i < ctk_end) - { - double dist = 0; - int seg_time; - - if (!ctk[i]->no_latlon && !ctk[i+1]->no_latlon) - dist = gcgeodist(ctk[i]->lat, ctk[i]->lon, - ctk[i+1]->lat, ctk[i+1]->lon); - clp->total_dist += dist; - - if (time_synth_speed) - ctk[i+1]->Time = ctk[i]->Time + (dist / time_synth_speed + 0.5); - - seg_time = ctk[i+1]->Time - ctk[i]->Time; - - if (ctk[i]->heartrate) - { - heartrate_sum += ctk[i]->heartrate * seg_time; - heartrate_sum_time += seg_time; - } - if (ctk[i]->cadence) - { - cadence_sum += ctk[i]->cadence * seg_time; - cadence_sum_time += seg_time; - } - } + int i; + double heartrate_sum = 0, cadence_sum = 0; + int heartrate_sum_time = 0, cadence_sum_time = 0; + double time_synth_speed = 10.0 * 1000 / 3600; /* speed in m/s */ + + if (ctk_start && ctk_end && !ctk[ctk_start]->Time) { + ctk[ctk_start]->Time = GPS_Time_Now(); + } else { + time_synth_speed = 0; + } + + clp->total_dist = 0; + clp->avg_heart_rate = 0; + clp->max_heart_rate = 0; + clp->intensity = 0; + clp->avg_cadence = 0xff; + for (i=ctk_start; i <= ctk_end; i++) { + if (ctk[i]->heartrate && ctk[i]->heartrate > clp->max_heart_rate) { + clp->max_heart_rate = ctk[i]->heartrate; } - - clp->total_time = 0; - clp->begin_lat = 0x7fffffff; - clp->begin_lon = 0x7fffffff; - clp->end_lat = 0x7fffffff; - clp->end_lon = 0x7fffffff; - if (ctk_start && ctk_end) - { - clp->total_time = (ctk[ctk_end]->Time - ctk[ctk_start]->Time) * 100; - if (!ctk[ctk_start]->no_latlon && !ctk[ctk_end]->no_latlon) - { - clp->begin_lat = ctk[ctk_start]->lat; - clp->begin_lon = ctk[ctk_start]->lon; - clp->end_lat = ctk[ctk_end]->lat; - clp->end_lon = ctk[ctk_end]->lon; - } + if (i < ctk_end) { + double dist = 0; + int seg_time; + + if (!ctk[i]->no_latlon && !ctk[i+1]->no_latlon) + dist = gcgeodist(ctk[i]->lat, ctk[i]->lon, + ctk[i+1]->lat, ctk[i+1]->lon); + clp->total_dist += dist; + + if (time_synth_speed) { + ctk[i+1]->Time = ctk[i]->Time + (dist / time_synth_speed + 0.5); + } + + seg_time = ctk[i+1]->Time - ctk[i]->Time; + + if (ctk[i]->heartrate) { + heartrate_sum += ctk[i]->heartrate * seg_time; + heartrate_sum_time += seg_time; + } + if (ctk[i]->cadence) { + cadence_sum += ctk[i]->cadence * seg_time; + cadence_sum_time += seg_time; + } + } + } + + clp->total_time = 0; + clp->begin_lat = 0x7fffffff; + clp->begin_lon = 0x7fffffff; + clp->end_lat = 0x7fffffff; + clp->end_lon = 0x7fffffff; + if (ctk_start && ctk_end) { + clp->total_time = (ctk[ctk_end]->Time - ctk[ctk_start]->Time) * 100; + if (!ctk[ctk_start]->no_latlon && !ctk[ctk_end]->no_latlon) { + clp->begin_lat = ctk[ctk_start]->lat; + clp->begin_lon = ctk[ctk_start]->lon; + clp->end_lat = ctk[ctk_end]->lat; + clp->end_lon = ctk[ctk_end]->lon; } - if (heartrate_sum_time) - clp->avg_heart_rate = heartrate_sum / heartrate_sum_time; - if (cadence_sum_time) - clp->avg_cadence = cadence_sum / cadence_sum_time; + } + if (heartrate_sum_time) { + clp->avg_heart_rate = heartrate_sum / heartrate_sum_time; + } + if (cadence_sum_time) { + clp->avg_cadence = cadence_sum / cadence_sum_time; + } } @@ -1049,105 +1040,102 @@ Calculate_Course_Lap_Data(GPS_PCourse_Lap clp, GPS_PTrack *ctk, ** @return [void] ************************************************************************/ static void -Course_Garbage_Collect(GPS_PCourse *crs, int *n_crs, - GPS_PCourse_Lap *clp, int *n_clp, - GPS_PTrack *ctk, int *n_ctk, - GPS_PCourse_Point *cpt, int *n_cpt) +Course_Garbage_Collect(GPS_PCourse* crs, int* n_crs, + GPS_PCourse_Lap* clp, int* n_clp, + GPS_PTrack* ctk, int* n_ctk, + GPS_PCourse_Point* cpt, int* n_cpt) { - int i, j; - - /* Remove courses with duplicate names, keeping newest. - * This is actually pretty important: Sending two courses with the same - * name to the device will result in internal data corruption on the - * device (e.g. "inventing" laps with weird course IDs that nobody ever - * transferred to it, that change with every upload of unrelated data - * and that can't be deleted except with a master reset by holding the - * Mode button during power on). - */ + int i, j; + + /* Remove courses with duplicate names, keeping newest. + * This is actually pretty important: Sending two courses with the same + * name to the device will result in internal data corruption on the + * device (e.g. "inventing" laps with weird course IDs that nobody ever + * transferred to it, that change with every upload of unrelated data + * and that can't be deleted except with a master reset by holding the + * Mode button during power on). + */ restart_courses: - for (i=*n_crs-1; i>0; i--) - { - for (j=i-1; j>=0; j--) - { - if (!strcmp(crs[i]->course_name, crs[j]->course_name)) - { - /* Remove course */ - GPS_Course_Del(&crs[j]); - memmove(&crs[j], &crs[j+1], (*n_crs-j-1)*sizeof(*crs)); - (*n_crs)--; - goto restart_courses; - } - } + for (i=*n_crs-1; i>0; i--) { + for (j=i-1; j>=0; j--) { + if (!strcmp(crs[i]->course_name, crs[j]->course_name)) { + /* Remove course */ + GPS_Course_Del(&crs[j]); + memmove(&crs[j], &crs[j+1], (*n_crs-j-1)*sizeof(*crs)); + (*n_crs)--; + goto restart_courses; + } } + } /* Remove unreferenced laps */ restart_laps: - for (i=0; i<*n_clp; i++) - { - for (j=0; j<*n_crs; j++) - if (crs[j]->index == clp[i]->course_index) - break; - if (j>=*n_crs) - { - /* Remove lap */ - GPS_Course_Lap_Del(&clp[i]); - memmove(&clp[i], &clp[i+1], (*n_clp-i-1)*sizeof(*clp)); - (*n_clp)--; - goto restart_laps; - } + for (i=0; i<*n_clp; i++) { + for (j=0; j<*n_crs; j++) + if (crs[j]->index == clp[i]->course_index) { + break; + } + if (j>=*n_crs) { + /* Remove lap */ + GPS_Course_Lap_Del(&clp[i]); + memmove(&clp[i], &clp[i+1], (*n_clp-i-1)*sizeof(*clp)); + (*n_clp)--; + goto restart_laps; } + } - /* Remove unreferenced tracks */ + /* Remove unreferenced tracks */ restart_tracks: - for (i=0; i<*n_ctk; i++) - { - uint32 trk_idx; - - if (!ctk[i]->ishdr) - continue; - trk_idx = strtoul(ctk[i]->trk_ident, NULL, 0); - for (j=0; j<*n_crs; j++) - if (crs[j]->track_index == trk_idx) - break; - if (j>=*n_crs) - { - /* Remove track */ - for (j=i; j<*n_ctk; j++) - { - if (j!=i && ctk[j]->ishdr) - break; - GPS_Track_Del(&ctk[j]); - } - memmove(&ctk[i], &ctk[j], (*n_ctk-j)*sizeof(*ctk)); - *(n_ctk) -= j-i; - goto restart_tracks; + for (i=0; i<*n_ctk; i++) { + uint32 trk_idx; + + if (!ctk[i]->ishdr) { + continue; + } + trk_idx = strtoul(ctk[i]->trk_ident, NULL, 0); + for (j=0; j<*n_crs; j++) + if (crs[j]->track_index == trk_idx) { + break; + } + if (j>=*n_crs) { + /* Remove track */ + for (j=i; j<*n_ctk; j++) { + if (j!=i && ctk[j]->ishdr) { + break; } + GPS_Track_Del(&ctk[j]); + } + memmove(&ctk[i], &ctk[j], (*n_ctk-j)*sizeof(*ctk)); + *(n_ctk) -= j-i; + goto restart_tracks; } + } - /* Remove unreferenced/duplicate course points */ + /* Remove unreferenced/duplicate course points */ restart_course_points: - for (i=0; i<*n_cpt; i++) - { - /* Check for unreferenced point */ - for (j=0; j<*n_crs; j++) - if (crs[j]->index == cpt[i]->course_index) - break; - if (j<*n_crs) - { - /* Check for duplicate point */ - for (j=0; jcourse_index == cpt[j]->course_index && - cpt[i]->track_point_time == cpt[j]->track_point_time) - break; - if (j>=i) - continue; /* Referenced & unique */ + for (i=0; i<*n_cpt; i++) { + /* Check for unreferenced point */ + for (j=0; j<*n_crs; j++) + if (crs[j]->index == cpt[i]->course_index) { + break; + } + if (j<*n_crs) { + /* Check for duplicate point */ + for (j=0; jcourse_index == cpt[j]->course_index && + cpt[i]->track_point_time == cpt[j]->track_point_time) { + break; } - /* Remove course point */ - GPS_Course_Point_Del(&cpt[i]); - memmove(&cpt[i], &cpt[i+1], (*n_cpt-i-1)*sizeof(*cpt)); - (*n_cpt)--; - goto restart_course_points; + if (j>=i) { + continue; /* Referenced & unique */ + } } + /* Remove course point */ + GPS_Course_Point_Del(&cpt[i]); + memmove(&cpt[i], &cpt[i+1], (*n_cpt-i-1)*sizeof(*cpt)); + (*n_cpt)--; + goto restart_course_points; + } } @@ -1167,168 +1155,177 @@ restart_course_points: ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Send_Track_As_Course(const char *port, GPS_PTrack *trk, int32 n_trk, - GPS_PWay *wpt, int32 n_wpt, int eraset) +int32 GPS_Command_Send_Track_As_Course(const char* port, GPS_PTrack* trk, int32 n_trk, + GPS_PWay* wpt, int32 n_wpt, int eraset) { - GPS_PCourse *crs = NULL; - GPS_PCourse_Lap *clp = NULL; - GPS_PTrack *ctk = NULL; - GPS_PCourse_Point *cpt = NULL; - int n_crs, n_clp=0, n_ctk=0, n_cpt=0; - int i, j, trk_end, new_crs, first_new_ctk; - int32 ret; - - /* Read existing courses from device */ - if (eraset) - n_crs = 0; - else { - n_crs = GPS_Command_Get_Course(port, &crs, &clp, &ctk, &cpt, &n_clp, &n_ctk, &n_cpt, NULL); - if (n_crs < 0) return n_crs; + GPS_PCourse* crs = NULL; + GPS_PCourse_Lap* clp = NULL; + GPS_PTrack* ctk = NULL; + GPS_PCourse_Point* cpt = NULL; + int n_crs, n_clp=0, n_ctk=0, n_cpt=0; + int i, j, trk_end, new_crs, first_new_ctk; + int32 ret; + + /* Read existing courses from device */ + if (eraset) { + n_crs = 0; + } else { + n_crs = GPS_Command_Get_Course(port, &crs, &clp, &ctk, &cpt, &n_clp, &n_ctk, &n_cpt, NULL); + if (n_crs < 0) { + return n_crs; } + } - /* Create new course+lap+track points for each track */ - new_crs = n_crs; - for (i=0;iishdr) - continue; - - /* Find end of track */ - for (trk_end=i; trk_endishdr) - break; - if (trk_end==i) - continue; /* Skip empty track */ - - /* Create & append course */ - crs = xrealloc(crs, (n_crs+1) * sizeof(GPS_PCourse)); - crs[n_crs] = GPS_Course_New(); - if (!crs[n_crs]) return MEMORY_ERROR; - - crs[n_crs]->index = Unique_Course_Index(crs, n_crs); - strncpy(crs[n_crs]->course_name, trk[i]->trk_ident, - sizeof(crs[n_crs]->course_name)-1); - - crs[n_crs]->track_index = Unique_Track_Index(crs, n_crs); - - /* Create & append new lap */ - clp = xrealloc(clp, (n_clp+1) * sizeof(GPS_PCourse_Lap)); - clp[n_clp] = GPS_Course_Lap_New(); - if (!clp[n_clp]) return MEMORY_ERROR; - - clp[n_clp]->course_index = crs[n_crs]->index; /* Index of associated course */ - clp[n_clp]->lap_index = 0; /* Lap index, unique per course */ - Calculate_Course_Lap_Data(clp[n_clp], trk, i+1, trk_end); - n_crs++; - n_clp++; + /* Create new course+lap+track points for each track */ + new_crs = n_crs; + for (i=0; iishdr) { + continue; } - /* Append new track points */ - ctk = xrealloc(ctk, (n_ctk+n_trk) * sizeof(GPS_PTrack)); - first_new_ctk = n_ctk; - for (i=0;iishdr && (i>=n_trk || trk[i+1]->ishdr)) - continue; - - ctk[n_ctk] = GPS_Track_New(); - if (!ctk[n_ctk]) return MEMORY_ERROR; - *ctk[n_ctk] = *trk[i]; - - if (trk[i]->ishdr) - { - /* Index of new track, must match the track index in associated course */ - memset(ctk[n_ctk]->trk_ident, 0, sizeof(ctk[n_ctk]->trk_ident)); - sprintf(ctk[n_ctk]->trk_ident, "%d", crs[new_crs]->track_index); - new_crs++; - } - n_ctk++; + /* Find end of track */ + for (trk_end=i; trk_endishdr) { + break; + } + if (trk_end==i) { + continue; /* Skip empty track */ } - /* Convert waypoints to course points by searching closest track point & - * append - */ - cpt = xrealloc(cpt, (n_cpt+n_wpt) * sizeof(GPS_PCourse_Point)); - for (i=0; iishdr) { - trk_idx = strtoul(ctk[j]->trk_ident, NULL, 0); - continue; - } - - dist = gcgeodist(wpt[i]->lat, wpt[i]->lon, ctk[j]->lat, ctk[j]->lon); - if (dist < min_dist) { - min_dist = dist; - min_dist_idx = j; - min_dist_trk_idx = trk_idx; - } - } - - cpt[i+n_cpt] = GPS_Course_Point_New(); - strncpy(cpt[i+n_cpt]->name, wpt[i]->cmnt, - sizeof(cpt[i+n_cpt]->name) - 1); - for (j=0; jtrack_index == min_dist_trk_idx) - { - cpt[i+n_cpt]->course_index = crs[j]->index; - break; - } - cpt[i+n_cpt]->track_point_time = ctk[min_dist_idx]->Time; - cpt[i+n_cpt]->point_type = 0; + /* Create & append course */ + crs = (struct GPS_SCourse**)xrealloc(crs, (n_crs+1) * sizeof(GPS_PCourse)); + crs[n_crs] = GPS_Course_New(); + if (!crs[n_crs]) { + return MEMORY_ERROR; } - n_cpt += n_wpt; - /* Remove course data that's no longer needed */ - Course_Garbage_Collect(crs, &n_crs, clp, &n_clp, ctk, &n_ctk, cpt, &n_cpt); + crs[n_crs]->index = Unique_Course_Index(crs, n_crs); + strncpy(crs[n_crs]->course_name, trk[i]->trk_ident, + sizeof(crs[n_crs]->course_name)-1); - /* Finally send courses including new ones to device */ - ret = GPS_Command_Send_Course(port, crs, clp, ctk, cpt, - n_crs, n_clp, n_ctk, n_cpt); + crs[n_crs]->track_index = Unique_Track_Index(crs, n_crs); - for (i=0;icourse_index = crs[n_crs]->index; /* Index of associated course */ + clp[n_clp]->lap_index = 0; /* Lap index, unique per course */ + Calculate_Course_Lap_Data(clp[n_clp], trk, i+1, trk_end); + n_crs++; + n_clp++; + } + + /* Append new track points */ + ctk = (struct GPS_STrack**) xrealloc(ctk, (n_ctk+n_trk) * sizeof(GPS_PTrack)); + first_new_ctk = n_ctk; + for (i=0; iishdr && (i>=n_trk || trk[i+1]->ishdr)) { + continue; } - free(clp); - for (i=0;iishdr) { + /* Index of new track, must match the track index in associated course */ + memset(ctk[n_ctk]->trk_ident, 0, sizeof(ctk[n_ctk]->trk_ident)); + sprintf(ctk[n_ctk]->trk_ident, "%d", crs[new_crs]->track_index); + new_crs++; + } + n_ctk++; + } + + /* Convert waypoints to course points by searching closest track point & + * append + */ + cpt = (struct GPS_SCourse_Point**) xrealloc(cpt, (n_cpt+n_wpt) * sizeof(GPS_PCourse_Point)); + for (i=0; iishdr) { + trk_idx = strtoul(ctk[j]->trk_ident, NULL, 0); + continue; + } + + dist = gcgeodist(wpt[i]->lat, wpt[i]->lon, ctk[j]->lat, ctk[j]->lon); + if (dist < min_dist) { + min_dist = dist; + min_dist_idx = j; + min_dist_trk_idx = trk_idx; + } } - free(cpt); - return ret; + cpt[i+n_cpt] = GPS_Course_Point_New(); + strncpy(cpt[i+n_cpt]->name, wpt[i]->cmnt, + sizeof(cpt[i+n_cpt]->name) - 1); + for (j=0; jtrack_index == min_dist_trk_idx) { + cpt[i+n_cpt]->course_index = crs[j]->index; + break; + } + cpt[i+n_cpt]->track_point_time = ctk[min_dist_idx]->Time; + cpt[i+n_cpt]->point_type = 0; + } + n_cpt += n_wpt; + + /* Remove course data that's no longer needed */ + Course_Garbage_Collect(crs, &n_crs, clp, &n_clp, ctk, &n_ctk, cpt, &n_cpt); + + /* Finally send courses including new ones to device */ + ret = GPS_Command_Send_Course(port, crs, clp, ctk, cpt, + n_crs, n_clp, n_ctk, n_cpt); + + for (i=0; i -int32 GPS_Command_Off(const char *port); + int32 GPS_Command_Off(const char* port); -time_t GPS_Command_Get_Time(const char *port); -int32 GPS_Command_Send_Time(const char *port, time_t Time); + time_t GPS_Command_Get_Time(const char* port); + int32 GPS_Command_Send_Time(const char* port, time_t Time); -int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon); -int32 GPS_Command_Send_Position(const char *port, double lat, double lon); + int32 GPS_Command_Get_Position(const char* port, double* lat, double* lon); + int32 GPS_Command_Send_Position(const char* port, double lat, double lon); -int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd); -int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd); -int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt); + int32 GPS_Command_Pvt_On(const char* port, gpsdevh** fd); + int32 GPS_Command_Pvt_Off(const char* port, gpsdevh** fd); + int32 GPS_Command_Pvt_Get(gpsdevh** fd, GPS_PPvt_Data* pvt); -int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm); -int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n); + int32 GPS_Command_Get_Almanac(const char* port, GPS_PAlmanac** alm); + int32 GPS_Command_Send_Almanac(const char* port, GPS_PAlmanac* alm, int32 n); -int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n, int eraset); + int32 GPS_Command_Get_Track(const char* port, GPS_PTrack** trk, int (*cb)(int, struct GPS_SWay**)); + int32 GPS_Command_Send_Track(const char* port, GPS_PTrack* trk, int32 n, int eraset); -int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way,int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **)); + int32 GPS_Command_Get_Waypoint(const char* port, GPS_PWay** way,int (*cb)(int, struct GPS_SWay**)); + int32 GPS_Command_Send_Waypoint(const char* port, GPS_PWay* way, int32 n, int (*cb)(struct GPS_SWay**)); -int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way); -int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n); + int32 GPS_Command_Get_Proximity(const char* port, GPS_PWay** way); + int32 GPS_Command_Send_Proximity(const char* port, GPS_PWay* way, int32 n); -int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way); -int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n); + int32 GPS_Command_Get_Route(const char* port, GPS_PWay** way); + int32 GPS_Command_Send_Route(const char* port, GPS_PWay* way, int32 n); -int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Get_Lap(const char* port, GPS_PLap** lap, int (*cb)(int, struct GPS_SWay**)); -int32 GPS_Command_Send_Course(const char *port, GPS_PCourse *crs, GPS_PCourse_Lap *clp, - GPS_PTrack *trk, GPS_PCourse_Point *cpt, - int32 n_crs, int32 n_clp, int32 n_trk, int32 n_cpt); -int32 GPS_Command_Send_Track_As_Course(const char *port, GPS_PTrack *trk, int32 n_trk, - GPS_PWay *wpt, int32 n_wpt, int eraset); + int32 GPS_Command_Send_Course(const char* port, GPS_PCourse* crs, GPS_PCourse_Lap* clp, + GPS_PTrack* trk, GPS_PCourse_Point* cpt, + int32 n_crs, int32 n_clp, int32 n_trk, int32 n_cpt); + int32 GPS_Command_Send_Track_As_Course(const char* port, GPS_PTrack* trk, int32 n_trk, + GPS_PWay* wpt, int32 n_wpt, int eraset); -int32 GPS_Command_Get_Workout(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Get_Fitness_User_Profile(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Get_Workout_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Get_Course_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Get_Workout(const char* port, void** lap, int (*cb)(int, struct GPS_SWay**)); + int32 GPS_Command_Get_Fitness_User_Profile(const char* port, void** lap, int (*cb)(int, struct GPS_SWay**)); + int32 GPS_Command_Get_Workout_Limits(const char* port, void** lap, int (*cb)(int, struct GPS_SWay**)); + int32 GPS_Command_Get_Course_Limits(const char* port, void** lap, int (*cb)(int, struct GPS_SWay**)); #endif #ifdef __cplusplus diff --git a/gpsbabel/jeeps/gpsdatum.h b/gpsbabel/jeeps/gpsdatum.h index b0e1bf696..faa54fe86 100644 --- a/gpsbabel/jeeps/gpsdatum.h +++ b/gpsbabel/jeeps/gpsdatum.h @@ -8,15 +8,13 @@ extern "C" -typedef struct GPS_SEllipse -{ - char *name; + typedef struct GPS_SEllipse { + char* name; double a; double invf; -} GPS_OEllipse, *GPS_PEllipse; + } GPS_OEllipse, *GPS_PEllipse; -GPS_OEllipse GPS_Ellipse[]= -{ + GPS_OEllipse GPS_Ellipse[]= { { "Airy 1830", 6377563.396, 299.3249646 }, { "Airy 1830 Modified", 6377340.189, 299.3249646 }, { "Australian National", 6378160.000, 298.25 }, @@ -45,159 +43,155 @@ GPS_OEllipse GPS_Ellipse[]= { "WGS72", 6378135.000, 298.26 }, { "WGS84", 6378137.000, 298.257223563 }, { "Clarke 1880 (Benoit)", 6378300.789, 293.466 }, -}; + }; -typedef struct GPS_SDatum -{ - char *name; + typedef struct GPS_SDatum { + char* name; int ellipse; double dx; double dy; double dz; -} GPS_ODatum, *GPS_PDatum; - -GPS_ODatum GPS_Datum[]= -{ -/* 000 */ { "Adindan", 6, -166, -15, 204 }, -/* 001 */ { "AFG", 18, -43, -163, 45 }, -/* 002 */ { "Ain-El-Abd", 17, -150, -251, -2 }, -/* 003 */ { "Alaska-NAD27", 5, -5, 135, 172 }, -/* 004 */ { "Alaska-Canada", 6, -9, 151, 185 }, -/* 005 */ { "Anna-1-Astro", 2, -491, -22, 435 }, -/* 006 */ { "ARC 1950 Mean", 6, -143, -90, -294 }, -/* 007 */ { "ARC 1960 Mean", 6, -160, -8, -300 }, -/* 008 */ { "Asc Island 58", 17, -207, 107, 52 }, -/* 009 */ { "Astro B4", 17, 114, -116, -333 }, -/* 010 */ { "Astro Beacon E", 17, 145, 75, -272 }, -/* 011 */ { "Astro pos 71/4", 17, -320, 550, -494 }, -/* 012 */ { "Astro stn 52", 17, 124, -234, -25 }, -/* 013 */ { "Australia Geo 1984", 2, -134, -48, 149 }, -/* 014 */ { "Bahamas NAD27", 6, -4, 154, 178 }, -/* 015 */ { "Bellevue IGN", 17, -127, -769, 472 }, -/* 016 */ { "Bermuda 1957", 6, -73, 213, 296 }, -/* 017 */ { "Bukit Rimpah", 4, -384, 664, -48 }, -/* 018 */ { "Camp_Area_Astro", 17, -104, -129, 239 }, -/* 019 */ { "Campo_Inchauspe", 17, -148, 136, 90 }, -/* 020 */ { "Canada_Mean(NAD27)", 5, -10, 158, 187 }, -/* 021 */ { "Canal_Zone_(NAD27)", 5, 0, 125, 201 }, -/* 022 */ { "Canton_Island_1966", 17, 298, -304, -375 }, -/* 023 */ { "Cape", 6, -136, -108, -292 }, -/* 024 */ { "Cape_Canaveral_mean", 5, -2, 150, 181 }, -/* 025 */ { "Carribean NAD27", 5, -7, 152, 178 }, -/* 026 */ { "Carthage", 6, -263, 6, 431 }, -/* 027 */ { "Cent America NAD27", 5 , 0, 125, 194 }, -/* 028 */ { "Chatham 1971", 17, 175, -38, 113 }, -/* 029 */ { "Chua Astro", 17, -134, 229, -29 }, -/* 030 */ { "Corrego Alegre", 17, -206, 172, -6 }, -/* 031 */ { "Cuba NAD27", 5, -9, 152, 178 }, -/* 032 */ { "Cyprus", 17, -104, -101, -140 }, -/* 033 */ { "Djakarta(Batavia)", 4, -377, 681, -50 }, -/* 034 */ { "DOS 1968", 17, 230, -199, -752 }, -/* 035 */ { "Easter lsland 1967", 17, 211, 147, 111 }, -/* 036 */ { "Egypt", 17, -130, -117, -151 }, -/* 037 */ { "European 1950", 17, -87, -96, -120 }, -/* 038 */ { "European 1950 mean", 17, -87, -98, -121 }, -/* 039 */ { "European 1979 mean", 17, -86, -98, -119 }, -/* 040 */ { "Finnish Nautical", 17, -78, -231, -97 }, -/* 041 */ { "Gandajika Base", 17, -133, -321, 50 }, -/* 042 */ { "Geodetic Datum 49", 17, 84, -22, 209 }, -/* 043 */ { "Ghana", 26, 0, 0, 0 }, -/* 044 */ { "Greenland NAD27", 5, 11, 114, 195 }, -/* 045 */ { "Guam 1963", 5, -100, -248, 259 }, -/* 046 */ { "Gunung Segara", 4, -403, 684, 41 }, -/* 047 */ { "Gunung Serindung 1962", 26, 0, 0, 0 }, -/* 048 */ { "GUX1 Astro", 17, 252, -209, -751 }, -/* 049 */ { "Herat North", 17, -333, -222, 114 }, -/* 050 */ { "Hjorsey 1955", 17, -73, 46, 86 }, -/* 051 */ { "Hong Kong 1963", 17, -156, -271, -189 }, -/* 052 */ { "Hu-Tzu-Shan", 17, -634, -549, -201 }, -/* 053 */ { "Indian", 9, 289, 734, 257 }, -/* 054 */ { "Iran", 17, -117, -132, -164 }, -/* 055 */ { "Ireland 1965", 1, 506, -122, 611 }, -/* 056 */ { "ISTS 073 Astro 69", 17, 208, -435, -229 }, -/* 057 */ { "Johnston Island 61", 17, 191, -77, -204 }, -/* 058 */ { "Kandawala", 7, -97, 787, 86 }, -/* 059 */ { "Kerguelen Island", 17, 145, -187, 103 }, -/* 060 */ { "Kertau 48", 11, -11, 851, 5 }, -/* 061 */ { "L.C. 5 Astro", 5, 42, 124, 147 }, -/* 062 */ { "La Reunion", 17, 94, -948, -1262 }, -/* 063 */ { "Liberia 1964", 6, -90, 40, 88 }, -/* 064 */ { "Luzon", 5, -133, -77, -51 }, -/* 065 */ { "Mahe 1971", 6, 41, -220, -134 }, -/* 066 */ { "Marco Astro", 17, -289, -124, 60 }, -/* 067 */ { "Masirah Is. Nahrwan", 6, -247, -148, 369 }, -/* 068 */ { "Massawa", 4, 639, 405, 60 }, -/* 069 */ { "Merchich", 6, 31, 146, 47 }, -/* 070 */ { "Mexico NAD27", 5, -12, 130, 190 }, -/* 071 */ { "Midway Astro 61", 17, 912, -58, 1227 }, -/* 072 */ { "Mindanao", 5, -133, -79, -72 }, -/* 073 */ { "Minna", 6, -92, -93, 122 }, -/* 074 */ { "Montjong Lowe", 26, 0, 0, 0 }, -/* 075 */ { "Nahrwan", 6, -231, -196, 482 }, -/* 076 */ { "Naparima BWI", 17, -2, 374, 172 }, -/* 077 */ { "North America 83", 21, 0, 0, 0 }, -/* 078 */ { "N. America 1927 mean", 5, -8, 160, 176 }, -/* 079 */ { "Observatorio 1966", 17, -425, -169, 81 }, -/* 080 */ { "Old Egyptian", 14, -130, 110, -13 }, -/* 081 */ { "Old Hawaiian_mean", 5, 89, -279, -183 }, -/* 082 */ { "Old Hawaiian Kauai", 5, 45, -290, -172 }, -/* 083 */ { "Old Hawaiian Maui", 5, 65, -290, -190 }, -/* 084 */ { "Old Hawaiian Oahu", 5, 56, -284, -181 }, -/* 085 */ { "Oman", 6, -346, -1, 224 }, -/* 086 */ { "OSGB36", 0, 375, -111, 431 }, -/* 087 */ { "Pico De Las Nieves", 17, -307, -92, 127 }, -/* 088 */ { "Pitcairn Astro 67", 17, 185, 165, 42 }, -/* 089 */ { "S. Am. 1956 mean(P)", 17, -288, 175, -376 }, -/* 090 */ { "S. Chilean 1963 (P)", 17, 16, 196, 93 }, -/* 091 */ { "Puerto Rico", 5, 11, 72, -101 }, -/* 092 */ { "Pulkovo 1942", 18, 28, -130, -95 }, -/* 093 */ { "Qornoq", 17, 164, 138, -189 }, -/* 094 */ { "Quatar National", 17, -128, -283, 22 }, -/* 095 */ { "Rome 1940", 17, -225, -65, 9 }, -/* 096 */ { "S-42(Pulkovo1942)", 18, 28, -121, -77 }, -/* 097 */ { "S.E.Asia_(Indian)", 7, 173, 750, 264 }, -/* 098 */ { "SAD-69/Brazil", 22, -60, -2, -41 }, -/* 099 */ { "Santa Braz", 17, -203, 141, 53 }, -/* 100 */ { "Santo (DOS)", 17, 170, 42, 84 }, -/* 101 */ { "Sapper Hill 43", 17, -355, 16, 74 }, -/* 102 */ { "Schwarzeck", 3, 616, 97, -251 }, -/* 103 */ { "Sicily", 17, -97, -88, -135 }, -/* 104 */ { "Sierra Leone 1960", 26, 0, 0, 0 }, -/* 105 */ { "S. Am. 1969 mean", 22, -57, 1, -41 }, -/* 106 */ { "South Asia", 13, 7, -10, -26 }, -/* 107 */ { "Southeast Base", 17, -499, -249, 314 }, -/* 108 */ { "Southwest Base", 17, -104, 167, -38 }, -/* 109 */ { "Tananarive Obs 25", 17, -189, -242, -91 }, -/* 110 */ { "Thai/Viet (Indian)", 7, 214, 836, 303 }, -/* 111 */ { "Timbalai 1948", 7, -689, 691, -45 }, -/* 112 */ { "Tokyo mean", 4, -128, 481, 664 }, -/* 113 */ { "Tristan Astro 1968", 17, -632, 438, -609 }, -/* 114 */ { "United Arab Emirates", 6, -249, -156, 381 }, -/* 115 */ { "Viti Levu 1916", 6, 51, 391, -36 }, -/* 116 */ { "Wake Eniwetok 60", 15, 101, 52, -39 }, -/* 117 */ { "WGS 72", 25, 0, 0, 5 }, -/* 118 */ { "WGS 84", 26, 0, 0, 0 }, -/* 119 */ { "Yacare", 17, -155, 171, 37 }, -/* 120 */ { "Zanderij", 17, -265, 120, -358 }, -/* 121 */ { "Sweden", 4, 424.3, -80.5, 613.1 }, -/* 122 */ { "GDA 94", 21, 0, 0, 0 }, -/* 123 */ { "CH-1903", 4, 674, 15, 405 }, -/* 124 */ { "Palestine 1923", 27, -235, -85, 264 }, -/* 125 */ { "ITM (Israeli New)", 21, -48, 55, -52 }, - { NULL, 0, 0, 0, 0 } -}; - - -typedef struct GPS_SDatum_Alias -{ - char *alias; + } GPS_ODatum, *GPS_PDatum; + + GPS_ODatum GPS_Datum[]= { + /* 000 */ { "Adindan", 6, -166, -15, 204 }, + /* 001 */ { "AFG", 18, -43, -163, 45 }, + /* 002 */ { "Ain-El-Abd", 17, -150, -251, -2 }, + /* 003 */ { "Alaska-NAD27", 5, -5, 135, 172 }, + /* 004 */ { "Alaska-Canada", 6, -9, 151, 185 }, + /* 005 */ { "Anna-1-Astro", 2, -491, -22, 435 }, + /* 006 */ { "ARC 1950 Mean", 6, -143, -90, -294 }, + /* 007 */ { "ARC 1960 Mean", 6, -160, -8, -300 }, + /* 008 */ { "Asc Island 58", 17, -207, 107, 52 }, + /* 009 */ { "Astro B4", 17, 114, -116, -333 }, + /* 010 */ { "Astro Beacon E", 17, 145, 75, -272 }, + /* 011 */ { "Astro pos 71/4", 17, -320, 550, -494 }, + /* 012 */ { "Astro stn 52", 17, 124, -234, -25 }, + /* 013 */ { "Australia Geo 1984", 2, -134, -48, 149 }, + /* 014 */ { "Bahamas NAD27", 6, -4, 154, 178 }, + /* 015 */ { "Bellevue IGN", 17, -127, -769, 472 }, + /* 016 */ { "Bermuda 1957", 6, -73, 213, 296 }, + /* 017 */ { "Bukit Rimpah", 4, -384, 664, -48 }, + /* 018 */ { "Camp_Area_Astro", 17, -104, -129, 239 }, + /* 019 */ { "Campo_Inchauspe", 17, -148, 136, 90 }, + /* 020 */ { "Canada_Mean(NAD27)", 5, -10, 158, 187 }, + /* 021 */ { "Canal_Zone_(NAD27)", 5, 0, 125, 201 }, + /* 022 */ { "Canton_Island_1966", 17, 298, -304, -375 }, + /* 023 */ { "Cape", 6, -136, -108, -292 }, + /* 024 */ { "Cape_Canaveral_mean", 5, -2, 150, 181 }, + /* 025 */ { "Carribean NAD27", 5, -7, 152, 178 }, + /* 026 */ { "Carthage", 6, -263, 6, 431 }, + /* 027 */ { "Cent America NAD27", 5 , 0, 125, 194 }, + /* 028 */ { "Chatham 1971", 17, 175, -38, 113 }, + /* 029 */ { "Chua Astro", 17, -134, 229, -29 }, + /* 030 */ { "Corrego Alegre", 17, -206, 172, -6 }, + /* 031 */ { "Cuba NAD27", 5, -9, 152, 178 }, + /* 032 */ { "Cyprus", 17, -104, -101, -140 }, + /* 033 */ { "Djakarta(Batavia)", 4, -377, 681, -50 }, + /* 034 */ { "DOS 1968", 17, 230, -199, -752 }, + /* 035 */ { "Easter lsland 1967", 17, 211, 147, 111 }, + /* 036 */ { "Egypt", 17, -130, -117, -151 }, + /* 037 */ { "European 1950", 17, -87, -96, -120 }, + /* 038 */ { "European 1950 mean", 17, -87, -98, -121 }, + /* 039 */ { "European 1979 mean", 17, -86, -98, -119 }, + /* 040 */ { "Finnish Nautical", 17, -78, -231, -97 }, + /* 041 */ { "Gandajika Base", 17, -133, -321, 50 }, + /* 042 */ { "Geodetic Datum 49", 17, 84, -22, 209 }, + /* 043 */ { "Ghana", 26, 0, 0, 0 }, + /* 044 */ { "Greenland NAD27", 5, 11, 114, 195 }, + /* 045 */ { "Guam 1963", 5, -100, -248, 259 }, + /* 046 */ { "Gunung Segara", 4, -403, 684, 41 }, + /* 047 */ { "Gunung Serindung 1962", 26, 0, 0, 0 }, + /* 048 */ { "GUX1 Astro", 17, 252, -209, -751 }, + /* 049 */ { "Herat North", 17, -333, -222, 114 }, + /* 050 */ { "Hjorsey 1955", 17, -73, 46, 86 }, + /* 051 */ { "Hong Kong 1963", 17, -156, -271, -189 }, + /* 052 */ { "Hu-Tzu-Shan", 17, -634, -549, -201 }, + /* 053 */ { "Indian", 9, 289, 734, 257 }, + /* 054 */ { "Iran", 17, -117, -132, -164 }, + /* 055 */ { "Ireland 1965", 1, 506, -122, 611 }, + /* 056 */ { "ISTS 073 Astro 69", 17, 208, -435, -229 }, + /* 057 */ { "Johnston Island 61", 17, 191, -77, -204 }, + /* 058 */ { "Kandawala", 7, -97, 787, 86 }, + /* 059 */ { "Kerguelen Island", 17, 145, -187, 103 }, + /* 060 */ { "Kertau 48", 11, -11, 851, 5 }, + /* 061 */ { "L.C. 5 Astro", 5, 42, 124, 147 }, + /* 062 */ { "La Reunion", 17, 94, -948, -1262 }, + /* 063 */ { "Liberia 1964", 6, -90, 40, 88 }, + /* 064 */ { "Luzon", 5, -133, -77, -51 }, + /* 065 */ { "Mahe 1971", 6, 41, -220, -134 }, + /* 066 */ { "Marco Astro", 17, -289, -124, 60 }, + /* 067 */ { "Masirah Is. Nahrwan", 6, -247, -148, 369 }, + /* 068 */ { "Massawa", 4, 639, 405, 60 }, + /* 069 */ { "Merchich", 6, 31, 146, 47 }, + /* 070 */ { "Mexico NAD27", 5, -12, 130, 190 }, + /* 071 */ { "Midway Astro 61", 17, 912, -58, 1227 }, + /* 072 */ { "Mindanao", 5, -133, -79, -72 }, + /* 073 */ { "Minna", 6, -92, -93, 122 }, + /* 074 */ { "Montjong Lowe", 26, 0, 0, 0 }, + /* 075 */ { "Nahrwan", 6, -231, -196, 482 }, + /* 076 */ { "Naparima BWI", 17, -2, 374, 172 }, + /* 077 */ { "North America 83", 21, 0, 0, 0 }, + /* 078 */ { "N. America 1927 mean", 5, -8, 160, 176 }, + /* 079 */ { "Observatorio 1966", 17, -425, -169, 81 }, + /* 080 */ { "Old Egyptian", 14, -130, 110, -13 }, + /* 081 */ { "Old Hawaiian_mean", 5, 89, -279, -183 }, + /* 082 */ { "Old Hawaiian Kauai", 5, 45, -290, -172 }, + /* 083 */ { "Old Hawaiian Maui", 5, 65, -290, -190 }, + /* 084 */ { "Old Hawaiian Oahu", 5, 56, -284, -181 }, + /* 085 */ { "Oman", 6, -346, -1, 224 }, + /* 086 */ { "OSGB36", 0, 375, -111, 431 }, + /* 087 */ { "Pico De Las Nieves", 17, -307, -92, 127 }, + /* 088 */ { "Pitcairn Astro 67", 17, 185, 165, 42 }, + /* 089 */ { "S. Am. 1956 mean(P)", 17, -288, 175, -376 }, + /* 090 */ { "S. Chilean 1963 (P)", 17, 16, 196, 93 }, + /* 091 */ { "Puerto Rico", 5, 11, 72, -101 }, + /* 092 */ { "Pulkovo 1942", 18, 28, -130, -95 }, + /* 093 */ { "Qornoq", 17, 164, 138, -189 }, + /* 094 */ { "Quatar National", 17, -128, -283, 22 }, + /* 095 */ { "Rome 1940", 17, -225, -65, 9 }, + /* 096 */ { "S-42(Pulkovo1942)", 18, 28, -121, -77 }, + /* 097 */ { "S.E.Asia_(Indian)", 7, 173, 750, 264 }, + /* 098 */ { "SAD-69/Brazil", 22, -60, -2, -41 }, + /* 099 */ { "Santa Braz", 17, -203, 141, 53 }, + /* 100 */ { "Santo (DOS)", 17, 170, 42, 84 }, + /* 101 */ { "Sapper Hill 43", 17, -355, 16, 74 }, + /* 102 */ { "Schwarzeck", 3, 616, 97, -251 }, + /* 103 */ { "Sicily", 17, -97, -88, -135 }, + /* 104 */ { "Sierra Leone 1960", 26, 0, 0, 0 }, + /* 105 */ { "S. Am. 1969 mean", 22, -57, 1, -41 }, + /* 106 */ { "South Asia", 13, 7, -10, -26 }, + /* 107 */ { "Southeast Base", 17, -499, -249, 314 }, + /* 108 */ { "Southwest Base", 17, -104, 167, -38 }, + /* 109 */ { "Tananarive Obs 25", 17, -189, -242, -91 }, + /* 110 */ { "Thai/Viet (Indian)", 7, 214, 836, 303 }, + /* 111 */ { "Timbalai 1948", 7, -689, 691, -45 }, + /* 112 */ { "Tokyo mean", 4, -128, 481, 664 }, + /* 113 */ { "Tristan Astro 1968", 17, -632, 438, -609 }, + /* 114 */ { "United Arab Emirates", 6, -249, -156, 381 }, + /* 115 */ { "Viti Levu 1916", 6, 51, 391, -36 }, + /* 116 */ { "Wake Eniwetok 60", 15, 101, 52, -39 }, + /* 117 */ { "WGS 72", 25, 0, 0, 5 }, + /* 118 */ { "WGS 84", 26, 0, 0, 0 }, + /* 119 */ { "Yacare", 17, -155, 171, 37 }, + /* 120 */ { "Zanderij", 17, -265, 120, -358 }, + /* 121 */ { "Sweden", 4, 424.3, -80.5, 613.1 }, + /* 122 */ { "GDA 94", 21, 0, 0, 0 }, + /* 123 */ { "CH-1903", 4, 674, 15, 405 }, + /* 124 */ { "Palestine 1923", 27, -235, -85, 264 }, + /* 125 */ { "ITM (Israeli New)", 21, -48, 55, -52 }, + { NULL, 0, 0, 0, 0 } + }; + + + typedef struct GPS_SDatum_Alias { + char* alias; const int datum; -} GPS_ODatum_Alias, *GPS_PDatum_Alias; + } GPS_ODatum_Alias, *GPS_PDatum_Alias; -GPS_ODatum_Alias GPS_DatumAlias[] = -{ + GPS_ODatum_Alias GPS_DatumAlias[] = { { "Australian GDA94", 122 }, { "Australian Geocentric 1994 (GDA94)", 122}, /* Observed in Ozi */ { "GDA94", 122 }, @@ -229,12 +223,11 @@ GPS_ODatum_Alias GPS_DatumAlias[] = { "Israeli", 124 }, { "D_Israel_new", 125 }, { NULL, -1 } -}; + }; -/* UK Ordnance Survey Nation Grid Map Codes */ -static char *UKNG[]= -{ + /* UK Ordnance Survey Nation Grid Map Codes */ + static char* UKNG[]= { "SV","SW","SX","SY","SZ","TV","TW","SQ","SR","SS","ST","SU","TQ","TR", "SL","SM","SN","SO","SP","TL","TM","SF","SG","SH","SJ","SK","TF","TG", "SA","SB","SC","SD","SE","TA","TB","NV","NW","NX","NY","NZ","OV","OW", @@ -242,7 +235,7 @@ static char *UKNG[]= "NF","NG","NH","NJ","NK","OF","OG","NA","NB","NC","ND","NE","OA","OB", "HV","HW","HX","HY","HZ","JV","JW","HQ","HR","HS","HT","HU","JQ","JR", "HL","HM","HN","HO","HP","JL","JM","" -}; + }; diff --git a/gpsbabel/jeeps/gpsdevice.c b/gpsbabel/jeeps/gpsdevice.c index 8c68bd6a0..eef48edd7 100644 --- a/gpsbabel/jeeps/gpsdevice.c +++ b/gpsbabel/jeeps/gpsdevice.c @@ -25,64 +25,64 @@ extern gps_device_ops gps_serial_ops; extern gps_device_ops gps_usb_ops; -gps_device_ops *ops = NULL; +gps_device_ops* ops = NULL; -int32 GPS_Device_On(const char *port, gpsdevh **fd) +int32 GPS_Device_On(const char* port, gpsdevh** fd) { - gps_is_usb = (0 == case_ignore_strncmp(port, "usb:", 4)); + gps_is_usb = (0 == case_ignore_strncmp(port, "usb:", 4)); - if (gps_is_usb) { - ops = &gps_usb_ops; - } else { - ops = &gps_serial_ops; - } + if (gps_is_usb) { + ops = &gps_usb_ops; + } else { + ops = &gps_serial_ops; + } - return (ops->Device_On)(port, fd); + return (ops->Device_On)(port, fd); } -int32 GPS_Device_Off(gpsdevh * fd) +int32 GPS_Device_Off(gpsdevh* fd) { - return (ops->Device_Off)(fd); + return (ops->Device_Off)(fd); } -int32 GPS_Device_Wait(gpsdevh * fd) +int32 GPS_Device_Wait(gpsdevh* fd) { - return (ops->Device_Wait)(fd); + return (ops->Device_Wait)(fd); } -int32 GPS_Device_Chars_Ready(gpsdevh * fd) +int32 GPS_Device_Chars_Ready(gpsdevh* fd) { - return (ops->Device_Chars_Ready)(fd); + return (ops->Device_Chars_Ready)(fd); } -int32 GPS_Device_Flush(gpsdevh * fd) +int32 GPS_Device_Flush(gpsdevh* fd) { - return (ops->Device_Flush)(fd); + return (ops->Device_Flush)(fd); } -int32 GPS_Write_Packet(gpsdevh * fd, GPS_PPacket packet) +int32 GPS_Write_Packet(gpsdevh* fd, GPS_PPacket packet) { - return (ops->Write_Packet)(fd, packet); + return (ops->Write_Packet)(fd, packet); } -int32 GPS_Packet_Read(gpsdevh * fd, GPS_PPacket *packet) +int32 GPS_Packet_Read(gpsdevh* fd, GPS_PPacket* packet) { - return (ops->Read_Packet)(fd, packet); + return (ops->Read_Packet)(fd, packet); } -int32 GPS_Send_Ack(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec) +int32 GPS_Send_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec) { - return (ops->Send_Ack)(fd, tra, rec); + return (ops->Send_Ack)(fd, tra, rec); } -int32 GPS_Get_Ack(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec) +int32 GPS_Get_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec) { - return (ops->Get_Ack)(fd, tra, rec); + return (ops->Get_Ack)(fd, tra, rec); } -void GPS_Make_Packet(GPS_PPacket *packet, US type, UC *data, uint32 n) +void GPS_Make_Packet(GPS_PPacket* packet, US type, UC* data, uint32 n) { - (*packet)->type = type; - memcpy((*packet)->data, data, n); - (*packet)->n = n; + (*packet)->type = type; + memcpy((*packet)->data, data, n); + (*packet)->n = n; } diff --git a/gpsbabel/jeeps/gpsdevice.h b/gpsbabel/jeeps/gpsdevice.h index c428ea158..481826545 100644 --- a/gpsbabel/jeeps/gpsdevice.h +++ b/gpsbabel/jeeps/gpsdevice.h @@ -27,42 +27,42 @@ extern "C" #ifndef gpsdevice_h #define gpsdevice_h -typedef struct gpsdevh gpsdevh; + typedef struct gpsdevh gpsdevh; #include "gps.h" #define usecDELAY 180000 /* Microseconds before GPS sends A001 */ -int32 GPS_Device_Chars_Ready(gpsdevh *fd); -int32 GPS_Device_On(const char *port, gpsdevh **fd); -int32 GPS_Device_Off(gpsdevh *fd); -int32 GPS_Device_Wait(gpsdevh * fd); -int32 GPS_Device_Flush(gpsdevh * fd); -int32 GPS_Device_Read(int32 ignored, void *ibuf, int size); -int32 GPS_Device_Write(int32 ignored, const void *obuf, int size); -void GPS_Device_Error(char *hdr, ...); -int32 GPS_Write_Packet(gpsdevh *fd, GPS_PPacket packet); -int32 GPS_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); -int32 GPS_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); -int32 GPS_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + int32 GPS_Device_Chars_Ready(gpsdevh* fd); + int32 GPS_Device_On(const char* port, gpsdevh** fd); + int32 GPS_Device_Off(gpsdevh* fd); + int32 GPS_Device_Wait(gpsdevh* fd); + int32 GPS_Device_Flush(gpsdevh* fd); + int32 GPS_Device_Read(int32 ignored, void* ibuf, int size); + int32 GPS_Device_Write(int32 ignored, const void* obuf, int size); + void GPS_Device_Error(char* hdr, ...); + int32 GPS_Write_Packet(gpsdevh* fd, GPS_PPacket packet); + int32 GPS_Send_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec); + int32 GPS_Packet_Read(gpsdevh* fd, GPS_PPacket* packet); + int32 GPS_Get_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec); -typedef int32 (*gps_device_op)(gpsdevh *); -typedef int32 (*gps_device_op5)(const char *, gpsdevh **fd); -typedef int32 (*gps_device_op10)(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec); -typedef int32 (*gps_device_op12)(gpsdevh * fd, GPS_PPacket packet); -typedef int32 (*gps_device_op13)(gpsdevh * fd, GPS_PPacket *packet); -typedef struct { - gps_device_op5 Device_On; - gps_device_op Device_Off; - gps_device_op Device_Chars_Ready; - gps_device_op Device_Wait; - gps_device_op Device_Flush; - gps_device_op10 Send_Ack; - gps_device_op10 Get_Ack; - gps_device_op13 Read_Packet; - gps_device_op12 Write_Packet; -} gps_device_ops; + typedef int32(*gps_device_op)(gpsdevh*); + typedef int32(*gps_device_op5)(const char*, gpsdevh** fd); + typedef int32(*gps_device_op10)(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec); + typedef int32(*gps_device_op12)(gpsdevh* fd, GPS_PPacket packet); + typedef int32(*gps_device_op13)(gpsdevh* fd, GPS_PPacket* packet); + typedef struct { + gps_device_op5 Device_On; + gps_device_op Device_Off; + gps_device_op Device_Chars_Ready; + gps_device_op Device_Wait; + gps_device_op Device_Flush; + gps_device_op10 Send_Ack; + gps_device_op10 Get_Ack; + gps_device_op13 Read_Packet; + gps_device_op12 Write_Packet; + } gps_device_ops; #endif /* gpsdevice.h */ diff --git a/gpsbabel/jeeps/gpsdevice_ser.c b/gpsbabel/jeeps/gpsdevice_ser.c index ae6c3cd17..bea30926d 100644 --- a/gpsbabel/jeeps/gpsdevice_ser.c +++ b/gpsbabel/jeeps/gpsdevice_ser.c @@ -24,13 +24,13 @@ #include "gpsread.h" gps_device_ops gps_serial_ops = { - GPS_Serial_On, - GPS_Serial_Off, - GPS_Serial_Chars_Ready, - GPS_Serial_Wait, - GPS_Serial_Flush, - GPS_Serial_Send_Ack, - GPS_Serial_Get_Ack, - GPS_Serial_Packet_Read, - GPS_Serial_Write_Packet, + GPS_Serial_On, + GPS_Serial_Off, + GPS_Serial_Chars_Ready, + GPS_Serial_Wait, + GPS_Serial_Flush, + GPS_Serial_Send_Ack, + GPS_Serial_Get_Ack, + GPS_Serial_Packet_Read, + GPS_Serial_Write_Packet, }; diff --git a/gpsbabel/jeeps/gpsdevice_usb.c b/gpsbabel/jeeps/gpsdevice_usb.c index 32cb0ef73..a9a9c9f8b 100644 --- a/gpsbabel/jeeps/gpsdevice_usb.c +++ b/gpsbabel/jeeps/gpsdevice_usb.c @@ -24,35 +24,37 @@ #include "gpsusbint.h" #include "gpsusbcommon.h" +garmin_unit_info_t garmin_unit_info[GUSB_MAX_UNITS]; + static int32 success_stub(void) { - return 1; + return 1; } -static int32 gdu_on(const char *port, gpsdevh **fd) +static int32 gdu_on(const char* port, gpsdevh** fd) { - return gusb_init(port, fd); + return gusb_init(port, fd); } -static int32 gdu_off(gpsdevh *dh) +static int32 gdu_off(gpsdevh* dh) { - return gusb_close(dh); + return gusb_close(dh); } -static int32 gdu_read(gpsdevh *fd, GPS_PPacket *packet) +static int32 gdu_read(gpsdevh* fd, GPS_PPacket* packet) { - /* Default is to eat bulk request packets. */ - return GPS_Packet_Read_usb(fd, packet, 1); + /* Default is to eat bulk request packets. */ + return GPS_Packet_Read_usb(fd, packet, 1); } gps_device_ops gps_usb_ops = { - gdu_on, - gdu_off, - (gps_device_op) success_stub, - (gps_device_op) success_stub, - (gps_device_op) success_stub, - (gps_device_op10) success_stub, - (gps_device_op10) success_stub, - gdu_read, - GPS_Write_Packet_usb + gdu_on, + gdu_off, + (gps_device_op) success_stub, + (gps_device_op) success_stub, + (gps_device_op) success_stub, + (gps_device_op10) success_stub, + (gps_device_op10) success_stub, + gdu_read, + GPS_Write_Packet_usb }; diff --git a/gpsbabel/jeeps/gpsfmt.c b/gpsbabel/jeeps/gpsfmt.c index f4919a092..af355a273 100644 --- a/gpsbabel/jeeps/gpsfmt.c +++ b/gpsbabel/jeeps/gpsfmt.c @@ -2,20 +2,20 @@ ** @source JEEPS output functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -26,89 +26,85 @@ #include -static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf); -static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf); - -static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf); -static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf); -static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf); - -static int32 GPS_Fmt_Print_Route201(GPS_PWay *way, int32 n, FILE *outf); - - -char *gps_marine_sym[]= -{ - "Anchor","Bell","Diamond-grn","Diamond_red","Dive1","Dive2","Dollar", - "Fish","Fuel","Horn","House","Knife","Light","Mug","Skull", - "Square_grn","Square_red","Wbuoy","Wpt_dot","Wreck","Null","Mob", - - "Buoy_amber","Buoy_blck","Buoy_blue","Buoy_grn","Buoy_grn_red", - "Buoy_grn_wht","Buoy_orng","Buoy_red","Buoy_red_grn","Buoy_red_wht", - "Buoy_violet","Buoy_wht","Buoy_wht_grn","Buoy_wht_red","Dot","Rbcn", - - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","", - - "Boat_ramp","Camp","Toilets","Showers","Drinking_wtr","Phone", - "1st_aid","Info","Parking","Park","Picnic","Scenic","Skiing", - "Swimming","Dam","Controlled","Danger","Restricted","Null_2","Ball", - "Car","Deer","Shpng_trolley","Lodging","Mine","Trail_head", - "Lorry_stop","User_exit","Flag","Circle-x" +static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE* outf); +static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE* outf); + +static void GPS_Fmt_Print_Track301(GPS_PTrack* trk, int32 n, FILE* outf); +static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE* outf); +static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE* outf); + +static int32 GPS_Fmt_Print_Route201(GPS_PWay* way, int32 n, FILE* outf); + + +char* gps_marine_sym[]= { + "Anchor","Bell","Diamond-grn","Diamond_red","Dive1","Dive2","Dollar", + "Fish","Fuel","Horn","House","Knife","Light","Mug","Skull", + "Square_grn","Square_red","Wbuoy","Wpt_dot","Wreck","Null","Mob", + + "Buoy_amber","Buoy_blck","Buoy_blue","Buoy_grn","Buoy_grn_red", + "Buoy_grn_wht","Buoy_orng","Buoy_red","Buoy_red_grn","Buoy_red_wht", + "Buoy_violet","Buoy_wht","Buoy_wht_grn","Buoy_wht_red","Dot","Rbcn", + + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","", + + "Boat_ramp","Camp","Toilets","Showers","Drinking_wtr","Phone", + "1st_aid","Info","Parking","Park","Picnic","Scenic","Skiing", + "Swimming","Dam","Controlled","Danger","Restricted","Null_2","Ball", + "Car","Deer","Shpng_trolley","Lodging","Mine","Trail_head", + "Lorry_stop","User_exit","Flag","Circle-x" }; -char *gps_land_sym[]= -{ - "Is_hwy","Us_hwy","St_hwy","Mi_mrkr","Trcbck","Golf","Sml_cty", - "Med_cty","Lrg_cty","Freeway","Ntl_hwy","Cap_cty","Amuse_pk", - "Bowling","Car_rental","Car_repair","Fastfood","Fitness","Film", - "Museum","Chemist","Pizza","Post_ofc","Rv_park","School", - "Stadium","Shop","Zoo","Petrol_plus","Theatre","Ramp_int", - "St_int","","","Weigh_stn","Toll_booth","Elev_pt","Ex_no_srvc", - "Geo_place_mm","Geo_place_wtr","Geo_place_lnd","Bridge","Building", - "Cemetery","Church","Civil_loc","Crossing","Hist_town","River_Embankment", - "Military_loc","Oil_field","Tunnel","Beach","Forest","Summit", - "Lrg_ramp_int","Lrg_exit_no_srvc","Official_badge","Gambling", - "Snow_ski","Ice_ski","Tow_truck","Border" +char* gps_land_sym[]= { + "Is_hwy","Us_hwy","St_hwy","Mi_mrkr","Trcbck","Golf","Sml_cty", + "Med_cty","Lrg_cty","Freeway","Ntl_hwy","Cap_cty","Amuse_pk", + "Bowling","Car_rental","Car_repair","Fastfood","Fitness","Film", + "Museum","Chemist","Pizza","Post_ofc","Rv_park","School", + "Stadium","Shop","Zoo","Petrol_plus","Theatre","Ramp_int", + "St_int","","","Weigh_stn","Toll_booth","Elev_pt","Ex_no_srvc", + "Geo_place_mm","Geo_place_wtr","Geo_place_lnd","Bridge","Building", + "Cemetery","Church","Civil_loc","Crossing","Hist_town","River_Embankment", + "Military_loc","Oil_field","Tunnel","Beach","Forest","Summit", + "Lrg_ramp_int","Lrg_exit_no_srvc","Official_badge","Gambling", + "Snow_ski","Ice_ski","Tow_truck","Border" }; -char *gps_aviation_sym[]= -{ - "Airport","Int","Ndb","Vor","Heliport","Private","Soft_fld", - "Tall_tower","Short_tower","Glider","Ultralight","Parachute", - "Vortac","Vordme","Faf","Lom","Map","Tacan","Seaplane" +char* gps_aviation_sym[]= { + "Airport","Int","Ndb","Vor","Heliport","Private","Soft_fld", + "Tall_tower","Short_tower","Glider","Ultralight","Parachute", + "Vortac","Vordme","Faf","Lom","Map","Tacan","Seaplane" }; -char *gps_16_sym[]= -{ - "Dot","House","Fuel","Car","Fish","Boat","Anchor","Wreck", - "Exit","Skull","Flag","Camp","Circle-x","Deer","1st_aid","Back_track" +char* gps_16_sym[]= { + "Dot","House","Fuel","Car","Fish","Boat","Anchor","Wreck", + "Exit","Skull","Flag","Camp","Circle-x","Deer","1st_aid","Back_track" }; @@ -125,12 +121,12 @@ char *gps_16_sym[]= ** @return [void] ************************************************************************/ -void GPS_Fmt_Print_Time(time_t Time, FILE *outf) +void GPS_Fmt_Print_Time(time_t Time, FILE* outf) { - (void) fprintf(outf,"%s",ctime(&Time)); - fflush(outf); + (void) fprintf(outf,"%s",ctime(&Time)); + fflush(outf); - return; + return; } @@ -146,12 +142,12 @@ void GPS_Fmt_Print_Time(time_t Time, FILE *outf) ** @return [void] ************************************************************************/ -void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf) +void GPS_Fmt_Print_Position(double lat, double lon, FILE* outf) { - (void) fprintf(outf,"Latitude: %f Longitude %f\n",lat,lon); - fflush(outf); + (void) fprintf(outf,"Latitude: %f Longitude %f\n",lat,lon); + fflush(outf); - return; + return; } @@ -166,52 +162,51 @@ void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf) ** @return [void] ************************************************************************/ -void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf) +void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE* outf) { - (void) fprintf(outf,"Fix: "); - switch(pvt->fix) - { - case 0: - (void) fprintf(outf,"UNUSABLE\n\n"); - break; - case 1: - (void) fprintf(outf,"INVALID \n\n"); - break; - case 2: - (void) fprintf(outf,"2D \n\n"); - break; - case 3: - (void) fprintf(outf,"3D \n\n"); - break; - case 4: - (void) fprintf(outf,"2D-diff \n\n"); - break; - case 5: - (void) fprintf(outf,"2D-diff \n\n"); - break; - default: - (void) fprintf(stderr,"PVT: Unsupported Fix type\n"); - break; - } - - (void) fprintf(outf,"Altitude (WGS 84): %-20f \n",pvt->alt); - (void) fprintf(outf,"EPE: %-20f \n",pvt->epe); - (void) fprintf(outf,"EPE (hor only): %-20f \n",pvt->eph); - (void) fprintf(outf,"EPE (ver only): %-20f \n",pvt->epv); - (void) fprintf(outf,"Time of week: %-20d \n",(int)pvt->tow); - (void) fprintf(outf,"Latitude: %-20f \n",pvt->lat); - (void) fprintf(outf,"Longitude: %-20f \n",pvt->lon); - (void) fprintf(outf,"East velocity: %-20f \n",pvt->east); - (void) fprintf(outf,"North velocity: %-20f \n",pvt->north); - (void) fprintf(outf,"Upward velocity %-20f \n",pvt->up); - (void) fprintf(outf,"Height above MSL: %-20f \n",pvt->msl_hght+pvt->alt); - (void) fprintf(outf,"Leap seconds: %-20d \n",pvt->leap_scnds); - (void) fprintf(outf,"Week number days: %-20d \n",(int)pvt->wn_days); - - fflush(outf); - - return; + (void) fprintf(outf,"Fix: "); + switch (pvt->fix) { + case 0: + (void) fprintf(outf,"UNUSABLE\n\n"); + break; + case 1: + (void) fprintf(outf,"INVALID \n\n"); + break; + case 2: + (void) fprintf(outf,"2D \n\n"); + break; + case 3: + (void) fprintf(outf,"3D \n\n"); + break; + case 4: + (void) fprintf(outf,"2D-diff \n\n"); + break; + case 5: + (void) fprintf(outf,"2D-diff \n\n"); + break; + default: + (void) fprintf(stderr,"PVT: Unsupported Fix type\n"); + break; + } + + (void) fprintf(outf,"Altitude (WGS 84): %-20f \n",pvt->alt); + (void) fprintf(outf,"EPE: %-20f \n",pvt->epe); + (void) fprintf(outf,"EPE (hor only): %-20f \n",pvt->eph); + (void) fprintf(outf,"EPE (ver only): %-20f \n",pvt->epv); + (void) fprintf(outf,"Time of week: %-20d \n",(int)pvt->tow); + (void) fprintf(outf,"Latitude: %-20f \n",pvt->lat); + (void) fprintf(outf,"Longitude: %-20f \n",pvt->lon); + (void) fprintf(outf,"East velocity: %-20f \n",pvt->east); + (void) fprintf(outf,"North velocity: %-20f \n",pvt->north); + (void) fprintf(outf,"Upward velocity %-20f \n",pvt->up); + (void) fprintf(outf,"Height above MSL: %-20f \n",pvt->msl_hght+pvt->alt); + (void) fprintf(outf,"Leap seconds: %-20d \n",pvt->leap_scnds); + (void) fprintf(outf,"Week number days: %-20d \n",(int)pvt->wn_days); + + fflush(outf); + + return; } @@ -227,62 +222,63 @@ void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf) ** @return [void] ************************************************************************/ -void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf) +void GPS_Fmt_Print_Almanac(GPS_PAlmanac* alm, int32 n, FILE* outf) { - int32 i; - int32 t; - int32 s; - - /* Type 0 models require all 32 satellites to be sent */ - t=32; - s=0; - if(n && alm[0]->svid!=0xff) - { - s=1; - t=n; - } - (void) fprintf(outf,"Almanac %d %d\n",(int)t,(int)s); - - - for(i=0;iwn<0) continue; - - if(alm[i]->svid == 0xff) - alm[i]->svid = i; - (void) fprintf(outf,"#\n#\n"); - (void) fprintf(outf,"\tID: %d\n", - alm[i]->svid+1); - (void) fprintf(outf,"\tWeek number: %d\n", - alm[i]->wn); - (void) fprintf(outf,"\tAlmanac Data Reference Time: %f\n", - alm[i]->toa); - (void) fprintf(outf,"\tClock Correction Coeff (s): %f\n", - alm[i]->af0); - (void) fprintf(outf,"\tClock Correction Coeff (s/s): %f\n", - alm[i]->af1); - (void) fprintf(outf,"\tEccentricity: %f\n", - alm[i]->e); - (void) fprintf(outf,"\tSqrt of semi-major axis: %f\n", - alm[i]->sqrta); - (void) fprintf(outf,"\tMean Anomaly at Ref. Time: %f\n", - alm[i]->m0); - (void) fprintf(outf,"\tArgument of perigee: %f\n", - alm[i]->w); - (void) fprintf(outf,"\tRight ascension: %f\n", - alm[i]->omg0); - (void) fprintf(outf,"\tRate of right ascension: %f\n", - alm[i]->odot); - (void) fprintf(outf,"\tInclination angle: %f\n", - alm[i]->i); - (void) fprintf(outf,"\tHealth: %d\n", - alm[i]->hlth); + int32 i; + int32 t; + int32 s; + + /* Type 0 models require all 32 satellites to be sent */ + t=32; + s=0; + if (n && alm[0]->svid!=0xff) { + s=1; + t=n; + } + (void) fprintf(outf,"Almanac %d %d\n",(int)t,(int)s); + + + for (i=0; iwn<0) { + continue; } - - fflush(outf); - - return; + if (alm[i]->svid == 0xff) { + alm[i]->svid = i; + } + (void) fprintf(outf,"#\n#\n"); + (void) fprintf(outf,"\tID: %d\n", + alm[i]->svid+1); + (void) fprintf(outf,"\tWeek number: %d\n", + alm[i]->wn); + (void) fprintf(outf,"\tAlmanac Data Reference Time: %f\n", + alm[i]->toa); + (void) fprintf(outf,"\tClock Correction Coeff (s): %f\n", + alm[i]->af0); + (void) fprintf(outf,"\tClock Correction Coeff (s/s): %f\n", + alm[i]->af1); + (void) fprintf(outf,"\tEccentricity: %f\n", + alm[i]->e); + (void) fprintf(outf,"\tSqrt of semi-major axis: %f\n", + alm[i]->sqrta); + (void) fprintf(outf,"\tMean Anomaly at Ref. Time: %f\n", + alm[i]->m0); + (void) fprintf(outf,"\tArgument of perigee: %f\n", + alm[i]->w); + (void) fprintf(outf,"\tRight ascension: %f\n", + alm[i]->omg0); + (void) fprintf(outf,"\tRate of right ascension: %f\n", + alm[i]->odot); + (void) fprintf(outf,"\tInclination angle: %f\n", + alm[i]->i); + (void) fprintf(outf,"\tHealth: %d\n", + alm[i]->hlth); + } + + + fflush(outf); + + return; } @@ -298,49 +294,47 @@ void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf) ** @return [void] ************************************************************************/ -void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf) +void GPS_Fmt_Print_Track(GPS_PTrack* trk, int32 n, FILE* outf) { - int32 i; + int32 i; - switch(gps_trk_transfer) - { - case pA300: - break; - case pA301: - GPS_Fmt_Print_Track301(trk,n,outf); - return; - default: - GPS_Error("GPS_Fmt_Print_Track: Unknown protocol"); - return; - } + switch (gps_trk_transfer) { + case pA300: + break; + case pA301: + GPS_Fmt_Print_Track301(trk,n,outf); + return; + default: + GPS_Error("GPS_Fmt_Print_Track: Unknown protocol"); + return; + } + + (void) fprintf(outf,"Track log 300 %d\n#\n",(int)gps_trk_type); + (void) fprintf(outf,"Start\n#\n"); - (void) fprintf(outf,"Track log 300 %d\n#\n",(int)gps_trk_type); - (void) fprintf(outf,"Start\n#\n"); - - for(i=0;itnew) - (void) fprintf(outf,"#\nNew track\n#\n"); - - switch(gps_trk_type) - { - case pD300: - GPS_Fmt_Print_D300(trk[i],outf); - break; - case pD301: - GPS_Fmt_Print_D301(trk[i],outf); - break; - default: - break; - } + for (i=0; itnew) { + (void) fprintf(outf,"#\nNew track\n#\n"); } - (void) fprintf(outf,"End\n#\n"); - fflush(outf); + switch (gps_trk_type) { + case pD300: + GPS_Fmt_Print_D300(trk[i],outf); + break; + case pD301: + GPS_Fmt_Print_D301(trk[i],outf); + break; + default: + break; + } + } - return; + (void) fprintf(outf,"End\n#\n"); + fflush(outf); + + return; } @@ -356,48 +350,47 @@ void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf) +static void GPS_Fmt_Print_Track301(GPS_PTrack* trk, int32 n, FILE* outf) { - int32 i; - - if(!n) - return; - - (void) fprintf(outf,"Track log 301 %d\n#\n",(int)gps_trk_type); - (void) fprintf(outf,"Start\n#\n"); - - for(i=0;iishdr) - { - (void) fprintf(outf,"Header\n"); - (void) fprintf(outf,"\tIdent: %s\n",trk[i]->trk_ident); - (void) fprintf(outf,"\tDisplay: %d\n",(int)trk[i]->dspl); - (void) fprintf(outf,"\tColour: %d\n#\n", - (int)trk[i]->colour); - continue; - } - - if(trk[i]->tnew) - (void) fprintf(outf,"#\nNew track\n#\n"); - - switch(gps_trk_type) - { - case pD300: - GPS_Fmt_Print_D300(trk[i],outf); - break; - case pD301: - GPS_Fmt_Print_D301(trk[i],outf); - break; - default: - break; - } + int32 i; + + if (!n) { + return; + } + + (void) fprintf(outf,"Track log 301 %d\n#\n",(int)gps_trk_type); + (void) fprintf(outf,"Start\n#\n"); + + for (i=0; iishdr) { + (void) fprintf(outf,"Header\n"); + (void) fprintf(outf,"\tIdent: %s\n",trk[i]->trk_ident); + (void) fprintf(outf,"\tDisplay: %d\n",(int)trk[i]->dspl); + (void) fprintf(outf,"\tColour: %d\n#\n", + (int)trk[i]->colour); + continue; } - (void) fprintf(outf,"End\n#\n"); - fflush(outf); + if (trk[i]->tnew) { + (void) fprintf(outf,"#\nNew track\n#\n"); + } - return; + switch (gps_trk_type) { + case pD300: + GPS_Fmt_Print_D300(trk[i],outf); + break; + case pD301: + GPS_Fmt_Print_D301(trk[i],outf); + break; + default: + break; + } + } + + (void) fprintf(outf,"End\n#\n"); + fflush(outf); + + return; } @@ -411,16 +404,17 @@ static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf) +static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE* outf) { - (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); - (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); - if(trk->Time) - (void) fprintf(outf,"\tTime: %s\n",ctime(&trk->Time)); - else - (void) fprintf(outf,"\tTime: Computer\n\n"); - - return; + (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); + (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); + if (trk->Time) { + (void) fprintf(outf,"\tTime: %s\n",ctime(&trk->Time)); + } else { + (void) fprintf(outf,"\tTime: Computer\n\n"); + } + + return; } @@ -435,18 +429,19 @@ static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf) +static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE* outf) { - (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); - (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); - if(trk->Time) - (void) fprintf(outf,"\tTime: %s",ctime(&trk->Time)); - else - (void) fprintf(outf,"\tTime: Computer\n"); - (void) fprintf(outf,"\tAltitude: %f\n",trk->alt); - (void) fprintf(outf,"\tDepth: %f\n\n",trk->dpth); - - return; + (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); + (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); + if (trk->Time) { + (void) fprintf(outf,"\tTime: %s",ctime(&trk->Time)); + } else { + (void) fprintf(outf,"\tTime: Computer\n"); + } + (void) fprintf(outf,"\tAltitude: %f\n",trk->alt); + (void) fprintf(outf,"\tDepth: %f\n\n",trk->dpth); + + return; } @@ -463,76 +458,75 @@ static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf) ** @return [int32] success ************************************************************************/ -int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf) +int32 GPS_Fmt_Print_Waypoint(GPS_PWay* way, int32 n, FILE* outf) { - int32 i; - - - if(!n) - return 1; - - (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", - (int)way[0]->prot); - - - for(i=0;iprot) - { - case 100: - GPS_Fmt_Print_Way100(way[i],outf); - break; - case 101: - GPS_Fmt_Print_Way101(way[i],outf); - break; - case 102: - GPS_Fmt_Print_Way102(way[i],outf); - break; - case 103: - GPS_Fmt_Print_Way103(way[i],outf); - break; - case 104: - GPS_Fmt_Print_Way104(way[i],outf); - break; - case 105: - GPS_Fmt_Print_Way105(way[i],outf); - break; - case 106: - GPS_Fmt_Print_Way106(way[i],outf); - break; - case 107: - GPS_Fmt_Print_Way107(way[i],outf); - break; - case 108: - GPS_Fmt_Print_Way108(way[i],outf); - break; - case 109: - GPS_Fmt_Print_Way109(way[i],outf); - break; - case 150: - GPS_Fmt_Print_Way150(way[i],outf); - break; - case 151: - GPS_Fmt_Print_Way151(way[i],outf); - break; - case 152: - GPS_Fmt_Print_Way152(way[i],outf); - break; - case 154: - GPS_Fmt_Print_Way154(way[i],outf); - break; - case 155: - GPS_Fmt_Print_Way155(way[i],outf); - break; - default: - GPS_Error("Print_Waypoint: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"#\n"); - } - (void) fprintf(outf,"End\n#\n"); + int32 i; + + if (!n) { return 1; + } + + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", + (int)way[0]->prot); + + + for (i=0; iprot) { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); + + return 1; } @@ -548,78 +542,77 @@ int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf) ** @return [int32] success ************************************************************************/ -int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf) +int32 GPS_Fmt_Print_Proximity(GPS_PWay* way, int32 n, FILE* outf) { - int32 i; - - - if(!n) - return 1; - - (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", - (int)way[0]->prot); - - - for(i=0;iprot) - { - case 400: - GPS_Fmt_Print_Way100(way[i],outf); - break; - case 101: - GPS_Fmt_Print_Way101(way[i],outf); - break; - case 102: - GPS_Fmt_Print_Way102(way[i],outf); - break; - case 403: - GPS_Fmt_Print_Way103(way[i],outf); - break; - case 104: - GPS_Fmt_Print_Way104(way[i],outf); - break; - case 105: - GPS_Fmt_Print_Way105(way[i],outf); - break; - case 106: - GPS_Fmt_Print_Way106(way[i],outf); - break; - case 107: - GPS_Fmt_Print_Way107(way[i],outf); - break; - case 108: - GPS_Fmt_Print_Way108(way[i],outf); - break; - case 109: - GPS_Fmt_Print_Way109(way[i],outf); - break; - case 450: - GPS_Fmt_Print_Way150(way[i],outf); - (void) fprintf(outf,"\tPindex: %d\n",(int)way[i]->idx); - break; - case 151: - GPS_Fmt_Print_Way151(way[i],outf); - break; - case 152: - GPS_Fmt_Print_Way152(way[i],outf); - break; - case 154: - GPS_Fmt_Print_Way154(way[i],outf); - break; - case 155: - GPS_Fmt_Print_Way155(way[i],outf); - break; - default: - GPS_Error("Print_Proximity: Unknown proximity protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"\tDistance: %f\n",way[i]->dst); - (void) fprintf(outf,"#\n"); - } - (void) fprintf(outf,"End\n#\n"); + int32 i; + + if (!n) { return 1; + } + + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", + (int)way[0]->prot); + + + for (i=0; iprot) { + case 400: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 403: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 450: + GPS_Fmt_Print_Way150(way[i],outf); + (void) fprintf(outf,"\tPindex: %d\n",(int)way[i]->idx); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Proximity: Unknown proximity protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\tDistance: %f\n",way[i]->dst); + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); + + return 1; } @@ -635,15 +628,15 @@ int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE* outf) { - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - return; + return; } @@ -657,19 +650,21 @@ static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE* outf) { - if(way->smbl > 176) way->smbl=36; - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, - gps_marine_sym[way->smbl]); + if (way->smbl > 176) { + way->smbl=36; + } - return; + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, + gps_marine_sym[way->smbl]); + + return; } @@ -683,36 +678,31 @@ static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE* outf) { - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - - return; + char** p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + + return; } @@ -726,23 +716,22 @@ static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE* outf) { - static char *dspl[]= - { - "SW","S","SC" - }; - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - gps_16_sym[way->smbl]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - - return; + static char* dspl[]= { + "SW","S","SC" + }; + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + gps_16_sym[way->smbl]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + + return; } @@ -756,41 +745,35 @@ static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE* outf) { - static char *dspl[]= - { - "S","S","","SW","","SC" - }; - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - - return; + static char* dspl[]= { + "S","S","","SW","","SC" + }; + char** p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + + return; } @@ -804,34 +787,29 @@ static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE* outf) { - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); - - return; + char** p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); + + return; } @@ -845,50 +823,42 @@ static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE* outf) { - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - if(!way->wpt_class) - { - (void) fprintf(outf,"\tClass: %d [User]\n",way->wpt_class); - (void) fprintf(outf,"\tSubclass: %d [%-13.13s]\n", - way->wpt_class,way->subclass); - (void) fprintf(outf,"\tSubclass:\n"); - } - else - { - (void) fprintf(outf,"\tClass: %d [Non-user]\n", - way->wpt_class); - (void) fprintf(outf,"\tSubclass: %d [%13.13s]\n", - way->wpt_class, - way->subclass); - } - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); - (void) fprintf(outf,"\tLnk_ident %s\n",way->lnk_ident); - - return; + char** p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + if (!way->wpt_class) { + (void) fprintf(outf,"\tClass: %d [User]\n",way->wpt_class); + (void) fprintf(outf,"\tSubclass: %d [%-13.13s]\n", + way->wpt_class,way->subclass); + (void) fprintf(outf,"\tSubclass:\n"); + } else { + (void) fprintf(outf,"\tClass: %d [Non-user]\n", + way->wpt_class); + (void) fprintf(outf,"\tSubclass: %d [%13.13s]\n", + way->wpt_class, + way->subclass); + } + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); + (void) fprintf(outf,"\tLnk_ident %s\n",way->lnk_ident); + + return; } @@ -902,30 +872,28 @@ static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE* outf) { - static char *dspl[]= - { - "SW","S","SC" - }; - static char *col[]= - { - "Default","Red","Green","Blue" - }; - - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - gps_16_sym[way->smbl]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, - col[way->colour]); - - return; + static char* dspl[]= { + "SW","S","SC" + }; + static char* col[]= { + "Default","Red","Green","Blue" + }; + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + gps_16_sym[way->smbl]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); + + return; } @@ -940,73 +908,69 @@ static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE* outf) { - char **p; - int32 x; - - static char *dspl[]= - { - "SW","S","SC" - }; - - static char *col[]= - { - "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", - "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", - "Yellow","Blue","Magenta","Cyan","White" - }; - - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - (void) fprintf(outf,"\tIdent: %s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - if(way->colour==0xff) - (void) fprintf(outf,"\tColour: 255 [Default]\n"); - else - (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, - col[way->colour]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - (void) fprintf(outf,"\tDepth: %f\n",way->dpth); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class>=0x80 && way->wpt_class<=0x85) - (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); - if(!way->wpt_class) - (void) fprintf(outf,"\tComment: %s\n",way->cmnt); - if(way->wpt_class>=0x40 && way->wpt_class<=0x46) - { - (void) fprintf(outf,"\tFacility: %s\n",way->facility); - (void) fprintf(outf,"\tCity: %s\n",way->city); - } - if(way->wpt_class==0x83) - (void) fprintf(outf,"\tAddress: %s\n",way->addr); - if(way->wpt_class==0x82) - (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); - - - return; + char** p; + int32 x; + + static char* dspl[]= { + "SW","S","SC" + }; + + static char* col[]= { + "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", + "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", + "Yellow","Blue","Magenta","Cyan","White" + }; + + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + if (way->colour==0xff) { + (void) fprintf(outf,"\tColour: 255 [Default]\n"); + } else + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + (void) fprintf(outf,"\tDepth: %f\n",way->dpth); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class>=0x80 && way->wpt_class<=0x85) { + (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tComment: %s\n",way->cmnt); + } + if (way->wpt_class>=0x40 && way->wpt_class<=0x46) { + (void) fprintf(outf,"\tFacility: %s\n",way->facility); + (void) fprintf(outf,"\tCity: %s\n",way->city); + } + if (way->wpt_class==0x83) { + (void) fprintf(outf,"\tAddress: %s\n",way->addr); + } + if (way->wpt_class==0x82) { + (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); + } + + + return; } /* @funcstatic GPS_Fmt_Print_Way109 ************************************ @@ -1019,76 +983,72 @@ static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE* outf) { - char **p; - int32 x; - - static char *dspl[]= - { - "SW","S","SC" - }; - - static char *col[]= - { - "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", - "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", - "Yellow","Blue","Magenta","Cyan","White" - }; - - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - (void) fprintf(outf,"\tIdent: %s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - if(way->colour==0xff) - (void) fprintf(outf,"\tColour: 255 [Default]\n"); - else - (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, - col[way->colour]); + char** p; + int32 x; + + static char* dspl[]= { + "SW","S","SC" + }; + + static char* col[]= { + "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", + "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", + "Yellow","Blue","Magenta","Cyan","White" + }; + + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + if (way->colour==0xff) { + (void) fprintf(outf,"\tColour: 255 [Default]\n"); + } else + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); #if 0 - /* avoid bounds violation in D109. Probably masking a bug elswhere...*/ - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); + /* avoid bounds violation in D109. Probably masking a bug elswhere...*/ + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); #endif - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - (void) fprintf(outf,"\tDepth: %f\n",way->dpth); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class>=0x80 && way->wpt_class<=0x85) - (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); - if(!way->wpt_class) - (void) fprintf(outf,"\tComment: %s\n",way->cmnt); - if(way->wpt_class>=0x40 && way->wpt_class<=0x46) - { - (void) fprintf(outf,"\tFacility: %s\n",way->facility); - (void) fprintf(outf,"\tCity: %s\n",way->city); - } - if(way->wpt_class==0x83) - (void) fprintf(outf,"\tAddress: %s\n",way->addr); - if(way->wpt_class==0x82) - (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); - - - return; + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + (void) fprintf(outf,"\tDepth: %f\n",way->dpth); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class>=0x80 && way->wpt_class<=0x85) { + (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tComment: %s\n",way->cmnt); + } + if (way->wpt_class>=0x40 && way->wpt_class<=0x46) { + (void) fprintf(outf,"\tFacility: %s\n",way->facility); + (void) fprintf(outf,"\tCity: %s\n",way->city); + } + if (way->wpt_class==0x83) { + (void) fprintf(outf,"\tAddress: %s\n",way->addr); + } + if (way->wpt_class==0x82) { + (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); + } + + + return; } /* @funcstatic GPS_Fmt_Print_Way150 ************************************* @@ -1101,25 +1061,25 @@ static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE* outf) { - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=4) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=4) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1133,25 +1093,25 @@ static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE* outf) { - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=2) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=2) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1166,25 +1126,25 @@ static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE* outf) { - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=4) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=4) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1198,46 +1158,41 @@ static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE* outf) { - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=4 && way->wpt_class!=8) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + char** p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=4 && way->wpt_class!=8) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1251,53 +1206,47 @@ static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf) ** @return [void] ************************************************************************/ -static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf) +static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE* outf) { - static char *dspl[]= - { - "","S","","SW","","SC" - }; - - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=4 && way->wpt_class!=8) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + static char* dspl[]= { + "","S","","SW","","SC" + }; + + char** p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=4 && way->wpt_class!=8) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1313,121 +1262,118 @@ static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf) ** @return [int32] success ************************************************************************/ -int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf) +int32 GPS_Fmt_Print_Route(GPS_PWay* way, int32 n, FILE* outf) { - int32 i; - int32 first; - - if(!n) - return 1; - - - switch(gps_route_transfer) - { - case pA200: - break; - case pA201: - return GPS_Fmt_Print_Route201(way,n,outf); - default: - GPS_Error("GPS_Fmt_Print_Route: Unknown protocol"); - return PROTOCOL_ERROR; - } + int32 i; + int32 first; + if (!n) { + return 1; + } + + + switch (gps_route_transfer) { + case pA200: + break; + case pA201: + return GPS_Fmt_Print_Route201(way,n,outf); + default: + GPS_Error("GPS_Fmt_Print_Route: Unknown protocol"); + return PROTOCOL_ERROR; + } + + + (void) fprintf(outf,"Route log 200 %d\n#\n",(int)gps_rte_type); + (void) fprintf(outf,"Start\n#\n"); + + + + first = 1; + + for (i=0; iisrte) { + if (!first) { + (void) fprintf(outf,"End\n#\n"); + } + (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); + first=0; + + switch (way[i]->rte_prot) { + case 200: + (void) fprintf(outf,"Number: %d",way[i]->rte_num); + break; + case 201: + (void) fprintf(outf,"Number: %d Comment: %-20.20s", + way[i]->rte_num,way[i]->rte_cmnt); + break; + case 202: + (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); + break; + default: + GPS_Error("Print_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\n#\n"); + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n" + ,(int)way[i]->prot); + continue; + } - (void) fprintf(outf,"Route log 200 %d\n#\n",(int)gps_rte_type); - (void) fprintf(outf,"Start\n#\n"); - - - - first = 1; - - for(i=0;iisrte) - { - if(!first) - (void) fprintf(outf,"End\n#\n"); - (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); - first=0; - - switch(way[i]->rte_prot) - { - case 200: - (void) fprintf(outf,"Number: %d",way[i]->rte_num); - break; - case 201: - (void) fprintf(outf,"Number: %d Comment: %-20.20s", - way[i]->rte_num,way[i]->rte_cmnt); - break; - case 202: - (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); - break; - default: - GPS_Error("Print_Route: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"\n#\n"); - (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n" - ,(int)way[i]->prot); - continue; - } - - switch(way[i]->prot) - { - case 100: - GPS_Fmt_Print_Way100(way[i],outf); - break; - case 101: - GPS_Fmt_Print_Way101(way[i],outf); - break; - case 102: - GPS_Fmt_Print_Way102(way[i],outf); - break; - case 103: - GPS_Fmt_Print_Way103(way[i],outf); - break; - case 104: - GPS_Fmt_Print_Way104(way[i],outf); - break; - case 105: - GPS_Fmt_Print_Way105(way[i],outf); - break; - case 106: - GPS_Fmt_Print_Way106(way[i],outf); - break; - case 107: - GPS_Fmt_Print_Way107(way[i],outf); - break; - case 108: - GPS_Fmt_Print_Way108(way[i],outf); - break; - case 109: - GPS_Fmt_Print_Way109(way[i],outf); - break; - case 150: - GPS_Fmt_Print_Way150(way[i],outf); - break; - case 151: - GPS_Fmt_Print_Way151(way[i],outf); - break; - case 152: - GPS_Fmt_Print_Way152(way[i],outf); - break; - case 154: - GPS_Fmt_Print_Way154(way[i],outf); - break; - case 155: - GPS_Fmt_Print_Way155(way[i],outf); - break; - default: - GPS_Error("Print_Route: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"#\n"); + switch (way[i]->prot) { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Route: Unknown waypoint protocol"); + return PROTOCOL_ERROR; } - (void) fprintf(outf,"End\n#\n"); + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); - return 1; + return 1; } @@ -1443,120 +1389,117 @@ int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf) ** @return [int32] success ************************************************************************/ -static int32 GPS_Fmt_Print_Route201(GPS_PWay *way, int32 n, FILE *outf) +static int32 GPS_Fmt_Print_Route201(GPS_PWay* way, int32 n, FILE* outf) { - int32 i; - int32 first; - - if(!n) - return 1; - - - (void) fprintf(outf,"Route log 201 %d\n#\n",(int)gps_rte_link_type); - (void) fprintf(outf,"Start\n#\n"); - - - first = 1; - - for(i=0;iisrte) - { - if(!first) - (void) fprintf(outf,"End\n#\n"); - (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); - first=0; - - switch(way[i]->rte_prot) - { - case 200: - (void) fprintf(outf,"Number: %d",way[i]->rte_num); - break; - case 201: - (void) fprintf(outf,"Number: %d Comment: %-20.20s", - way[i]->rte_num,way[i]->rte_cmnt); - break; - case 202: - (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); - break; - default: - GPS_Error("Print_Route: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"\n#\n"); - (void) fprintf(outf,"Waypoints Type: %d\n#\n" - ,(int)way[i]->prot); - continue; - } - - - if(way[i]->islink) - { - (void) fprintf(outf,"\tLink Class: %d\n", - (int)way[i]->rte_link_class); - if(!(way[i]->rte_link_class==3 || way[i]->rte_link_class==0xff)) - (void) fprintf(outf,"\tLink Subclass: %-18.18s\n", - way[i]->rte_link_subclass); - (void) fprintf(outf,"\tLink Ident: %s\n#\n", - way[i]->rte_link_ident); - continue; - } - - - switch(way[i]->prot) - { - case 100: - GPS_Fmt_Print_Way100(way[i],outf); - break; - case 101: - GPS_Fmt_Print_Way101(way[i],outf); - break; - case 102: - GPS_Fmt_Print_Way102(way[i],outf); - break; - case 103: - GPS_Fmt_Print_Way103(way[i],outf); - break; - case 104: - GPS_Fmt_Print_Way104(way[i],outf); - break; - case 105: - GPS_Fmt_Print_Way105(way[i],outf); - break; - case 106: - GPS_Fmt_Print_Way106(way[i],outf); - break; - case 107: - GPS_Fmt_Print_Way107(way[i],outf); - break; - case 108: - GPS_Fmt_Print_Way108(way[i],outf); - break; - case 109: - GPS_Fmt_Print_Way109(way[i],outf); - break; - case 150: - GPS_Fmt_Print_Way150(way[i],outf); - break; - case 151: - GPS_Fmt_Print_Way151(way[i],outf); - break; - case 152: - GPS_Fmt_Print_Way152(way[i],outf); - break; - case 154: - GPS_Fmt_Print_Way154(way[i],outf); - break; - case 155: - GPS_Fmt_Print_Way155(way[i],outf); - break; - default: - GPS_Error("Print_Route: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"#\n"); - } - (void) fprintf(outf,"End\n"); + int32 i; + int32 first; + if (!n) { return 1; + } + + + (void) fprintf(outf,"Route log 201 %d\n#\n",(int)gps_rte_link_type); + (void) fprintf(outf,"Start\n#\n"); + + + first = 1; + + for (i=0; iisrte) { + if (!first) { + (void) fprintf(outf,"End\n#\n"); + } + (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); + first=0; + + switch (way[i]->rte_prot) { + case 200: + (void) fprintf(outf,"Number: %d",way[i]->rte_num); + break; + case 201: + (void) fprintf(outf,"Number: %d Comment: %-20.20s", + way[i]->rte_num,way[i]->rte_cmnt); + break; + case 202: + (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); + break; + default: + GPS_Error("Print_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\n#\n"); + (void) fprintf(outf,"Waypoints Type: %d\n#\n" + ,(int)way[i]->prot); + continue; + } + + + if (way[i]->islink) { + (void) fprintf(outf,"\tLink Class: %d\n", + (int)way[i]->rte_link_class); + if (!(way[i]->rte_link_class==3 || way[i]->rte_link_class==0xff)) + (void) fprintf(outf,"\tLink Subclass: %-18.18s\n", + way[i]->rte_link_subclass); + (void) fprintf(outf,"\tLink Ident: %s\n#\n", + way[i]->rte_link_ident); + continue; + } + + + switch (way[i]->prot) { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Route: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n"); + + return 1; } diff --git a/gpsbabel/jeeps/gpsfmt.h b/gpsbabel/jeeps/gpsfmt.h index f9eaae32c..8a7377b37 100644 --- a/gpsbabel/jeeps/gpsfmt.h +++ b/gpsbabel/jeeps/gpsfmt.h @@ -11,14 +11,14 @@ extern "C" #include #include -void GPS_Fmt_Print_Time(time_t Time, FILE *outf); -void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf); -void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf); -void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf); -void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf); -int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf); -int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf); -int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf); + void GPS_Fmt_Print_Time(time_t Time, FILE* outf); + void GPS_Fmt_Print_Position(double lat, double lon, FILE* outf); + void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE* outf); + void GPS_Fmt_Print_Almanac(GPS_PAlmanac* alm, int32 n, FILE* outf); + void GPS_Fmt_Print_Track(GPS_PTrack* trk, int32 n, FILE* outf); + int32 GPS_Fmt_Print_Waypoint(GPS_PWay* way, int32 n, FILE* outf); + int32 GPS_Fmt_Print_Proximity(GPS_PWay* way, int32 n, FILE* outf); + int32 GPS_Fmt_Print_Route(GPS_PWay* way, int32 n, FILE* outf); #endif diff --git a/gpsbabel/jeeps/gpsinput.c b/gpsbabel/jeeps/gpsinput.c index 9cdf84741..66e708b70 100644 --- a/gpsbabel/jeeps/gpsinput.c +++ b/gpsbabel/jeeps/gpsinput.c @@ -2,20 +2,20 @@ ** @source JEEPS input functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -28,32 +28,32 @@ #include -static int32 GPS_Input_Load_String(char *t, int32 n, char *s); -static int32 GPS_Input_Load_Strnull(char *t, char *s); -static int32 GPS_Input_Read_Line(char *s, FILE *inf); +static int32 GPS_Input_Load_String(char* t, int32 n, char* s); +static int32 GPS_Input_Load_Strnull(char* t, char* s); +static int32 GPS_Input_Read_Line(char* s, FILE* inf); -static int32 GPS_Input_Get_D100(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D101(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D102(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D103(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D104(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D105(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D106(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D107(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf, int protonum); -static int32 GPS_Input_Get_D150(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D151(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D152(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D154(GPS_PWay *way, FILE *inf); -static int32 GPS_Input_Get_D155(GPS_PWay *way, FILE *inf); +static int32 GPS_Input_Get_D100(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D101(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D102(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D103(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D104(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D105(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D106(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D107(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D108(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D109(GPS_PWay* way, FILE* inf, int protonum); +static int32 GPS_Input_Get_D150(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D151(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D152(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D154(GPS_PWay* way, FILE* inf); +static int32 GPS_Input_Get_D155(GPS_PWay* way, FILE* inf); -static int32 GPS_Input_Get_Track301(GPS_PTrack **trk, FILE *inf, int32 type, - int32 n); -static int32 GPS_Input_Get_D300(GPS_PTrack *trk, FILE *inf, char *s); -static int32 GPS_Input_Get_D301(GPS_PTrack *trk, FILE *inf, char *s); +static int32 GPS_Input_Get_Track301(GPS_PTrack** trk, FILE* inf, int32 type, + int32 n); +static int32 GPS_Input_Get_D300(GPS_PTrack* trk, FILE* inf, char* s); +static int32 GPS_Input_Get_D301(GPS_PTrack* trk, FILE* inf, char* s); -static int32 GPS_Input_Get_Route201(GPS_PWay **way, FILE *inf); +static int32 GPS_Input_Get_Route201(GPS_PWay** way, FILE* inf); /* @funcstatic GPS_Input_Load_String *********************************** @@ -67,37 +67,44 @@ static int32 GPS_Input_Get_Route201(GPS_PWay **way, FILE *inf); ** ** @return [int32] success ************************************************************************/ -static int32 GPS_Input_Load_String(char *t, int32 n, char *s) +static int32 GPS_Input_Load_String(char* t, int32 n, char* s) { - char *p; - char *q; - - int32 len; - int32 i; - - gps_errno = INPUT_ERROR; - - p=s; - if(!(p=strchr(p,':'))) - return gps_errno; + char* p; + char* q; + + int32 len; + int32 i; + + gps_errno = INPUT_ERROR; + + p=s; + if (!(p=strchr(p,':'))) { + return gps_errno; + } + ++p; + while (*p && (*p==' ' || *p=='\t')) { ++p; - while(*p && (*p==' ' || *p=='\t')) ++p; - if(!*p) - return 0; - - len = strlen(p); - q = p+len-1; - while(*q==' ' || *q=='\t') --q; - len = q-p+1; - - if(q-p+1 > n) - { - len = n; - p[n]='\0'; - } - for(i=0;i n) { + len = n; + p[n]='\0'; + } + for (i=0; isvid = i; - (*alm)[i]->wn = -1; - } - } - else - { - if(!(*alm = (GPS_PAlmanac *) malloc(n*sizeof(GPS_PAlmanac *)))) - return MEMORY_ERROR; - for(i=0;i<32;++i) - if(!((*alm)[i] = GPS_Almanac_New())) - return MEMORY_ERROR; - } - - for(i=0;isvid!=d) ++i; - (*alm)[i]->svid=d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*alm)[i]->wn = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->toa = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->af0 = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->af1 = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->e = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->sqrta = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->m0 = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->w = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->omg0 = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->odot = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->i = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*alm)[i]->hlth=d; - } - - if(!type) - n = 32; - - return n; + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 i; + int32 d; + float f; + char* p; + + gps_errno = INPUT_ERROR; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + if (sscanf(s,"Almanac %d%d",(int*)&n,(int*)&type)!=2) { + return gps_errno; + } + + if (!type) { + if (!(*alm = (GPS_PAlmanac*) malloc(32*sizeof(GPS_PAlmanac*)))) { + return MEMORY_ERROR; + } + for (i=0; i<32; ++i) { + if (!((*alm)[i] = GPS_Almanac_New())) { + return MEMORY_ERROR; + } + + (*alm)[i]->svid = i; + (*alm)[i]->wn = -1; + } + } else { + if (!(*alm = (GPS_PAlmanac*) malloc(n*sizeof(GPS_PAlmanac*)))) { + return MEMORY_ERROR; + } + for (i=0; i<32; ++i) + if (!((*alm)[i] = GPS_Almanac_New())) { + return MEMORY_ERROR; + } + } + + for (i=0; isvid!=d) { + ++i; + } + (*alm)[i]->svid=d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*alm)[i]->wn = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->toa = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->af0 = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->af1 = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->e = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->sqrta = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->m0 = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->w = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->omg0 = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->odot = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->i = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*alm)[i]->hlth=d; + } + + if (!type) { + n = 32; + } + + return n; } @@ -339,123 +377,159 @@ int32 GPS_Input_Get_Almanac(GPS_PAlmanac **alm, FILE *inf) ** @return [int32] number of entries ************************************************************************/ -int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf) +int32 GPS_Input_Get_Waypoint(GPS_PWay** way, FILE* inf) { - char s[GPS_ARB_LEN]; - int32 n; - int32 type; - int32 i; - long pos; - int32 ret; - - gps_errno = INPUT_ERROR; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) - return gps_errno; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strncmp(s,"Start",5)) - return gps_errno; - - pos = ftell(inf); - n = 0; - while(strncmp(s,"End",3)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strstr(s,"Latitude")) - ++n; - } - fseek(inf,pos,0); - - if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) - return MEMORY_ERROR; - for(i=0;iprot = type; - } - - - for(i=0;iprot = type; + } + + + for (i=0; iprot = type; - } - - for(i=0;idst = f; - } - - return n; + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 i; + long pos; + int32 ret; + double f; + char* p; + + gps_errno = INPUT_ERROR; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Waypoints Type: %d",(int*)&type)!=1) { + return gps_errno; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strncmp(s,"Start",5)) { + return gps_errno; + } + + pos = ftell(inf); + n = 0; + while (strncmp(s,"End",3)) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strstr(s,"Latitude")) { + ++n; + } + } + fseek(inf,pos,0); + + if (!(*way=(GPS_PWay*)malloc(n*sizeof(GPS_PWay*)))) { + return MEMORY_ERROR; + } + for (i=0; iprot = type; + } + + for (i=0; idst = f; + } + + return n; } @@ -608,36 +720,42 @@ int32 GPS_Input_Get_Proximity(GPS_PWay **way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D100(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D100(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - return 1; + char s[GPS_ARB_LEN]; + char* p; + + double f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + return 1; } @@ -651,45 +769,53 @@ static int32 GPS_Input_Get_D100(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D101(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D101(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - return 1; + char s[GPS_ARB_LEN]; + char* p; + + double f; + int32 d; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + return 1; } @@ -703,9 +829,9 @@ static int32 GPS_Input_Get_D101(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D102(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D102(GPS_PWay* way, FILE* inf) { - return GPS_Input_Get_D101(way,inf); + return GPS_Input_Get_D101(way,inf); } @@ -719,52 +845,62 @@ static int32 GPS_Input_Get_D102(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D103(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D103(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->dspl = d; - - return 1; + char s[GPS_ARB_LEN]; + char* p; + + double f; + int32 d; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->dspl = d; + + return 1; } @@ -778,9 +914,9 @@ static int32 GPS_Input_Get_D103(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D104(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D104(GPS_PWay* way, FILE* inf) { - return GPS_Input_Get_D103(way,inf); + return GPS_Input_Get_D103(way,inf); } @@ -794,41 +930,48 @@ static int32 GPS_Input_Get_D104(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D105(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D105(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->wpt_ident,s); - - return 1; + char s[GPS_ARB_LEN]; + char* p; + + double f; + int32 d; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->wpt_ident,s); + + return 1; } @@ -842,60 +985,72 @@ static int32 GPS_Input_Get_D105(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D106(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D106(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((char *)(*way)->subclass,13,s); - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->wpt_ident,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->lnk_ident,s); - - return 1; + char s[GPS_ARB_LEN]; + char* p; + + double f; + int32 d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((char*)(*way)->subclass,13,s); + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->wpt_ident,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->lnk_ident,s); + + return 1; } @@ -909,25 +1064,28 @@ static int32 GPS_Input_Get_D106(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D107(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D107(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - int32 d; - int32 ret; - - if((ret=GPS_Input_Get_D103(way,inf))<0) - return ret; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->colour = d; - - return 1; + char s[GPS_ARB_LEN]; + char* p; + + int32 d; + int32 ret; + + if ((ret=GPS_Input_Get_D103(way,inf))<0) { + return ret; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->colour = d; + + return 1; } @@ -941,131 +1099,149 @@ static int32 GPS_Input_Get_D107(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D108(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - double f; - int32 d; - int32 xc; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->ident,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->colour = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->dspl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + char s[GPS_ARB_LEN]; + char* p; + double f; + int32 d; + int32 xc; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->ident,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->colour = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->dspl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->alt = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->dpth = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = d; + xc = d; + + if (xc>=0x80 && xc<=0x85) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((char*)(*way)->subclass,18,s); + } else { + GPS_Util_Put_Short((*way)->subclass,0); + GPS_Util_Put_Int((*way)->subclass+2,0); + GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); + } + + if (!xc) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->cmnt,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->dpth = f; + if (xc>=0x40 && xc<=0x46) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->facility,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->city,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (xc==0x83) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->addr,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + if (xc==0x82) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->cross_road,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = d; - xc = d; - - if(xc>=0x80 && xc<=0x85) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((char *)(*way)->subclass,18,s); - } - else - { - GPS_Util_Put_Short((*way)->subclass,0); - GPS_Util_Put_Int((*way)->subclass+2,0); - GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); - GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); - GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); - } - - if(!xc) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->cmnt,s); - } - - if(xc>=0x40 && xc<=0x46) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->facility,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->city,s); - } - - if(xc==0x83) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->addr,s); - } - - if(xc==0x82) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->cross_road,s); - } - - return 1; + return 1; } @@ -1080,131 +1256,149 @@ static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf) ** @return [int32] number of entries ** D109's and D110's are so similar, we handle both with the same function. ************************************************************************/ -static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf, int protonum) +static int32 GPS_Input_Get_D109(GPS_PWay* way, FILE* inf, int protonum) { - char s[GPS_ARB_LEN]; - char *p; - double f; - int32 d; - int32 xc; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->ident,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->colour = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->dspl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + char s[GPS_ARB_LEN]; + char* p; + double f; + int32 d; + int32 xc; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->ident,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->colour = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->dspl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->alt = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->dpth = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = d; + xc = d; + + if (xc>=0x80 && xc<=0x85) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((char*)(*way)->subclass,18,s); + } else { + GPS_Util_Put_Short((*way)->subclass,0); + GPS_Util_Put_Int((*way)->subclass+2,0); + GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); + } + + if (!xc) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->cmnt,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->dpth = f; + if (xc>=0x40 && xc<=0x46) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->facility,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->city,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (xc==0x83) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->addr,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + if (xc==0x82) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->cross_road,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = d; - xc = d; - - if(xc>=0x80 && xc<=0x85) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((char *)(*way)->subclass,18,s); - } - else - { - GPS_Util_Put_Short((*way)->subclass,0); - GPS_Util_Put_Int((*way)->subclass+2,0); - GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); - GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); - GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); - } - - if(!xc) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->cmnt,s); - } - - if(xc>=0x40 && xc<=0x46) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->facility,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->city,s); - } - - if(xc==0x83) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->addr,s); - } - - if(xc==0x82) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->cross_road,s); - } - - return 1; + return 1; } @@ -1217,75 +1411,87 @@ static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf, int protonum) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D150(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D150(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - int32 cl=0; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = cl = d; - - if(cl != 4) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + char s[GPS_ARB_LEN]; + char* p; + + double f; + int32 d; + int32 cl=0; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = cl = d; + + if (cl != 4) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->city,24,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->city,24,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->name,30,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + GPS_Input_Load_String((*way)->name,30,s); + } - if(!cl) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + if (!cl) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->alt = d; + } - return 1; + return 1; } @@ -1299,75 +1505,87 @@ static int32 GPS_Input_Get_D150(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D151(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D151(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - int32 cl=0; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = cl = d; - - if(cl != 2) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + char s[GPS_ARB_LEN]; + char* p; + + double f; + int32 d; + int32 cl=0; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = cl = d; + + if (cl != 2) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->city,24,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->city,24,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->name,30,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + GPS_Input_Load_String((*way)->name,30,s); + } - if(!cl) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + if (!cl) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->alt = d; + } - return 1; + return 1; } @@ -1380,9 +1598,9 @@ static int32 GPS_Input_Get_D151(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D152(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D152(GPS_PWay* way, FILE* inf) { - return GPS_Input_Get_D150(way,inf); + return GPS_Input_Get_D150(way,inf); } @@ -1396,82 +1614,96 @@ static int32 GPS_Input_Get_D152(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D154(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D154(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - int32 cl=0; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = cl = d; - - if(cl != 4 && cl != 8) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + char s[GPS_ARB_LEN]; + char* p; + + double f; + int32 d; + int32 cl=0; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = cl = d; + + if (cl != 4 && cl != 8) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->city,24,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->city,24,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->name,30,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + GPS_Input_Load_String((*way)->name,30,s); + } - if(!cl) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + if (!cl) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; } + (*way)->alt = d; + } - return 1; + return 1; } @@ -1485,89 +1717,105 @@ static int32 GPS_Input_Get_D154(GPS_PWay *way, FILE *inf) ** ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D155(GPS_PWay *way, FILE *inf) +static int32 GPS_Input_Get_D155(GPS_PWay* way, FILE* inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - int32 cl=0; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->dspl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = cl = d; - - if(cl != 4 && cl != 8) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + char s[GPS_ARB_LEN]; + char* p; + + double f; + int32 d; + int32 cl=0; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->dspl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = cl = d; + + if (cl != 4 && cl != 8) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->city,24,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->city,24,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->name,30,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + GPS_Input_Load_String((*way)->name,30,s); + } - if(!cl) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + if (!cl) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_errno; } + (*way)->alt = d; + } - return 1; + return 1; } @@ -1582,92 +1830,99 @@ static int32 GPS_Input_Get_D155(GPS_PWay *way, FILE *inf) ** @return [int32] number of entries ************************************************************************/ -int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf) +int32 GPS_Input_Get_Track(GPS_PTrack** trk, FILE* inf) { - char s[GPS_ARB_LEN]; - int32 n; - int32 i; - long pos; - int32 a; - int32 d; - - gps_errno = INPUT_ERROR; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strncmp(s,"Track log",9)) - return gps_errno; - - if(sscanf(s,"Track log %d%d",(int *)&a,(int *)&d)!=2) - return INPUT_ERROR; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strncmp(s,"Start",5)) - return gps_errno; - - pos = ftell(inf); - n = 0; - while(strncmp(s,"End",3)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strstr(s,"Latitude")) - ++n; - if(strstr(s,"Header")) - ++n; - } - fseek(inf,pos,0); - - - if(!(*trk=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack *)))) - return MEMORY_ERROR; - for(i=0;itnew=1; + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + } else { + (*trk)[i]->tnew=0; + } + + switch (d) { + case pD300: + GPS_Input_Get_D300(&((*trk)[i]),inf,s); + break; + case pD301: + GPS_Input_Get_D301(&((*trk)[i]),inf,s); + break; default: - return INPUT_ERROR; - } - - - - for(i=0;itnew=1; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - } - else - (*trk)[i]->tnew=0; - - switch(d) - { - case pD300: - GPS_Input_Get_D300(&((*trk)[i]),inf,s); - break; - case pD301: - GPS_Input_Get_D301(&((*trk)[i]),inf,s); - break; - default: - return PROTOCOL_ERROR; - } - } - - return n; + return PROTOCOL_ERROR; + } + } + + return n; } @@ -1684,68 +1939,71 @@ int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf) ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_Track301(GPS_PTrack **trk, FILE *inf, int32 type, - int32 n) +static int32 GPS_Input_Get_Track301(GPS_PTrack** trk, FILE* inf, int32 type, + int32 n) { - char s[GPS_ARB_LEN]; - int32 i; - char *p; - int32 x; - - for(i=0;iishdr = 1; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*trk)[i]->trk_ident,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&x)!=1) - return INPUT_ERROR; - (*trk)[i]->dspl = x; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&x)!=1) - return INPUT_ERROR; - (*trk)[i]->colour = x; - - continue; - } - - (*trk)[i]->ishdr = 0; - - if(!strcmp(s,"New track")) - { - (*trk)[i]->tnew=1; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - } - else - (*trk)[i]->tnew=0; - - switch(type) - { - case pD300: - GPS_Input_Get_D300(&((*trk)[i]),inf,s); - break; - case pD301: - GPS_Input_Get_D301(&((*trk)[i]),inf,s); - break; - default: - return PROTOCOL_ERROR; - } - } - - return n; + char s[GPS_ARB_LEN]; + int32 i; + char* p; + int32 x; + + for (i=0; iishdr = 1; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*trk)[i]->trk_ident,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&x)!=1) { + return INPUT_ERROR; + } + (*trk)[i]->dspl = x; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&x)!=1) { + return INPUT_ERROR; + } + (*trk)[i]->colour = x; + + continue; + } + + (*trk)[i]->ishdr = 0; + + if (!strcmp(s,"New track")) { + (*trk)[i]->tnew=1; + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + } else { + (*trk)[i]->tnew=0; + } + + switch (type) { + case pD300: + GPS_Input_Get_D300(&((*trk)[i]),inf,s); + break; + case pD301: + GPS_Input_Get_D301(&((*trk)[i]),inf,s); + break; + default: + return PROTOCOL_ERROR; + } + } + + return n; } @@ -1761,28 +2019,32 @@ static int32 GPS_Input_Get_Track301(GPS_PTrack **trk, FILE *inf, int32 type, ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D300(GPS_PTrack *trk, FILE *inf, char *s) +static int32 GPS_Input_Get_D300(GPS_PTrack* trk, FILE* inf, char* s) { - char *p; - double f; - - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - (*trk)->Time = 0; - - return 1; + char* p; + double f; + + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + (*trk)->Time = 0; + + return 1; } @@ -1798,42 +2060,50 @@ static int32 GPS_Input_Get_D300(GPS_PTrack *trk, FILE *inf, char *s) ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_D301(GPS_PTrack *trk, FILE *inf, char *s) +static int32 GPS_Input_Get_D301(GPS_PTrack* trk, FILE* inf, char* s) { - char *p; - double f; - - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - (*trk)->Time = 0; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->alt = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->dpth = f; - - return 1; + char* p; + double f; + + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + (*trk)->Time = 0; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->alt = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->dpth = f; + + return 1; } @@ -1848,199 +2118,240 @@ static int32 GPS_Input_Get_D301(GPS_PTrack *trk, FILE *inf, char *s) ** @return [int32] number of entries ************************************************************************/ -int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf) +int32 GPS_Input_Get_Route(GPS_PWay** way, FILE* inf) { - char s[GPS_ARB_LEN]; - int32 n; - int32 type; - int32 rtype=0; - int32 atype=0; - int32 i; - long pos; - int32 ret; - char *p; - int32 d; - - gps_errno = INPUT_ERROR; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Route log %d",(int *)&atype)!=1) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - - switch(atype) - { - case pA200: - break; - case pA201: - return GPS_Input_Get_Route201(way,inf); + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 rtype=0; + int32 atype=0; + int32 i; + long pos; + int32 ret; + char* p; + int32 d; + + gps_errno = INPUT_ERROR; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Route log %d",(int*)&atype)!=1) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + switch (atype) { + case pA200: + break; + case pA201: + return GPS_Input_Get_Route201(way,inf); + default: + GPS_Error("GPS_Input_Get_Route: Unknown protocol"); + return PROTOCOL_ERROR; + } + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Route Type: %d",(int*)&rtype)!=1) { + return gps_errno; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Waypoints Type: %d",(int*)&type)!=1) { + return gps_errno; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strncmp(s,"Start",5)) { + return gps_errno; + } + + pos = ftell(inf); + n = 1; + while (strncmp(s,"End",3)) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strstr(s,"Latitude") || strstr(s,"Route")) { + ++n; + } + } + fseek(inf,0L,0); + + + if (!(*way=(GPS_PWay*)malloc(n*sizeof(GPS_PWay*)))) { + return MEMORY_ERROR; + } + for (i=0; iprot = type; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + for (i=0; irte_prot = rtype; + (*way)[i]->islink = 0; + if (strstr(s,"Route")) { + (*way)[i]->isrte = 1; + switch (rtype) { + case 200: + p = strchr(s,':'); + p = strchr(p+1,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_num=d; + break; + case 201: + p = strchr(s,':'); + p = strchr(p+1,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_num=d; + ++p; + GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+2); + break; + case 202: + p = strchr(s,':'); + p = strchr(p+1,':'); + GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); + break; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + continue; + } else { + (*way)[i]->isrte=0; + } + + if (strstr(s,"End")) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + continue; + } + + + switch (type) { + case 100: + ret = GPS_Input_Get_D100(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 101: + ret = GPS_Input_Get_D101(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 102: + ret = GPS_Input_Get_D102(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 103: + ret = GPS_Input_Get_D103(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 104: + ret = GPS_Input_Get_D104(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 105: + ret = GPS_Input_Get_D105(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 106: + ret = GPS_Input_Get_D106(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 107: + ret = GPS_Input_Get_D107(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 108: + ret = GPS_Input_Get_D108(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 150: + ret = GPS_Input_Get_D150(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 151: + ret = GPS_Input_Get_D151(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 152: + ret = GPS_Input_Get_D152(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 154: + ret = GPS_Input_Get_D154(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 155: + ret = GPS_Input_Get_D155(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; default: - GPS_Error("GPS_Input_Get_Route: Unknown protocol"); - return PROTOCOL_ERROR; - } - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Route Type: %d",(int *)&rtype)!=1) - return gps_errno; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) - return gps_errno; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strncmp(s,"Start",5)) - return gps_errno; - - pos = ftell(inf); - n = 1; - while(strncmp(s,"End",3)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strstr(s,"Latitude") || strstr(s,"Route")) - ++n; - } - fseek(inf,0L,0); - - - if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) - return MEMORY_ERROR; - for(i=0;iprot = type; - } - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - - for(i=0;irte_prot = rtype; - (*way)[i]->islink = 0; - if(strstr(s,"Route")) - { - (*way)[i]->isrte = 1; - switch(rtype) - { - case 200: - p = strchr(s,':'); - p = strchr(p+1,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_num=d; - break; - case 201: - p = strchr(s,':'); - p = strchr(p+1,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_num=d; - ++p; - GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+2); - break; - case 202: - p = strchr(s,':'); - p = strchr(p+1,':'); - GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); - break; - } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - continue; - } - else - (*way)[i]->isrte=0; - - if(strstr(s,"End")) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - - continue; - } - - - switch(type) - { - case 100: - ret = GPS_Input_Get_D100(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 101: - ret = GPS_Input_Get_D101(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 102: - ret = GPS_Input_Get_D102(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 103: - ret = GPS_Input_Get_D103(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 104: - ret = GPS_Input_Get_D104(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 105: - ret = GPS_Input_Get_D105(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 106: - ret = GPS_Input_Get_D106(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 107: - ret = GPS_Input_Get_D107(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 108: - ret = GPS_Input_Get_D108(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 150: - ret = GPS_Input_Get_D150(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 151: - ret = GPS_Input_Get_D151(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 152: - ret = GPS_Input_Get_D152(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 154: - ret = GPS_Input_Get_D154(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 155: - ret = GPS_Input_Get_D155(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - default: - GPS_Error("Input_Get_Waypoints: Unknown protocol"); - return PROTOCOL_ERROR; - } - - } - - return n; + GPS_Error("Input_Get_Waypoints: Unknown protocol"); + return PROTOCOL_ERROR; + } + + } + + return n; } @@ -2055,208 +2366,243 @@ int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf) ** @return [int32] number of entries ************************************************************************/ -static int32 GPS_Input_Get_Route201(GPS_PWay **way, FILE *inf) +static int32 GPS_Input_Get_Route201(GPS_PWay** way, FILE* inf) { - char s[GPS_ARB_LEN]; - int32 n; - int32 type; - int32 rtype; - int32 i; - long pos; - int32 ret; - char *p; - int32 d; - - gps_errno = INPUT_ERROR; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Route Type: %d",(int *)&rtype)!=1) - return gps_errno; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) - return gps_errno; - - - pos = ftell(inf); - n = 1; - while(strncmp(s,"End",3)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strstr(s,"Latitude") || strstr(s,"Route") || strstr(s,"Link Class")) - ++n; - } - fseek(inf,0L,0); - - if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) - return MEMORY_ERROR; - for(i=0;iprot = type; - } - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - - for(i=0;irte_prot = rtype; - (*way)[i]->islink = 0; - if(strstr(s,"Route")) - { - (*way)[i]->isrte = 1; - switch(rtype) - { - case 200: - p = strchr(s,':'); - p = strchr(p+1,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_num=d; - break; - case 201: - p = strchr(s,':'); - p = strchr(p+1,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_num=d; - p = strchr(p+1,':'); - GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+1); - break; - case 202: - p = strchr(s,':'); - p = strchr(p+1,':'); - GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); - break; - } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - continue; - } - else - (*way)[i]->isrte=0; - - - - if(strstr(s,"Link Class")) - { - (*way)[i]->islink = 1; - - p = strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_link_class=d; - - if(!((*way)[i]->rte_link_class==3 || (*way)[i]->rte_link_class - ==0xff)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)[i]->rte_link_subclass,18,s); - } - else - { - GPS_Util_Put_Short((UC *)(*way)[i]->rte_link_subclass,0); - GPS_Util_Put_Int((UC *)(*way)[i]->rte_link_subclass+2,0); - GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+6, - 0xffffffff); - GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+10, - 0xffffffff); - GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+14, - 0xffffffff); - } - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)[i]->rte_link_ident,s); - - continue; - } - else - (*way)[i]->islink=0; - - - if(strstr(s,"End")) - { - GPS_Error("Get_Route201: Unexpected End"); - return INPUT_ERROR; - } - - - switch(type) - { - case 100: - ret = GPS_Input_Get_D100(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 101: - ret = GPS_Input_Get_D101(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 102: - ret = GPS_Input_Get_D102(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 103: - ret = GPS_Input_Get_D103(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 104: - ret = GPS_Input_Get_D104(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 105: - ret = GPS_Input_Get_D105(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 106: - ret = GPS_Input_Get_D106(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 107: - ret = GPS_Input_Get_D107(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 108: - ret = GPS_Input_Get_D108(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 150: - ret = GPS_Input_Get_D150(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 151: - ret = GPS_Input_Get_D151(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 152: - ret = GPS_Input_Get_D152(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 154: - ret = GPS_Input_Get_D154(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 155: - ret = GPS_Input_Get_D155(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - default: - GPS_Error("Input_Get_Waypoints: Unknown protocol"); - return PROTOCOL_ERROR; - } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - } - - return n; + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 rtype; + int32 i; + long pos; + int32 ret; + char* p; + int32 d; + + gps_errno = INPUT_ERROR; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Route Type: %d",(int*)&rtype)!=1) { + return gps_errno; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Waypoints Type: %d",(int*)&type)!=1) { + return gps_errno; + } + + + pos = ftell(inf); + n = 1; + while (strncmp(s,"End",3)) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strstr(s,"Latitude") || strstr(s,"Route") || strstr(s,"Link Class")) { + ++n; + } + } + fseek(inf,0L,0); + + if (!(*way=(GPS_PWay*)malloc(n*sizeof(GPS_PWay*)))) { + return MEMORY_ERROR; + } + for (i=0; iprot = type; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + for (i=0; irte_prot = rtype; + (*way)[i]->islink = 0; + if (strstr(s,"Route")) { + (*way)[i]->isrte = 1; + switch (rtype) { + case 200: + p = strchr(s,':'); + p = strchr(p+1,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_num=d; + break; + case 201: + p = strchr(s,':'); + p = strchr(p+1,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_num=d; + p = strchr(p+1,':'); + GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+1); + break; + case 202: + p = strchr(s,':'); + p = strchr(p+1,':'); + GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); + break; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + continue; + } else { + (*way)[i]->isrte=0; + } + + + + if (strstr(s,"Link Class")) { + (*way)[i]->islink = 1; + + p = strchr(s,':'); + if (sscanf(p+1,"%d",(int*)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_link_class=d; + + if (!((*way)[i]->rte_link_class==3 || (*way)[i]->rte_link_class + ==0xff)) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)[i]->rte_link_subclass,18,s); + } else { + GPS_Util_Put_Short((UC*)(*way)[i]->rte_link_subclass,0); + GPS_Util_Put_Int((UC*)(*way)[i]->rte_link_subclass+2,0); + GPS_Util_Put_Uint((UC*)(*way)[i]->rte_link_subclass+6, + 0xffffffff); + GPS_Util_Put_Uint((UC*)(*way)[i]->rte_link_subclass+10, + 0xffffffff); + GPS_Util_Put_Uint((UC*)(*way)[i]->rte_link_subclass+14, + 0xffffffff); + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)[i]->rte_link_ident,s); + + continue; + } else { + (*way)[i]->islink=0; + } + + + if (strstr(s,"End")) { + GPS_Error("Get_Route201: Unexpected End"); + return INPUT_ERROR; + } + + + switch (type) { + case 100: + ret = GPS_Input_Get_D100(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 101: + ret = GPS_Input_Get_D101(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 102: + ret = GPS_Input_Get_D102(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 103: + ret = GPS_Input_Get_D103(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 104: + ret = GPS_Input_Get_D104(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 105: + ret = GPS_Input_Get_D105(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 106: + ret = GPS_Input_Get_D106(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 107: + ret = GPS_Input_Get_D107(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 108: + ret = GPS_Input_Get_D108(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 150: + ret = GPS_Input_Get_D150(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 151: + ret = GPS_Input_Get_D151(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 152: + ret = GPS_Input_Get_D152(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 154: + ret = GPS_Input_Get_D154(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 155: + ret = GPS_Input_Get_D155(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + default: + GPS_Error("Input_Get_Waypoints: Unknown protocol"); + return PROTOCOL_ERROR; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + } + + return n; } diff --git a/gpsbabel/jeeps/gpsinput.h b/gpsbabel/jeeps/gpsinput.h index 5b0e41615..78c7d73f9 100644 --- a/gpsbabel/jeeps/gpsinput.h +++ b/gpsbabel/jeeps/gpsinput.h @@ -9,11 +9,11 @@ extern "C" #include "gps.h" -int32 GPS_Input_Get_Almanac(GPS_PAlmanac **alm, FILE *inf); -int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf); -int32 GPS_Input_Get_Proximity(GPS_PWay **way, FILE *inf); -int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf); -int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf); + int32 GPS_Input_Get_Almanac(GPS_PAlmanac** alm, FILE* inf); + int32 GPS_Input_Get_Waypoint(GPS_PWay** way, FILE* inf); + int32 GPS_Input_Get_Proximity(GPS_PWay** way, FILE* inf); + int32 GPS_Input_Get_Track(GPS_PTrack** trk, FILE* inf); + int32 GPS_Input_Get_Route(GPS_PWay** way, FILE* inf); #endif diff --git a/gpsbabel/jeeps/gpslibusb.c b/gpsbabel/jeeps/gpslibusb.c index ef82454b3..acb732c78 100644 --- a/gpsbabel/jeeps/gpslibusb.c +++ b/gpsbabel/jeeps/gpslibusb.c @@ -47,112 +47,123 @@ #define TMOUT_B 5000 /* Milliseconds to timeout bulk pipe access. */ typedef struct { - struct usb_bus *busses; - unsigned product_id; + struct usb_bus* busses; + unsigned product_id; } libusb_unit_data; -/* +/* * TODO: this should all be moved into libusbdata in gpslibusb.h, * allocated once here in gusb_start, and deallocated at the end. */ static int gusb_intr_in_ep; static int gusb_bulk_out_ep; static int gusb_bulk_in_ep; -static gusb_llops_t libusb_llops; -static usb_dev_handle *udev; -static int garmin_usb_scan(libusb_unit_data *, int); -static const gdx_info *gdx; +static usb_dev_handle* udev; +static int garmin_usb_scan(libusb_unit_data*, int); +static const gdx_info* gdx; + +static int gusb_libusb_get(garmin_usb_packet* ibuf, size_t sz); +static int gusb_libusb_get_bulk(garmin_usb_packet* ibuf, size_t sz); +static int gusb_teardown(gpsdevh* dh); +static int gusb_libusb_send(const garmin_usb_packet* opkt, size_t sz); +static gusb_llops_t libusb_llops = { + gusb_libusb_get, + gusb_libusb_get_bulk, + gusb_libusb_send, + gusb_teardown, + 0 +}; #if __linux__ static -char ** os_get_garmin_mountpoints() +char** os_get_garmin_mountpoints() { - // Hacked for testing. - return NULL; + // Hacked for testing. + return NULL; } #elif __APPLE__ // In fantasy land, we'd query iokit for enumerated devices of the Garmin // vendor ID and match that against the mounted device table. In practical // matters, that's crazy complex and this is where the devices seems to always // get mounted... -char ** os_get_garmin_mountpoints() +char** os_get_garmin_mountpoints() { - char **dlist = xcalloc(2, sizeof *dlist); - dlist[0] = xstrdup("/Volumes/GARMIN"); - dlist[1] = NULL; - return dlist; + char** dlist = (char**) xcalloc(2, sizeof *dlist); + dlist[0] = xstrdup("/Volumes/GARMIN"); + dlist[1] = NULL; + return dlist; } #else -char ** os_get_garmin_mountpoints() +char** os_get_garmin_mountpoints() { - return NULL; + return NULL; } #endif static int -gusb_libusb_send(const garmin_usb_packet *opkt, size_t sz) +gusb_libusb_send(const garmin_usb_packet* opkt, size_t sz) { - int r; - r = usb_bulk_write(udev, gusb_bulk_out_ep, (char *)(void *)opkt->dbuf, sz, TMOUT_B); - - if (r != (int) sz) { - fprintf(stderr, "Bad cmdsend r %d sz %ld\n", r, (unsigned long) sz); - if (r < 0) { - fatal("usb_bulk_write failed. '%s'\n", - usb_strerror()); - } - } - - return r; + int r; + r = usb_bulk_write(udev, gusb_bulk_out_ep, (char*)(void*)opkt->dbuf, sz, TMOUT_B); + + if (r != (int) sz) { + fprintf(stderr, "Bad cmdsend r %d sz %ld\n", r, (unsigned long) sz); + if (r < 0) { + fatal("usb_bulk_write failed. '%s'\n", + usb_strerror()); + } + } + + return r; } static int -gusb_libusb_get(garmin_usb_packet *ibuf, size_t sz) +gusb_libusb_get(garmin_usb_packet* ibuf, size_t sz) { - unsigned char *buf = &ibuf->dbuf[0]; - int r = -1; + unsigned char* buf = &ibuf->dbuf[0]; + int r = -1; - r = usb_interrupt_read(udev, gusb_intr_in_ep, (char *) buf, sz, TMOUT_I); - return r; + r = usb_interrupt_read(udev, gusb_intr_in_ep, (char*) buf, sz, TMOUT_I); + return r; } static int -gusb_libusb_get_bulk(garmin_usb_packet *ibuf, size_t sz) +gusb_libusb_get_bulk(garmin_usb_packet* ibuf, size_t sz) { - int r; - unsigned char *buf = &ibuf->dbuf[0]; + int r; + unsigned char* buf = &ibuf->dbuf[0]; - r = usb_bulk_read(udev, gusb_bulk_in_ep, (char *) buf, sz, TMOUT_B); + r = usb_bulk_read(udev, gusb_bulk_in_ep, (char*) buf, sz, TMOUT_B); - return r; + return r; } static int -gusb_teardown(gpsdevh *dh) +gusb_teardown(gpsdevh* dh) { - if (udev) { - usb_release_interface(udev, 0); - usb_close(udev); - /* In the worst case, we leak a little bit of memory - * when called via the atexit handler. That's not too - * terrible. - */ - if (NULL != dh) { - xfree(dh); - } - udev = NULL; - } - return 0; + if (udev) { + usb_release_interface(udev, 0); + usb_close(udev); + /* In the worst case, we leak a little bit of memory + * when called via the atexit handler. That's not too + * terrible. + */ + if (NULL != dh) { + xfree(dh); + } + udev = NULL; + } + return 0; } static void gusb_atexit_teardown(void) { - gusb_teardown(NULL); + gusb_teardown(NULL); } @@ -164,21 +175,21 @@ gusb_atexit_teardown(void) * set. After a reset, the toggles both match. So we tear through the * conversation and life is good. Unfortunately, the second time through, * if we had an odd number of transactions in the previous conversation, - * we send a configuration set and reset the toggle on the HCI but the + * we send a configuration set and reset the toggle on the HCI but the * toggle on the device's end of the pipe is now out of whack which means * that the subsequent transaction will hang. - * + * * This isn't a problem in Windows since the configuration set is done only * once there. - * + * * This code has been tested in loops of 1000 cycles on Linux and OS/X and * it seems to cure this at a mere cost of complexity and startup time. I'll * be delighted when all the firmware gets revved and updated and we can * remove this. * - * 9/2008 But wait, there's more. The very toggle reset that we *had* to + * 9/2008 But wait, there's more. The very toggle reset that we *had* to * implement in 2006 to make non-Windows OSes work actually locks up verion - * 2.70 of the Venture HC. On that model, the second product request + * 2.70 of the Venture HC. On that model, the second product request * (you know, the one that we *use*, locks that device's protocol stack * after the RET2INTR that immediately follows the REQBLK (and why is it * telling us to go into bulk mode followed by an immeidate EOF, anyway?) @@ -190,273 +201,284 @@ gusb_atexit_teardown(void) * * Grrrr! */ -unsigned +unsigned gusb_reset_toggles(void) { - static const char oinit[12] = - {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; - static const char oid[12] = - {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; - garmin_usb_packet iresp; - int t; - unsigned rv = 0; - - /* Start off with three session starts. - * #1 resets the bulk out toggle. It may not make it to the device. - * #2 resets the the intr in toggle. It will make it to the device - * since #1 reset the the bulk out toggle. The device will - * respond on the intr in pipe which will clear its toggle. - * #3 actually starts the session now that the above are both clear. - */ - - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - - t = 10; - while(1) { - le_write16(&iresp.gusb_pkt.pkt_id, 0); - le_write32(&iresp.gusb_pkt.datasz, 0); - le_write32(&iresp.gusb_pkt.databuf, 0); - - gusb_cmd_get(&iresp, sizeof(iresp)); - - if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && - (le_read32(iresp.gusb_pkt.datasz) == 4)) { - break; - } - if (t-- <= 0) { - fatal("Could not start session in a reasonable number of tries.\n"); - } - } - - /* - * Now that the bulk out and intr in packets are good, we send - * a product ID. On devices that respond totally on the intr - * pipe, this does nothing interesting, but on devices that respon - * on the bulk pipe this will reset the toggles on the bulk in. - */ - - t = 10; - gusb_cmd_send((const garmin_usb_packet *) oid, sizeof(oid)); - while(1) { - le_write16(&iresp.gusb_pkt.pkt_id, 0); - le_write32(&iresp.gusb_pkt.datasz, 0); - le_write32(&iresp.gusb_pkt.databuf, 0); - - gusb_cmd_get(&iresp, sizeof(iresp)); - - if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { - rv = le_read16(iresp.gusb_pkt.databuf+0); - } - - if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return rv; - if (t-- <= 0) { - fatal("Could not start session in a reasonable number of tries.\n"); - } - } - return 0; + static const char oinit[12] = + {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; + static const char oid[12] = + {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int t; + unsigned rv = 0; + + /* Start off with three session starts. + * #1 resets the bulk out toggle. It may not make it to the device. + * #2 resets the the intr in toggle. It will make it to the device + * since #1 reset the the bulk out toggle. The device will + * respond on the intr in pipe which will clear its toggle. + * #3 actually starts the session now that the above are both clear. + */ + + gusb_cmd_send((const garmin_usb_packet*) oinit, sizeof(oinit)); + gusb_cmd_send((const garmin_usb_packet*) oinit, sizeof(oinit)); + gusb_cmd_send((const garmin_usb_packet*) oinit, sizeof(oinit)); + + t = 10; + while (1) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + break; + } + if (t-- <= 0) { + fatal("Could not start session in a reasonable number of tries.\n"); + } + } + + /* + * Now that the bulk out and intr in packets are good, we send + * a product ID. On devices that respond totally on the intr + * pipe, this does nothing interesting, but on devices that respon + * on the bulk pipe this will reset the toggles on the bulk in. + */ + + t = 10; + gusb_cmd_send((const garmin_usb_packet*) oid, sizeof(oid)); + while (1) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_get(&iresp, sizeof(iresp)); + + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { + rv = le_read16(iresp.gusb_pkt.databuf+0); + } + + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) { + return rv; + } + if (t-- <= 0) { + fatal("Could not start session in a reasonable number of tries.\n"); + } + } + return 0; } void -garmin_usb_start(struct usb_device *dev, libusb_unit_data *lud) +garmin_usb_start(struct usb_device* dev, libusb_unit_data* lud) { - int i; + int i; - if (udev) return; - udev = usb_open(dev); - atexit(gusb_atexit_teardown); + if (udev) { + return; + } + udev = usb_open(dev); + atexit(gusb_atexit_teardown); - if (!udev) { fatal("usb_open failed: %s\n", usb_strerror()); } - /* - * Hrmph. No iManufacturer or iProduct headers.... - */ + if (!udev) { + fatal("usb_open failed: %s\n", usb_strerror()); + } + /* + * Hrmph. No iManufacturer or iProduct headers.... + */ #if __APPLE__ - // On Leopard, if we don't do an explicit set_configuration, some - // devices will work only the first time after a reset. - if (usb_set_configuration(udev, 1) < 0) { - fatal("usb_set_configuration failed: %s\n", usb_strerror()); - }; + // On Leopard, if we don't do an explicit set_configuration, some + // devices will work only the first time after a reset. + if (usb_set_configuration(udev, 1) < 0) { + fatal("usb_set_configuration failed: %s\n", usb_strerror()); + }; #endif #if 0 - if (usb_set_configuration(udev, 1) < 0) { + if (usb_set_configuration(udev, 1) < 0) { #if __linux__ - char drvnm[128]; - drvnm[0] = 0; - /* - * Most Linux distributions ship a slightly broken - * kernel driver that bonds with the hardware. - */ - usb_get_driver_np(udev, 0, drvnm, sizeof(drvnm)-1); - fatal("usb_set_configuration failed, probably because kernel driver '%s'\n is blocking our access to the USB device.\n" - "For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html\n", drvnm); + char drvnm[128]; + drvnm[0] = 0; + /* + * Most Linux distributions ship a slightly broken + * kernel driver that bonds with the hardware. + */ + usb_get_driver_np(udev, 0, drvnm, sizeof(drvnm)-1); + fatal("usb_set_configuration failed, probably because kernel driver '%s'\n is blocking our access to the USB device.\n" + "For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html\n", drvnm); #else - fatal("usb_set_configuration failed: %s\n", usb_strerror()); + fatal("usb_set_configuration failed: %s\n", usb_strerror()); #endif - } + } #endif - if (usb_claim_interface(udev, 0) < 0) { - fatal("Claim interfaced failed: %s\n", usb_strerror()); - } - - libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; - - /* - * About 5% of the time on OS/X (Observed on 10.5.4 on Intel Imac - * with Venture HC) we get a dev with a valid vendor ID, but no - * associated configuration. I was unable to see a single instance - * of this on a 276, a 60CS, a 60CSx, an SP310, or an Edge 305, leading - * me to think this is some kind of bug in the Venture HC. - * - * Rather than crash, we at least print - * a nastygram. Experiments with retrying various USB ops brought - * no joy, so just call fatal and move on. - */ - if (!dev->config) { - fatal("Found USB device with no configuration.\n"); - } - - for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { - struct usb_endpoint_descriptor * ep; - ep = &dev->config->interface->altsetting->endpoint[i]; - - switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { + if (usb_claim_interface(udev, 0) < 0) { + fatal("Claim interfaced failed: %s\n", usb_strerror()); + } + + libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; + + /* + * About 5% of the time on OS/X (Observed on 10.5.4 on Intel Imac + * with Venture HC) we get a dev with a valid vendor ID, but no + * associated configuration. I was unable to see a single instance + * of this on a 276, a 60CS, a 60CSx, an SP310, or an Edge 305, leading + * me to think this is some kind of bug in the Venture HC. + * + * Rather than crash, we at least print + * a nastygram. Experiments with retrying various USB ops brought + * no joy, so just call fatal and move on. + */ + if (!dev->config) { + fatal("Found USB device with no configuration.\n"); + } + + for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { + struct usb_endpoint_descriptor* ep; + ep = &dev->config->interface->altsetting->endpoint[i]; + + switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { #define EA(x) x & USB_ENDPOINT_ADDRESS_MASK - case USB_ENDPOINT_TYPE_BULK: - if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - gusb_bulk_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; - else - gusb_bulk_out_ep = EA(ep->bEndpointAddress); - break; - case USB_ENDPOINT_TYPE_INTERRUPT: - if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - gusb_intr_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; - break; - } - } - - /* - * Zero is the configuration endpoint, so if we made it through - * that loop without non-zero values for all three, we're hosed. - */ - if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) { - lud->product_id = gusb_reset_toggles(); - switch (lud->product_id) { - // Search for "Venture HC" for more on this siliness.. - // It's a case instead of an 'if' becuase I have a - // feeling there are more affected models either - // on the market or on the way. - case 695: break; // Venture HC - case 941: break; // Venture HC, Japanese version. - case 957: break; // Legend H - case 285: break; // GPSMap 276C/4.80 - case 402: break; // GPSMap 396C/4.50 - case 1095: break; // GPS72H/2.30 - default: gusb_syncup(); - } - return; - } - - fatal("Could not identify endpoints on USB device.\n" - "Found endpoints Intr In 0x%x Bulk Out 0x%x Bulk In %0xx\n", - gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); + case USB_ENDPOINT_TYPE_BULK: + if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { + gusb_bulk_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; + } else { + gusb_bulk_out_ep = EA(ep->bEndpointAddress); + } + break; + case USB_ENDPOINT_TYPE_INTERRUPT: + if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { + gusb_intr_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; + } + break; + } + } + + /* + * Zero is the configuration endpoint, so if we made it through + * that loop without non-zero values for all three, we're hosed. + */ + if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) { + lud->product_id = gusb_reset_toggles(); + switch (lud->product_id) { + // Search for "Venture HC" for more on this siliness.. + // It's a case instead of an 'if' becuase I have a + // feeling there are more affected models either + // on the market or on the way. + case 695: + break; // Venture HC + case 941: + break; // Venture HC, Japanese version. + case 957: + break; // Legend H + case 285: + break; // GPSMap 276C/4.80 + case 402: + break; // GPSMap 396C/4.50 + case 1095: + break; // GPS72H/2.30 + default: + gusb_syncup(); + } + return; + } + + fatal("Could not identify endpoints on USB device.\n" + "Found endpoints Intr In 0x%x Bulk Out 0x%x Bulk In %0xx\n", + gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); } static -int garmin_usb_scan(libusb_unit_data *lud, int req_unit_number) +int garmin_usb_scan(libusb_unit_data* lud, int req_unit_number) { - int found_devices = 0; - struct usb_bus *bus; - - for (bus = lud->busses; bus; bus = bus->next) { - struct usb_device *dev; - - for (dev = bus->devices; dev; dev = dev->next) { - /* - * Exclude Mass Storage devices (CO, OR, Nuvi, etc.) - * from this scan. - * At least on Mac, bDeviceClass isn't - * USB_MASS_STORAGE as it should be (perhaps because - * the storage driver has already bound to it?) so - * we fondle only the proprietary class devices. - */ - if (dev->descriptor.idVendor == GARMIN_VID && - dev->config && - dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC ) { - if (req_unit_number < 0) { - garmin_usb_start(dev, lud); - /* - * It's important to call _close - * here since the bulk/intr models - * may have a "dangling" packet that - * needs to be drained. - */ - gusb_close(NULL); - } else - if (req_unit_number == found_devices) - garmin_usb_start(dev, lud); - found_devices++; - } - } - } - - if (req_unit_number < 0) { - gusb_list_units(); - exit (0); - } - - if (0 == found_devices) { - /* It's time for Plan B. The user told us to use - * Garmin Protocol in device "usb:" but it's possible - * that they're talking to one of the dozens of models - * that is wants to read and write GPX files on a - * mounted drive. Try that now. - */ - char **dlist = os_get_garmin_mountpoints(); - gdx = gdx_find_file(dlist); - if (gdx) return 1; - /* Plan C. */ - fatal("Found no Garmin USB devices.\n"); - } else { - return 1; + int found_devices = 0; + struct usb_bus* bus; + + for (bus = lud->busses; bus; bus = bus->next) { + struct usb_device* dev; + + for (dev = bus->devices; dev; dev = dev->next) { + /* + * Exclude Mass Storage devices (CO, OR, Nuvi, etc.) + * from this scan. + * At least on Mac, bDeviceClass isn't + * USB_MASS_STORAGE as it should be (perhaps because + * the storage driver has already bound to it?) so + * we fondle only the proprietary class devices. + */ + if (dev->descriptor.idVendor == GARMIN_VID && + dev->config && + dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC) { + if (req_unit_number < 0) { + garmin_usb_start(dev, lud); + /* + * It's important to call _close + * here since the bulk/intr models + * may have a "dangling" packet that + * needs to be drained. + */ + gusb_close(NULL); + } else if (req_unit_number == found_devices) { + garmin_usb_start(dev, lud); } + found_devices++; + } + } + } + + if (req_unit_number < 0) { + gusb_list_units(); + exit(0); + } + + if (0 == found_devices) { + /* It's time for Plan B. The user told us to use + * Garmin Protocol in device "usb:" but it's possible + * that they're talking to one of the dozens of models + * that is wants to read and write GPX files on a + * mounted drive. Try that now. + */ + char** dlist = os_get_garmin_mountpoints(); + gdx = gdx_find_file(dlist); + if (gdx) { + return 1; + } + /* Plan C. */ + fatal("Found no Garmin USB devices.\n"); + } else { + return 1; + } } -static gusb_llops_t libusb_llops = { - gusb_libusb_get, - gusb_libusb_get_bulk, - gusb_libusb_send, - gusb_teardown -}; int -gusb_init(const char *portname, gpsdevh **dh) +gusb_init(const char* portname, gpsdevh** dh) { - int req_unit_number = 0; - libusb_unit_data *lud = xcalloc(sizeof (libusb_unit_data), 1); + int req_unit_number = 0; + libusb_unit_data* lud = (libusb_unit_data*) xcalloc(sizeof(libusb_unit_data), 1); - *dh = (gpsdevh*) lud; + *dh = (gpsdevh*) lud; // usb_set_debug(99); - usb_init(); - gusb_register_ll(&libusb_llops); - - /* if "usb:N", read "N" to be the unit number. */ - if (strlen(portname) > 4) { - if (0 == strcmp(portname+4, "list")) { - req_unit_number = -1; - } else { - req_unit_number = atoi(portname + 4); - } - } - usb_find_busses(); - usb_find_devices(); - lud->busses = usb_get_busses(); - return garmin_usb_scan(lud, req_unit_number); + usb_init(); + gusb_register_ll(&libusb_llops); + + /* if "usb:N", read "N" to be the unit number. */ + if (strlen(portname) > 4) { + if (0 == strcmp(portname+4, "list")) { + req_unit_number = -1; + } else { + req_unit_number = atoi(portname + 4); + } + } + usb_find_busses(); + usb_find_devices(); + lud->busses = usb_get_busses(); + return garmin_usb_scan(lud, req_unit_number); } #endif /* HAVE_LIBUSB */ diff --git a/gpsbabel/jeeps/gpsmath.c b/gpsbabel/jeeps/gpsmath.c index 6a5ee3df2..1a025012d 100644 --- a/gpsbabel/jeeps/gpsmath.c +++ b/gpsbabel/jeeps/gpsmath.c @@ -2,20 +2,20 @@ ** @source JEEPS arithmetic/conversion functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -28,11 +28,11 @@ #include "gpsdatum.h" -static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32 *zone, - char *zc, double *Mc, double *E0, - double *N0, double *F0); -static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, - double *E0, double *N0, double *F0); +static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32* zone, + char* zc, double* Mc, double* E0, + double* N0, double* F0); +static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double* Mc, + double* E0, double* N0, double* F0); @@ -47,7 +47,7 @@ static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, double GPS_Math_Deg_To_Rad(double v) { - return v*(double)((double)GPS_PI/(double)180.); + return v*(double)((double)GPS_PI/(double)180.); } @@ -63,7 +63,7 @@ double GPS_Math_Deg_To_Rad(double v) double GPS_Math_Rad_To_Deg(double v) { - return v*(double)((double)180./(double)GPS_PI); + return v*(double)((double)180./(double)GPS_PI); } @@ -79,30 +79,29 @@ double GPS_Math_Rad_To_Deg(double v) ** @return [void] ************************************************************************/ -void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m) +void GPS_Math_Deg_To_DegMin(double v, int32* d, double* m) { - int32 sign; - - if(v<(double)0.) - { - v *= (double)-1.; - sign = 1; - } - else - sign = 0; - - *d = (int32)v; - *m = (v-(double)*d) * (double)60.0; - if(*m>(double)59.999) - { - ++*d; - *m = (double)0.0; - } - - if(sign) - *d = -*d; - - return; + int32 sign; + + if (v<(double)0.) { + v *= (double)-1.; + sign = 1; + } else { + sign = 0; + } + + *d = (int32)v; + *m = (v-(double)*d) * (double)60.0; + if (*m>(double)59.999) { + ++*d; + *m = (double)0.0; + } + + if (sign) { + *d = -*d; + } + + return; } @@ -118,14 +117,15 @@ void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m) ** @return [void] ************************************************************************/ -void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg) +void GPS_Math_DegMin_To_Deg(int32 d, double m, double* deg) { - *deg = ((double)abs(d)) + m / (double)60.0; - if(d<0) - *deg = -*deg; + *deg = ((double)abs(d)) + m / (double)60.0; + if (d<0) { + *deg = -*deg; + } - return; + return; } @@ -142,43 +142,41 @@ void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg) ** @return [void] ************************************************************************/ -void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s) +void GPS_Math_Deg_To_DegMinSec(double v, int32* d, int32* m, double* s) { - int32 sign; - double t; - - if(v<(double)0.) - { - v *= (double)-1.; - sign = 1; - } - else - sign = 0; - - *d = (int32)v; - t = (v -(double)*d) * (double)60.0; - *m = (v-(double)*d) * (double)60.0; - *s = (t - (int32)t) * (double)60.0; - - if(*s>(double)59.999) - { - ++t; - *s = (double)0.0; - } + int32 sign; + double t; - - if(t>(double)59.999) - { - ++*d; - t = 0; - } + if (v<(double)0.) { + v *= (double)-1.; + sign = 1; + } else { + sign = 0; + } + + *d = (int32)v; + t = (v -(double)*d) * (double)60.0; + *m = (v-(double)*d) * (double)60.0; + *s = (t - (int32)t) * (double)60.0; + + if (*s>(double)59.999) { + ++t; + *s = (double)0.0; + } - *m = (int32)t; - if(sign) - *d = -*d; + if (t>(double)59.999) { + ++*d; + t = 0; + } - return; + *m = (int32)t; + + if (sign) { + *d = -*d; + } + + return; } @@ -195,21 +193,22 @@ void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s) ** @return [void] ************************************************************************/ -void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg) +void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double* deg) { - *deg = ((double)abs(d)) + ((double)m + s / (double)60.0) / (double)60.0; - if(d<0) - *deg = -*deg; + *deg = ((double)abs(d)) + ((double)m + s / (double)60.0) / (double)60.0; + if (d<0) { + *deg = -*deg; + } - return; + return; } /* @func GPS_Math_Metres_To_Feet ******************************************* ** -** Convert metres to feet +** Convert metres to feet ** ** @param [r] v [double] metres ** @@ -218,7 +217,7 @@ void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg) double GPS_Math_Metres_To_Feet(double v) { - return v/0.3048; + return v/0.3048; } @@ -234,7 +233,7 @@ double GPS_Math_Metres_To_Feet(double v) double GPS_Math_Feet_To_Metres(double v) { - return v * 0.3048; + return v * 0.3048; } @@ -250,7 +249,7 @@ double GPS_Math_Feet_To_Metres(double v) int32 GPS_Math_Deg_To_Semi(double v) { - return ( (double)(1U<<31) / (double)180) * v; + return ((double)(1U<<31) / (double)180) * v; } @@ -266,7 +265,7 @@ int32 GPS_Math_Deg_To_Semi(double v) double GPS_Math_Semi_To_Deg(int32 v) { - return (double) (((double)v / (double)(1U<<31)) * (double)180); + return (double)(((double)v / (double)(1U<<31)) * (double)180); } @@ -282,7 +281,7 @@ double GPS_Math_Semi_To_Deg(int32 v) time_t GPS_Math_Utime_To_Gtime(time_t v) { - return v-631065600; + return v-631065600; } @@ -298,7 +297,7 @@ time_t GPS_Math_Utime_To_Gtime(time_t v) time_t GPS_Math_Gtime_To_Utime(time_t v) { - return v+631065600; + return v+631065600; } @@ -321,24 +320,24 @@ time_t GPS_Math_Gtime_To_Utime(time_t v) ** @return [void] ************************************************************************/ void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z, - double a, double b) + double* x, double* y, double* z, + double a, double b) { - double esq; - double nu; + double esq; + double nu; + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - - esq = ((a*a)-(b*b)) / (a*a); - - nu = a / pow(((double)1.0-esq*sin(phi)*sin(phi)),(double)0.5); - *x = (nu+H) * cos(phi) * cos(lambda); - *y = (nu+H) * cos(phi) * sin(lambda); - *z = (((double)1.0-esq)*nu+H) * sin(phi); + esq = ((a*a)-(b*b)) / (a*a); - return; + nu = a / pow(((double)1.0-esq*sin(phi)*sin(phi)),(double)0.5); + *x = (nu+H) * cos(phi) * cos(lambda); + *y = (nu+H) * cos(phi) * sin(lambda); + *z = (((double)1.0-esq)*nu+H) * sin(phi); + + return; } @@ -359,41 +358,48 @@ void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, ** ** @return [void] ************************************************************************/ -void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z, - double a, double b) +void GPS_Math_XYZ_To_LatLonH(double* phi, double* lambda, double* H, + double x, double y, double z, + double a, double b) { - double esq; - double nu=0.0; - double phix; - double nphi; - double rho; - int32 t1=0; - int32 t2=0; - - if(x<(double)0 && y>=(double)0) t1=1; - if(x<(double)0 && y<(double)0) t2=1; - - rho = pow(((x*x)+(y*y)),(double)0.5); - esq = ((a*a)-(b*b)) / (a*a); - phix = atan(z/(((double)1.0 - esq) * rho)); - nphi = (double)1e20; - - while(fabs(phix-nphi)>(double)0.00000000001) - { - nphi = phix; - nu = a / pow(((double)1.0-esq*sin(nphi)*sin(nphi)),(double)0.5); - phix = atan((z+esq*nu*sin(nphi))/rho); - } - - *phi = GPS_Math_Rad_To_Deg(phix); - *H = (rho / cos(phix)) - nu; - *lambda = GPS_Math_Rad_To_Deg(atan(y/x)); - - if(t1) *lambda += (double)180.0; - if(t2) *lambda -= (double)180.0; - - return; + double esq; + double nu=0.0; + double phix; + double nphi; + double rho; + int32 t1=0; + int32 t2=0; + + if (x<(double)0 && y>=(double)0) { + t1=1; + } + if (x<(double)0 && y<(double)0) { + t2=1; + } + + rho = pow(((x*x)+(y*y)),(double)0.5); + esq = ((a*a)-(b*b)) / (a*a); + phix = atan(z/(((double)1.0 - esq) * rho)); + nphi = (double)1e20; + + while (fabs(phix-nphi)>(double)0.00000000001) { + nphi = phix; + nu = a / pow(((double)1.0-esq*sin(nphi)*sin(nphi)),(double)0.5); + phix = atan((z+esq*nu*sin(nphi))/rho); + } + + *phi = GPS_Math_Rad_To_Deg(phix); + *H = (rho / cos(phix)) - nu; + *lambda = GPS_Math_Rad_To_Deg(atan(y/x)); + + if (t1) { + *lambda += (double)180.0; + } + if (t2) { + *lambda -= (double)180.0; + } + + return; } @@ -413,14 +419,14 @@ void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, ** @return [void] ************************************************************************/ void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z) + double* x, double* y, double* z) { - double a = 6377563.396; - double b = 6356256.910; + double a = 6377563.396; + double b = 6356256.910; - GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); + GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); - return; + return; } @@ -440,14 +446,14 @@ void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, ** @return [void] ************************************************************************/ void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z) + double* x, double* y, double* z) { - double a = 6378137.000; - double b = 6356752.3141; + double a = 6378137.000; + double b = 6356752.3141; - GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); + GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); - return; + return; } @@ -466,15 +472,15 @@ void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, ** ** @return [void] ************************************************************************/ -void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z) +void GPS_Math_XYZ_To_Airy1830LatLonH(double* phi, double* lambda, double* H, + double x, double y, double z) { - double a = 6377563.396; - double b = 6356256.910; + double a = 6377563.396; + double b = 6356256.910; - GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); + GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); - return; + return; } @@ -492,15 +498,15 @@ void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, ** ** @return [void] ************************************************************************/ -void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z) +void GPS_Math_XYZ_To_WGS84LatLonH(double* phi, double* lambda, double* H, + double x, double y, double z) { - double a = 6378137.000; - double b = 66356752.3141; + double a = 6378137.000; + double b = 66356752.3141; - GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); + GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); - return; + return; } @@ -523,88 +529,88 @@ void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, ** ** @return [void] ************************************************************************/ -void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, - double lambda, double N0, double E0, - double phi0, double lambda0, - double F0, double a, double b) +void GPS_Math_LatLon_To_EN(double* E, double* N, double phi, + double lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b) { - double esq; - double n; - double etasq; - double nu; - double rho; - double M; - double I; - double II; - double III; - double IIIA; - double IV; - double V; - double VI; - - double tmp; - double tmp2; - double fdf; - double fde; - - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - - esq = ((a*a)-(b*b)) / (a*a); - n = (a-b) / (a+b); - - tmp = (double)1.0 - (esq * sin(phi) * sin(phi)); - nu = a * F0 * pow(tmp,(double)-0.5); - rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); - etasq = (nu / rho) - (double)1.0; - - fdf = (double)5.0 / (double)4.0; - tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); - tmp *= (phi - phi0); - tmp2 = (double)3.0*n + (double)3.0*n*n + ((double)21./(double)8.)*n*n*n; - tmp2 *= (sin(phi-phi0) * cos(phi+phi0)); - tmp -= tmp2; - - fde = ((double)15.0 / (double)8.0); - tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (phi-phi0)); - tmp2 *= cos((double)2.0 * (phi+phi0)); - tmp += tmp2; - - tmp2 = ((double)35.0/(double)24.0) * n * n * n; - tmp2 *= sin((double)3.0 * (phi-phi0)); - tmp2 *= cos((double)3.0 * (phi+phi0)); - tmp -= tmp2; - - M = b * F0 * tmp; - I = M + N0; - II = (nu / (double)2.0) * sin(phi) * cos(phi); - III = (nu / (double)24.0) * sin(phi) * cos(phi) * cos(phi) * cos(phi); - III *= ((double)5.0 - (tan(phi) * tan(phi)) + ((double)9.0 * etasq)); - IIIA = (nu / (double)720.0) * sin(phi) * pow(cos(phi),(double)5.0); - IIIA *= ((double)61.0 - ((double)58.0*tan(phi)*tan(phi)) + - pow(tan(phi),(double)4.0)); - IV = nu * cos(phi); - - tmp = pow(cos(phi),(double)3.0); - tmp *= ((nu/rho) - tan(phi) * tan(phi)); - V = (nu/(double)6.0) * tmp; - - tmp = (double)5.0 - ((double)18.0 * tan(phi) * tan(phi)); - tmp += tan(phi)*tan(phi)*tan(phi)*tan(phi) + ((double)14.0 * etasq); - tmp -= ((double)58.0 * tan(phi) * tan(phi) * etasq); - tmp2 = cos(phi)*cos(phi)*cos(phi)*cos(phi)*cos(phi) * tmp; - VI = (nu / (double)120.0) * tmp2; - - *N = I + II*(lambda-lambda0)*(lambda-lambda0) + - III*pow((lambda-lambda0),(double)4.0) + - IIIA*pow((lambda-lambda0),(double)6.0); - - *E = E0 + IV*(lambda-lambda0) + V*pow((lambda-lambda0),(double)3.0) + - VI * pow((lambda-lambda0),(double)5.0); - - return; + double esq; + double n; + double etasq; + double nu; + double rho; + double M; + double I; + double II; + double III; + double IIIA; + double IV; + double V; + double VI; + + double tmp; + double tmp2; + double fdf; + double fde; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + + esq = ((a*a)-(b*b)) / (a*a); + n = (a-b) / (a+b); + + tmp = (double)1.0 - (esq * sin(phi) * sin(phi)); + nu = a * F0 * pow(tmp,(double)-0.5); + rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); + etasq = (nu / rho) - (double)1.0; + + fdf = (double)5.0 / (double)4.0; + tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); + tmp *= (phi - phi0); + tmp2 = (double)3.0*n + (double)3.0*n*n + ((double)21./(double)8.)*n*n*n; + tmp2 *= (sin(phi-phi0) * cos(phi+phi0)); + tmp -= tmp2; + + fde = ((double)15.0 / (double)8.0); + tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (phi-phi0)); + tmp2 *= cos((double)2.0 * (phi+phi0)); + tmp += tmp2; + + tmp2 = ((double)35.0/(double)24.0) * n * n * n; + tmp2 *= sin((double)3.0 * (phi-phi0)); + tmp2 *= cos((double)3.0 * (phi+phi0)); + tmp -= tmp2; + + M = b * F0 * tmp; + I = M + N0; + II = (nu / (double)2.0) * sin(phi) * cos(phi); + III = (nu / (double)24.0) * sin(phi) * cos(phi) * cos(phi) * cos(phi); + III *= ((double)5.0 - (tan(phi) * tan(phi)) + ((double)9.0 * etasq)); + IIIA = (nu / (double)720.0) * sin(phi) * pow(cos(phi),(double)5.0); + IIIA *= ((double)61.0 - ((double)58.0*tan(phi)*tan(phi)) + + pow(tan(phi),(double)4.0)); + IV = nu * cos(phi); + + tmp = pow(cos(phi),(double)3.0); + tmp *= ((nu/rho) - tan(phi) * tan(phi)); + V = (nu/(double)6.0) * tmp; + + tmp = (double)5.0 - ((double)18.0 * tan(phi) * tan(phi)); + tmp += tan(phi)*tan(phi)*tan(phi)*tan(phi) + ((double)14.0 * etasq); + tmp -= ((double)58.0 * tan(phi) * tan(phi) * etasq); + tmp2 = cos(phi)*cos(phi)*cos(phi)*cos(phi)*cos(phi) * tmp; + VI = (nu / (double)120.0) * tmp2; + + *N = I + II*(lambda-lambda0)*(lambda-lambda0) + + III*pow((lambda-lambda0),(double)4.0) + + IIIA*pow((lambda-lambda0),(double)6.0); + + *E = E0 + IV*(lambda-lambda0) + V*pow((lambda-lambda0),(double)3.0) + + VI * pow((lambda-lambda0),(double)5.0); + + return; } @@ -621,20 +627,20 @@ void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, - double *N) +void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double* E, + double* N) { - double N0 = 250000; - double E0 = 200000; - double F0 = 1.000035; - double phi0 = 53.5; - double lambda0 = -8.; - double a = 6377340.189; - double b = 6356034.447; + double N0 = 250000; + double E0 = 200000; + double F0 = 1.000035; + double phi0 = 53.5; + double lambda0 = -8.; + double a = 6377340.189; + double b = 6356034.447; - GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - return; + return; } @@ -652,26 +658,26 @@ void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, - double *N) +void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double* E, + double* N) { - double N0 = -100000; - double E0 = 400000; - double F0 = 0.9996012717; - double phi0 = 49.; - double lambda0 = -2.; - double a = 6377563.396; - double b = 6356256.910; + double N0 = -100000; + double E0 = 400000; + double F0 = 0.9996012717; + double phi0 = 49.; + double lambda0 = -2.; + double a = 6377563.396; + double b = 6356256.910; - GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - return; + return; } /* @func int32 GPS_Math_WGS84_To_Swiss_EN ****************************** ** -** Convert WGS84 latitude and longitude to +** Convert WGS84 latitude and longitude to ** Swiss CH-1903 National Grid Eastings and Northings ** ( Oblique Mercator Projection ) ** @@ -683,31 +689,35 @@ void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ -int32 GPS_Math_WGS84_To_Swiss_EN(double lat, double lon, double *E, - double *N) +int32 GPS_Math_WGS84_To_Swiss_EN(double lat, double lon, double* E, + double* N) { - const double phi0 = 46.95240556; - const double lambda0 = 7.43958333; - const double E0 = 600000.0; - const double N0 = 200000.0; - double phi, lambda, alt, a, b; - - if (lat < 44.89022757) return 0; - if (lon < -0.16386312) return 0; - - a = GPS_Ellipse[4].a; - b = a - (a / GPS_Ellipse[4].invf); - - GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &phi, &lambda, &alt, 123); - GPS_Math_Swiss_LatLon_To_EN(phi, lambda, E, N, phi0, lambda0, E0, N0, a, b); - - return 1; + const double phi0 = 46.95240556; + const double lambda0 = 7.43958333; + const double E0 = 600000.0; + const double N0 = 200000.0; + double phi, lambda, alt, a, b; + + if (lat < 44.89022757) { + return 0; + } + if (lon < -0.16386312) { + return 0; + } + + a = GPS_Ellipse[4].a; + b = a - (a / GPS_Ellipse[4].invf); + + GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &phi, &lambda, &alt, 123); + GPS_Math_Swiss_LatLon_To_EN(phi, lambda, E, N, phi0, lambda0, E0, N0, a, b); + + return 1; } /* @GPS_Math_Swiss_EN_To_WGS84 ***************************************** ** -** Convert WGS84 latitude and longitude to +** Convert WGS84 latitude and longitude to ** Swiss CH-1903 National Grid Eastings and Northings ** ** @param [r] E [double] Swiss-NG easting (metres) @@ -717,19 +727,19 @@ int32 GPS_Math_WGS84_To_Swiss_EN(double lat, double lon, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double *lat, double *lon) +void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double* lat, double* lon) { - const double phi0 = 46.95240556; - const double lambda0 = 7.43958333; - const double E0 = 600000.0; - const double N0 = 200000.0; - double phi, lambda, alt, a, b; - - a = GPS_Ellipse[4].a; - b = a - (a / GPS_Ellipse[4].invf); - - GPS_Math_Swiss_EN_To_LatLon(E, N, &phi, &lambda, phi0, lambda0, E0, N0, a, b); - GPS_Math_Known_Datum_To_WGS84_M(phi, lambda, 0, lat, lon, &alt, 123); + const double phi0 = 46.95240556; + const double lambda0 = 7.43958333; + const double E0 = 600000.0; + const double N0 = 200000.0; + double phi, lambda, alt, a, b; + + a = GPS_Ellipse[4].a; + b = a - (a / GPS_Ellipse[4].invf); + + GPS_Math_Swiss_EN_To_LatLon(E, N, &phi, &lambda, phi0, lambda0, E0, N0, a, b); + GPS_Math_Known_Datum_To_WGS84_M(phi, lambda, 0, lat, lon, &alt, 123); } @@ -751,127 +761,129 @@ void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double *lat, double *lon) ** ** @return [void] ************************************************************************/ -void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double om0; - double A0; - double A1; - double A2; - double A3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - double lat; - double x; - double E1; - double E2; - double E3; - double E4; - - double phis; - double phic; - double phit; - double phis2; - double phis4; - double phis6; - double RD; - double dlam; - double NN; - double TT; - double WW; - double WW2; - double WW3; - double WW4; - double WW5; - double CC; - double MM; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - te4 = (double)3.0 * e4; - j = (double)45. * e6 / (double)1024.; - c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; - c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - - lat = c0*phi0; - phi0s2 = c1 * sin((double)2.*phi0); - phi0s4 = c2 * sin((double)4.*phi0); - phi0s6 = c3 * sin((double)6.*phi0); - AM0 = a * (lat-phi0s2+phi0s4-phi0s6); - - om0 = (double)1.0 - e2; - x = pow(om0,(double)0.5); - E1 = ((double)1.0 - x) / ((double)1.0 + x); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - phis = sin(phi); - phic = cos(phi); - phit = tan(phi); - RD = pow((double)1.-e2*phis*phis,(double).5); - NN = a/RD; - TT = phit*phit; - WW = dlam*phic; - WW2 = WW*WW; - WW3 = WW*WW2; - WW4 = WW*WW3; - WW5 = WW*WW4; - CC = e2*phic*phic/om0; - lat = c0*phi; - phis2 = c1 * sin((double)2.*phi); - phis4 = c2 * sin((double)4.*phi); - phis6 = c3 * sin((double)6.*phi); - MM = a * (lat-phis2+phis4-phis6); - - *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* - (TT*WW5/(double)120.)) + E0; - *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * - WW4/(double)24.) + N0; - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double om0; + double A0; + double A1; + double A2; + double A3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + double lat; + double x; + double E1; + double E2; + double E3; + double E4; + + double phis; + double phic; + double phit; + double phis2; + double phis4; + double phis6; + double RD; + double dlam; + double NN; + double TT; + double WW; + double WW2; + double WW3; + double WW4; + double WW5; + double CC; + double MM; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + te4 = (double)3.0 * e4; + j = (double)45. * e6 / (double)1024.; + c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; + c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + + lat = c0*phi0; + phi0s2 = c1 * sin((double)2.*phi0); + phi0s4 = c2 * sin((double)4.*phi0); + phi0s6 = c3 * sin((double)6.*phi0); + AM0 = a * (lat-phi0s2+phi0s4-phi0s6); + + om0 = (double)1.0 - e2; + x = pow(om0,(double)0.5); + E1 = ((double)1.0 - x) / ((double)1.0 + x); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + phic = cos(phi); + phit = tan(phi); + RD = pow((double)1.-e2*phis*phis,(double).5); + NN = a/RD; + TT = phit*phit; + WW = dlam*phic; + WW2 = WW*WW; + WW3 = WW*WW2; + WW4 = WW*WW3; + WW5 = WW*WW4; + CC = e2*phic*phic/om0; + lat = c0*phi; + phis2 = c1 * sin((double)2.*phi); + phis4 = c2 * sin((double)4.*phi); + phis6 = c3 * sin((double)6.*phi); + MM = a * (lat-phis2+phis4-phis6); + + *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* + (TT*WW5/(double)120.)) + E0; + *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * + WW4/(double)24.) + N0; + return; } @@ -895,162 +907,161 @@ void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double om0; - double A0; - double A1; - double A2; - double A3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - double lat; - double x; - double E1; - double E2; - double E3; - double E4; - - double dx; - double dy; - double mu; - double mus2; - double mus4; - double mus6; - double mus8; - double M1; - double phi1; - double phi1s; - double phi1c; - double phi1t; - double T; - double T1; - double N1; - double R1; - double RD; - double DD; - double D2; - double D3; - double D4; - double D5; - double tol; - - M0 = GPS_Math_Deg_To_Rad(M0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - te4 = (double)3.0 * e4; - j = (double)45. * e6 / (double)1024.; - c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; - c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - - lat = c0*phi0; - phi0s2 = c1 * sin((double)2.*phi0); - phi0s4 = c2 * sin((double)4.*phi0); - phi0s6 = c3 * sin((double)6.*phi0); - AM0 = a * (lat-phi0s2+phi0s4-phi0s6); - - om0 = (double)1.0 - e2; - x = pow(om0,(double)0.5); - E1 = ((double)1.0 - x) / ((double)1.0 + x); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - - tol = (double)1.e-5; - - dx = E - E0; - dy = N - N0; - M1 = AM0 + dy; - mu = M1 / (a*c0); - mus2 = A0 * sin((double)2.*mu); - mus4 = A1 * sin((double)4.*mu); - mus6 = A2 * sin((double)6.*mu); - mus8 = A3 * sin((double)8.*mu); - phi1 = mu + mus2 + mus4 + mus6 + mus8; - - if((((po2-tol)po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; } - else if((((-po2-tol)GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; } - else - { - phi1s = sin(phi1); - phi1c = cos(phi1); - phi1t = tan(phi1); - T1 = phi1t*phi1t; - RD = pow((double)1.-e2*phi1s*phi1s,(double).5); - N1 = a/RD; - R1 = N1 * om0 / (RD*RD); - DD = dx/N1; - D2 = DD*DD; - D3 = DD*D2; - D4 = DD*D3; - D5 = DD*D4; - T = (double)1. + (double)3.*T1; - *phi = phi1-(N1*phi1t/R1)*(D2/(double)2.-T*D4/(double)24.); - *lambda = M0+(DD-T1*D3/(double)3.+T*T1*D5/(double)15.)/phi1c; - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; } + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -1058,7 +1069,7 @@ void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, /* @func int32 GPS_Math_WGS84_To_ICS_EN ****************************** ** -** Convert WGS84 latitude and longitude to +** Convert WGS84 latitude and longitude to ** Israeli old Grid Eastings and Northings ** ( Israeli Cassini Soldner ) ** @@ -1070,32 +1081,32 @@ void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ -int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double *E, - double *N) +int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double* E, + double* N) { - double const phi0 = 31.73409694444; // 31 44 2.749 - double const lambda0 = 35.21208055556; // 35 12 43.49 - double const E0 = 170251.555; - double const N0 = 1126867.909; - double phi, lambda, alt, a, b; - - int32 datum = GPS_Lookup_Datum_Index("Palestine 1923"); - int32 ellipse = GPS_Datum[datum].ellipse; - - a = GPS_Ellipse[ellipse].a; - b = a - (a / GPS_Ellipse[ellipse].invf); - - GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &phi, &lambda, &alt, datum); - GPS_Math_Cassini_LatLon_To_EN(phi, lambda, E, N, - phi0, lambda0, E0, N0, a, b); - - return 1; + double const phi0 = 31.73409694444; // 31 44 2.749 + double const lambda0 = 35.21208055556; // 35 12 43.49 + double const E0 = 170251.555; + double const N0 = 1126867.909; + double phi, lambda, alt, a, b; + + int32 datum = GPS_Lookup_Datum_Index("Palestine 1923"); + int32 ellipse = GPS_Datum[datum].ellipse; + + a = GPS_Ellipse[ellipse].a; + b = a - (a / GPS_Ellipse[ellipse].invf); + + GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &phi, &lambda, &alt, datum); + GPS_Math_Cassini_LatLon_To_EN(phi, lambda, E, N, + phi0, lambda0, E0, N0, a, b); + + return 1; } /* @GPS_Math_ICS_EN_To_WGS84 ***************************************** ** -** Convert WGS84 latitude and longitude to +** Convert WGS84 latitude and longitude to ** Israeli Oldl Grid Eastings and Northings ** ** @param [r] E [double] ICS easting (metres) @@ -1105,22 +1116,22 @@ int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_ICS_EN_To_WGS84(double E, double N, double *lat, double *lon) +void GPS_Math_ICS_EN_To_WGS84(double E, double N, double* lat, double* lon) { - double const phi0 = 31.73409694444; // 31 44 2.749 - double const lambda0 = 35.21208055556; // 35 12 43.49 - double const E0 = 170251.555; - double const N0 = 1126867.909; - double phi, lambda, alt, a, b; - int32 datum = GPS_Lookup_Datum_Index("Palestine 1923"); - int32 ellipse = GPS_Datum[datum].ellipse; - - a = GPS_Ellipse[ellipse].a; - b = a - (a / GPS_Ellipse[ellipse].invf); - - GPS_Math_Cassini_EN_To_LatLon(E, N, &phi, &lambda, phi0, lambda0, - E0, N0, a, b); - GPS_Math_Known_Datum_To_WGS84_M(phi, lambda, 0, lat, lon, &alt, datum); + double const phi0 = 31.73409694444; // 31 44 2.749 + double const lambda0 = 35.21208055556; // 35 12 43.49 + double const E0 = 170251.555; + double const N0 = 1126867.909; + double phi, lambda, alt, a, b; + int32 datum = GPS_Lookup_Datum_Index("Palestine 1923"); + int32 ellipse = GPS_Datum[datum].ellipse; + + a = GPS_Ellipse[ellipse].a; + b = a - (a / GPS_Ellipse[ellipse].invf); + + GPS_Math_Cassini_EN_To_LatLon(E, N, &phi, &lambda, phi0, lambda0, + E0, N0, a, b); + GPS_Math_Known_Datum_To_WGS84_M(phi, lambda, 0, lat, lon, &alt, datum); } @@ -1143,115 +1154,115 @@ void GPS_Math_ICS_EN_To_WGS84(double E, double N, double *lat, double *lon) ** ** @return [void] ************************************************************************/ -void GPS_Math_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double N0, double E0, - double phi0, double lambda0, - double F0, double a, double b) +void GPS_Math_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b) { - double esq; - double n; - double etasq; - double nu; - double rho; - double M; - double VII; - double VIII; - double IX; - double X; - double XI; - double XII; - double XIIA; - double phix; - double nphi=0.0; - - double tmp; - double tmp2; - double fdf; - double fde; - - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - n = (a-b) / (a+b); - fdf = (double)5.0 / (double)4.0; - fde = ((double)15.0 / (double)8.0); - - esq = ((a*a)-(b*b)) / (a*a); - - - phix = ((N-N0)/(a*F0)) + phi0; - - tmp = (double)1.0 - (esq * sin(phix) * sin(phix)); - nu = a * F0 * pow(tmp,(double)-0.5); - rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); - etasq = (nu / rho) - (double)1.0; - - M = (double)-1e20; - - while(N-N0-M > (double)0.000001) - { - nphi = phix; - - tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); - tmp *= (nphi - phi0); - tmp2 = (double)3.0*n + (double)3.0*n*n + - ((double)21./(double)8.)*n*n*n; - tmp2 *= (sin(nphi-phi0) * cos(nphi+phi0)); - tmp -= tmp2; - - - tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (nphi-phi0)); - tmp2 *= cos((double)2.0 * (nphi+phi0)); - tmp += tmp2; - - tmp2 = ((double)35.0/(double)24.0) * n * n * n; - tmp2 *= sin((double)3.0 * (nphi-phi0)); - tmp2 *= cos((double)3.0 * (nphi+phi0)); - tmp -= tmp2; - - M = b * F0 * tmp; - - if(N-N0-M > (double)0.000001) - phix = ((N-N0-M)/(a*F0)) + nphi; + double esq; + double n; + double etasq; + double nu; + double rho; + double M; + double VII; + double VIII; + double IX; + double X; + double XI; + double XII; + double XIIA; + double phix; + double nphi=0.0; + + double tmp; + double tmp2; + double fdf; + double fde; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + n = (a-b) / (a+b); + fdf = (double)5.0 / (double)4.0; + fde = ((double)15.0 / (double)8.0); + + esq = ((a*a)-(b*b)) / (a*a); + + + phix = ((N-N0)/(a*F0)) + phi0; + + tmp = (double)1.0 - (esq * sin(phix) * sin(phix)); + nu = a * F0 * pow(tmp,(double)-0.5); + rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); + etasq = (nu / rho) - (double)1.0; + + M = (double)-1e20; + + while (N-N0-M > (double)0.000001) { + nphi = phix; + + tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); + tmp *= (nphi - phi0); + tmp2 = (double)3.0*n + (double)3.0*n*n + + ((double)21./(double)8.)*n*n*n; + tmp2 *= (sin(nphi-phi0) * cos(nphi+phi0)); + tmp -= tmp2; + + + tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (nphi-phi0)); + tmp2 *= cos((double)2.0 * (nphi+phi0)); + tmp += tmp2; + + tmp2 = ((double)35.0/(double)24.0) * n * n * n; + tmp2 *= sin((double)3.0 * (nphi-phi0)); + tmp2 *= cos((double)3.0 * (nphi+phi0)); + tmp -= tmp2; + + M = b * F0 * tmp; + + if (N-N0-M > (double)0.000001) { + phix = ((N-N0-M)/(a*F0)) + nphi; } - + } + - VII = tan(nphi) / ((double)2.0 * rho * nu); + VII = tan(nphi) / ((double)2.0 * rho * nu); - tmp = (double)5.0 + (double)3.0 * tan(nphi) * tan(nphi) + etasq; - tmp -= (double)9.0 * tan(nphi) * tan(nphi) * etasq; - VIII = (tan(nphi)*tmp) / ((double)24.0 * rho * nu*nu*nu); + tmp = (double)5.0 + (double)3.0 * tan(nphi) * tan(nphi) + etasq; + tmp -= (double)9.0 * tan(nphi) * tan(nphi) * etasq; + VIII = (tan(nphi)*tmp) / ((double)24.0 * rho * nu*nu*nu); - tmp = (double)61.0 + (double)90.0 * tan(nphi) * tan(nphi); - tmp += (double)45.0 * pow(tan(nphi),(double)4.0); - IX = tan(nphi) / ((double)720.0 * rho * pow(nu,(double)5.0)) * tmp; + tmp = (double)61.0 + (double)90.0 * tan(nphi) * tan(nphi); + tmp += (double)45.0 * pow(tan(nphi),(double)4.0); + IX = tan(nphi) / ((double)720.0 * rho * pow(nu,(double)5.0)) * tmp; - X = (double)1.0 / (cos(nphi) * nu); + X = (double)1.0 / (cos(nphi) * nu); - tmp = (nu / rho) + (double)2.0 * tan(nphi) * tan(nphi); - XI = ((double)1.0 / (cos(nphi) * (double)6.0 * nu*nu*nu)) * tmp; + tmp = (nu / rho) + (double)2.0 * tan(nphi) * tan(nphi); + XI = ((double)1.0 / (cos(nphi) * (double)6.0 * nu*nu*nu)) * tmp; - tmp = (double)5.0 + (double)28.0 * tan(nphi)*tan(nphi); - tmp += (double)24.0 * pow(tan(nphi),(double)4.0); - XII = ((double)1.0 / ((double)120.0 * pow(nu,(double)5.0) * cos(nphi))) - * tmp; + tmp = (double)5.0 + (double)28.0 * tan(nphi)*tan(nphi); + tmp += (double)24.0 * pow(tan(nphi),(double)4.0); + XII = ((double)1.0 / ((double)120.0 * pow(nu,(double)5.0) * cos(nphi))) + * tmp; - tmp = (double)61.0 + (double)662.0 * tan(nphi) * tan(nphi); - tmp += (double)1320.0 * pow(tan(nphi),(double)4.0); - tmp += (double)720.0 * pow(tan(nphi),(double)6.0); - XIIA = ((double)1.0 / (cos(nphi) * (double)5040.0 * pow(nu,(double)7.0))) - * tmp; + tmp = (double)61.0 + (double)662.0 * tan(nphi) * tan(nphi); + tmp += (double)1320.0 * pow(tan(nphi),(double)4.0); + tmp += (double)720.0 * pow(tan(nphi),(double)6.0); + XIIA = ((double)1.0 / (cos(nphi) * (double)5040.0 * pow(nu,(double)7.0))) + * tmp; - *phi = nphi - VII*pow((E-E0),(double)2.0) + VIII*pow((E-E0),(double)4.0) - - IX*pow((E-E0),(double)6.0); - - *lambda = lambda0 + X*(E-E0) - XI*pow((E-E0),(double)3.0) + - XII*pow((E-E0),(double)5.0) - XIIA*pow((E-E0),(double)7.0); + *phi = nphi - VII*pow((E-E0),(double)2.0) + VIII*pow((E-E0),(double)4.0) - + IX*pow((E-E0),(double)6.0); - *phi = GPS_Math_Rad_To_Deg(*phi); - *lambda = GPS_Math_Rad_To_Deg(*lambda); + *lambda = lambda0 + X*(E-E0) - XI*pow((E-E0),(double)3.0) + + XII*pow((E-E0),(double)5.0) - XIIA*pow((E-E0),(double)7.0); - return; + *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + + return; } @@ -1269,20 +1280,20 @@ void GPS_Math_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, - double *lambda) +void GPS_Math_NGENToAiry1830LatLon(double E, double N, double* phi, + double* lambda) { - double N0 = -100000; - double E0 = 400000; - double F0 = 0.9996012717; - double phi0 = 49.; - double lambda0 = -2.; - double a = 6377563.396; - double b = 6356256.910; - - GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - - return; + double N0 = -100000; + double E0 = 400000; + double F0 = 0.9996012717; + double phi0 = 49.; + double lambda0 = -2.; + double a = 6377563.396; + double b = 6356256.910; + + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; } @@ -1299,20 +1310,20 @@ void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, - double *lambda) +void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double* phi, + double* lambda) { - double N0 = 250000; - double E0 = 200000; - double F0 = 1.000035; - double phi0 = 53.5; - double lambda0 = -8.; - double a = 6377340.189; - double b = 6356034.447; - - GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - - return; + double N0 = 250000; + double E0 = 200000; + double F0 = 1.000035; + double phi0 = 53.5; + double lambda0 = -8.; + double a = 6377340.189; + double b = 6356034.447; + + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; } @@ -1330,26 +1341,27 @@ void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, - double *mN, char *map) +int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double* mE, + double* mN, char* map) { - int32 t; - int32 idx; - - if(E>=(double)700000. || E<(double)0.0 || N<(double)0.0 || - N>=(double)1300000.0) - return 0; - - idx = ((int32)N/100000)*7 + (int32)E/100000; - (void) strcpy(map,UKNG[idx]); - - t = ((int32)E / 100000) * 100000; - *mE = E - (double)t; - - t = ((int32)N / 100000) * 100000; - *mN = N - (double)t; - - return 1; + int32 t; + int32 idx; + + if (E>=(double)700000. || E<(double)0.0 || N<(double)0.0 || + N>=(double)1300000.0) { + return 0; + } + + idx = ((int32)N/100000)*7 + (int32)E/100000; + (void) strcpy(map,UKNG[idx]); + + t = ((int32)E / 100000) * 100000; + *mE = E - (double)t; + + t = ((int32)N / 100000) * 100000; + *mN = N - (double)t; + + return 1; } @@ -1368,33 +1380,36 @@ int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, double *E, - double *N) +int32 GPS_Math_UKOSNG_Map_To_EN(char* map, double mapE, double mapN, double* E, + double* N) { - int32 t; - int32 idx; - - if(mapE>=(double)100000.0 || mapE<(double)0.0 || mapN<(double)0.0 || - mapN>(double)100000.0) - return 0; - - idx=0; - while(*UKNG[idx]) - { - if(!strcmp(UKNG[idx],map)) break; - ++idx; + int32 t; + int32 idx; + + if (mapE>=(double)100000.0 || mapE<(double)0.0 || mapN<(double)0.0 || + mapN>(double)100000.0) { + return 0; + } + + idx=0; + while (*UKNG[idx]) { + if (!strcmp(UKNG[idx],map)) { + break; } - if(!*UKNG[idx]) - return 0; - + ++idx; + } + if (!*UKNG[idx]) { + return 0; + } + - t = (idx / 7) * 100000; - *N = mapN + (double)t; + t = (idx / 7) * 100000; + *N = mapN + (double)t; - t = (idx % 7) * 100000; - *E = mapE + (double)t; + t = (idx % 7) * 100000; + *E = mapE + (double)t; - return 1; + return 1; } @@ -1420,67 +1435,67 @@ int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, - double Sif, double *Dphi, double *Dlam, - double *DH, double Da, double Dif, double dx, - double dy, double dz) + double Sif, double* Dphi, double* Dlam, + double* DH, double Da, double Dif, double dx, + double dy, double dz) { - double Sf; - double Df; - double esq; - double bda; - double da; - double df; - double N; - double M; - double tmp; - double tmp2; - double dphi; - double dlambda; - double dheight; - double phis; - double phic; - double lams; - double lamc; - - Sf = (double)1.0 / Sif; - Df = (double)1.0 / Dif; - - esq = (double)2.0*Sf - pow(Sf,(double)2.0); - bda = (double)1.0 - Sf; - Sphi = GPS_Math_Deg_To_Rad(Sphi); - Slam = GPS_Math_Deg_To_Rad(Slam); - - da = Da - Sa; - df = Df - Sf; - - phis = sin(Sphi); - phic = cos(Sphi); - lams = sin(Slam); - lamc = cos(Slam); - - N = Sa / sqrt((double)1.0 - esq*pow(phis,(double)2.0)); - - tmp = ((double)1.0-esq) /pow(((double)1.0-esq*pow(phis,(double)2.0)),1.5); - M = Sa * tmp; - - tmp = df * ((M/bda)+N*bda) * phis * phic; - tmp2 = da * N * esq * phis * phic / Sa; - tmp2 += ((-dx*phis*lamc-dy*phis*lams) + dz*phic); - dphi = (tmp2 + tmp) / (M + SH); - - dlambda = (-dx*lams+dy*lamc) / ((N+SH)*phic); - - dheight = dx*phic*lamc + dy*phic*lams + dz*phis - da*(Sa/N) + - df*bda*N*phis*phis; - - *Dphi = Sphi + dphi; - *Dlam = Slam + dlambda; - *DH = SH + dheight; - - *Dphi = GPS_Math_Rad_To_Deg(*Dphi); - *Dlam = GPS_Math_Rad_To_Deg(*Dlam); - - return; + double Sf; + double Df; + double esq; + double bda; + double da; + double df; + double N; + double M; + double tmp; + double tmp2; + double dphi; + double dlambda; + double dheight; + double phis; + double phic; + double lams; + double lamc; + + Sf = (double)1.0 / Sif; + Df = (double)1.0 / Dif; + + esq = (double)2.0*Sf - pow(Sf,(double)2.0); + bda = (double)1.0 - Sf; + Sphi = GPS_Math_Deg_To_Rad(Sphi); + Slam = GPS_Math_Deg_To_Rad(Slam); + + da = Da - Sa; + df = Df - Sf; + + phis = sin(Sphi); + phic = cos(Sphi); + lams = sin(Slam); + lamc = cos(Slam); + + N = Sa / sqrt((double)1.0 - esq*pow(phis,(double)2.0)); + + tmp = ((double)1.0-esq) /pow(((double)1.0-esq*pow(phis,(double)2.0)),1.5); + M = Sa * tmp; + + tmp = df * ((M/bda)+N*bda) * phis * phic; + tmp2 = da * N * esq * phis * phic / Sa; + tmp2 += ((-dx*phis*lamc-dy*phis*lams) + dz*phic); + dphi = (tmp2 + tmp) / (M + SH); + + dlambda = (-dx*lams+dy*lamc) / ((N+SH)*phic); + + dheight = dx*phic*lamc + dy*phic*lams + dz*phis - da*(Sa/N) + + df*bda*N*phis*phis; + + *Dphi = Sphi + dphi; + *Dlam = Slam + dlambda; + *DH = SH + dheight; + + *Dphi = GPS_Math_Rad_To_Deg(*Dphi); + *Dlam = GPS_Math_Rad_To_Deg(*Dlam); + + return; } @@ -1500,31 +1515,31 @@ void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, ** @return [void] ************************************************************************/ void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n) + double* Dphi, double* Dlam, double* DH, + int32 n) { - double Sa; - double Sif; - double Da; - double Dif; - double x; - double y; - double z; - int32 idx; - - Da = (double) 6378137.0; - Dif = (double) 298.257223563; - - idx = GPS_Datum[n].ellipse; - Sa = GPS_Ellipse[idx].a; - Sif = GPS_Ellipse[idx].invf; - x = GPS_Datum[n].dx; - y = GPS_Datum[n].dy; - z = GPS_Datum[n].dz; - - GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + + Da = (double) 6378137.0; + Dif = (double) 298.257223563; + + idx = GPS_Datum[n].ellipse; + Sa = GPS_Ellipse[idx].a; + Sif = GPS_Ellipse[idx].invf; + x = GPS_Datum[n].dx; + y = GPS_Datum[n].dy; + z = GPS_Datum[n].dz; + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; } @@ -1544,31 +1559,31 @@ void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n) + double* Dphi, double* Dlam, double* DH, + int32 n) { - double Sa; - double Sif; - double Da; - double Dif; - double x; - double y; - double z; - int32 idx; - - Sa = (double) 6378137.0; - Sif = (double) 298.257223563; - - idx = GPS_Datum[n].ellipse; - Da = GPS_Ellipse[idx].a; - Dif = GPS_Ellipse[idx].invf; - x = -GPS_Datum[n].dx; - y = -GPS_Datum[n].dy; - z = -GPS_Datum[n].dz; - - GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + + Sa = (double) 6378137.0; + Sif = (double) 298.257223563; + + idx = GPS_Datum[n].ellipse; + Da = GPS_Ellipse[idx].a; + Dif = GPS_Ellipse[idx].invf; + x = -GPS_Datum[n].dx; + y = -GPS_Datum[n].dy; + z = -GPS_Datum[n].dz; + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; } @@ -1588,44 +1603,44 @@ void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n) + double* Dphi, double* Dlam, double* DH, + int32 n) { - double Sa; - double Sif; - double Sb; - double Da; - double Dif; - double Db; - double x; - double y; - double z; - int32 idx; - double sx; - double sy; - double sz; - - Da = (double) 6378137.0; - Dif = (double) 298.257223563; - Db = Da - (Da / Dif); - - idx = GPS_Datum[n].ellipse; - Sa = GPS_Ellipse[idx].a; - Sif = GPS_Ellipse[idx].invf; - Sb = Sa - (Sa / Sif); - - x = GPS_Datum[n].dx; - y = GPS_Datum[n].dy; - z = GPS_Datum[n].dz; - - GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&sx,&sy,&sz,Sa,Sb); - sx += x; - sy += y; - sz += z; - - GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,sx,sy,sz,Da,Db); - - return; + double Sa; + double Sif; + double Sb; + double Da; + double Dif; + double Db; + double x; + double y; + double z; + int32 idx; + double sx; + double sy; + double sz; + + Da = (double) 6378137.0; + Dif = (double) 298.257223563; + Db = Da - (Da / Dif); + + idx = GPS_Datum[n].ellipse; + Sa = GPS_Ellipse[idx].a; + Sif = GPS_Ellipse[idx].invf; + Sb = Sa - (Sa / Sif); + + x = GPS_Datum[n].dx; + y = GPS_Datum[n].dy; + z = GPS_Datum[n].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&sx,&sy,&sz,Sa,Sb); + sx += x; + sy += y; + sz += z; + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,sx,sy,sz,Da,Db); + + return; } @@ -1645,44 +1660,44 @@ void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n) + double* Dphi, double* Dlam, double* DH, + int32 n) { - double Sa; - double Sif; - double Da; - double Dif; - double x; - double y; - double z; - int32 idx; - double Sb; - double Db; - double dx; - double dy; - double dz; - - Sa = (double) 6378137.0; - Sif = (double) 298.257223563; - Sb = Sa - (Sa / Sif); - - idx = GPS_Datum[n].ellipse; - Da = GPS_Ellipse[idx].a; - Dif = GPS_Ellipse[idx].invf; - Db = Da - (Da / Dif); - - x = -GPS_Datum[n].dx; - y = -GPS_Datum[n].dy; - z = -GPS_Datum[n].dz; - - GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); - dx += x; - dy += y; - dz += z; - - GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + double Sb; + double Db; + double dx; + double dy; + double dz; + + Sa = (double) 6378137.0; + Sif = (double) 298.257223563; + Sb = Sa - (Sa / Sif); + + idx = GPS_Datum[n].ellipse; + Da = GPS_Ellipse[idx].a; + Dif = GPS_Ellipse[idx].invf; + Db = Da - (Da / Dif); + + x = -GPS_Datum[n].dx; + y = -GPS_Datum[n].dy; + z = -GPS_Datum[n].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); + dx += x; + dy += y; + dz += z; + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); + + return; } @@ -1703,48 +1718,48 @@ void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, - double *DH, int32 n1, int32 n2) + double* Dphi, double* Dlam, + double* DH, int32 n1, int32 n2) { - double Sa; - double Sif; - double Da; - double Dif; - double x1; - double y1; - double z1; - double x2; - double y2; - double z2; - double x; - double y; - double z; - - int32 idx1; - int32 idx2; - - - idx1 = GPS_Datum[n1].ellipse; - Sa = GPS_Ellipse[idx1].a; - Sif = GPS_Ellipse[idx1].invf; - x1 = GPS_Datum[n1].dx; - y1 = GPS_Datum[n1].dy; - z1 = GPS_Datum[n1].dz; - - idx2 = GPS_Datum[n2].ellipse; - Da = GPS_Ellipse[idx2].a; - Dif = GPS_Ellipse[idx2].invf; - x2 = GPS_Datum[n2].dx; - y2 = GPS_Datum[n2].dy; - z2 = GPS_Datum[n2].dz; - - x = -(x2-x1); - y = -(y2-y1); - z = -(z2-z1); - - GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x1; + double y1; + double z1; + double x2; + double y2; + double z2; + double x; + double y; + double z; + + int32 idx1; + int32 idx2; + + + idx1 = GPS_Datum[n1].ellipse; + Sa = GPS_Ellipse[idx1].a; + Sif = GPS_Ellipse[idx1].invf; + x1 = GPS_Datum[n1].dx; + y1 = GPS_Datum[n1].dy; + z1 = GPS_Datum[n1].dz; + + idx2 = GPS_Datum[n2].ellipse; + Da = GPS_Ellipse[idx2].a; + Dif = GPS_Ellipse[idx2].invf; + x2 = GPS_Datum[n2].dx; + y2 = GPS_Datum[n2].dy; + z2 = GPS_Datum[n2].dz; + + x = -(x2-x1); + y = -(y2-y1); + z = -(z2-z1); + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; } @@ -1765,55 +1780,55 @@ void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, - double *DH, int32 n1, int32 n2) + double* Dphi, double* Dlam, + double* DH, int32 n1, int32 n2) { - double Sa; - double Sif; - double Da; - double Dif; - double x1; - double y1; - double z1; - double x2; - double y2; - double z2; - - int32 idx1; - int32 idx2; - - double Sb; - double Db; - double dx; - double dy; - double dz; - - idx1 = GPS_Datum[n1].ellipse; - Sa = GPS_Ellipse[idx1].a; - Sif = GPS_Ellipse[idx1].invf; - Sb = Sa - (Sa / Sif); - - x1 = GPS_Datum[n1].dx; - y1 = GPS_Datum[n1].dy; - z1 = GPS_Datum[n1].dz; - - idx2 = GPS_Datum[n2].ellipse; - Da = GPS_Ellipse[idx2].a; - Dif = GPS_Ellipse[idx2].invf; - Db = Da - (Da / Dif); - - x2 = GPS_Datum[n2].dx; - y2 = GPS_Datum[n2].dy; - z2 = GPS_Datum[n2].dz; - - GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); - dx += -(x2-x1); - dy += -(y2-y1); - dz += -(z2-z1); - - GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x1; + double y1; + double z1; + double x2; + double y2; + double z2; + + int32 idx1; + int32 idx2; + + double Sb; + double Db; + double dx; + double dy; + double dz; + + idx1 = GPS_Datum[n1].ellipse; + Sa = GPS_Ellipse[idx1].a; + Sif = GPS_Ellipse[idx1].invf; + Sb = Sa - (Sa / Sif); + + x1 = GPS_Datum[n1].dx; + y1 = GPS_Datum[n1].dy; + z1 = GPS_Datum[n1].dz; + + idx2 = GPS_Datum[n2].ellipse; + Da = GPS_Ellipse[idx2].a; + Dif = GPS_Ellipse[idx2].invf; + Db = Da - (Da / Dif); + + x2 = GPS_Datum[n2].dx; + y2 = GPS_Datum[n2].dy; + z2 = GPS_Datum[n2].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); + dx += -(x2-x1); + dy += -(y2-y1); + dz += -(z2-z1); + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); + + return; } @@ -1831,24 +1846,25 @@ void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, - double *mN, char *map) +int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double* mE, + double* mN, char* map) { - double alat; - double alon; - double aht; - double aE; - double aN; + double alat; + double alon; + double aht; + double aE; + double aN; - GPS_Math_WGS84_To_Known_Datum_M(lat,lon,30,&alat,&alon,&aht,86); + GPS_Math_WGS84_To_Known_Datum_M(lat,lon,30,&alat,&alon,&aht,86); - GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); + GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); - if(!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) - return 0; + if (!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) { + return 0; + } - return 1; + return 1; } @@ -1866,23 +1882,24 @@ int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, - double *lat, double *lon) +int32 GPS_Math_UKOSMap_To_WGS84_M(char* map, double mE, double mN, + double* lat, double* lon) { - double E; - double N; - double alat; - double alon; - double ht; - - if(!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) - return 0; + double E; + double N; + double alat; + double alon; + double ht; - GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); + if (!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) { + return 0; + } - GPS_Math_Known_Datum_To_WGS84_M(alat,alon,0,lat,lon,&ht,86); + GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); - return 1; + GPS_Math_Known_Datum_To_WGS84_M(alat,alon,0,lat,lon,&ht,86); + + return 1; } @@ -1900,24 +1917,25 @@ int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, - double *mN, char *map) +int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double* mE, + double* mN, char* map) { - double alat; - double alon; - double aht; - double aE; - double aN; + double alat; + double alon; + double aht; + double aE; + double aN; - GPS_Math_WGS84_To_Known_Datum_C(lat,lon,30,&alat,&alon,&aht,86); + GPS_Math_WGS84_To_Known_Datum_C(lat,lon,30,&alat,&alon,&aht,86); - GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); + GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); - if(!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) - return 0; + if (!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) { + return 0; + } - return 1; + return 1; } @@ -1935,23 +1953,24 @@ int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, - double *lat, double *lon) +int32 GPS_Math_UKOSMap_To_WGS84_C(char* map, double mE, double mN, + double* lat, double* lon) { - double E; - double N; - double alat; - double alon; - double ht; - - if(!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) - return 0; + double E; + double N; + double alat; + double alon; + double ht; + + if (!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) { + return 0; + } - GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); + GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); - GPS_Math_Known_Datum_To_WGS84_C(alat,alon,0,lat,lon,&ht,86); + GPS_Math_Known_Datum_To_WGS84_C(alat,alon,0,lat,lon,&ht,86); - return 1; + return 1; } @@ -1970,91 +1989,84 @@ int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, ** ** @return [int32] success ************************************************************************/ -static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32 *zone, - char *zc, double *Mc, double *E0, - double *N0, double *F0) +static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32* zone, + char* zc, double* Mc, double* E0, + double* N0, double* F0) { - int32 ilon; - int32 ilat; - int32 psign; - int32 lsign; - - if(lat >= (double)84.0 || lat < (double)-80.0) - return 0; - - psign = lsign = 0; - if(lon < (double)0.0) - lsign=1; - if(lat < (double)0.0) - psign=1; - - ilon = abs((int32)lon); - ilat = abs((int32)lat); - - if(!lsign) - { - *zone = 31 + (ilon / 6); - *Mc = (double)((ilon / 6) * 6 + 3); - } - else - { - *zone = 30 - (ilon / 6); - *Mc = -(double)((ilon / 6) * 6 + 3); + int32 ilon; + int32 ilat; + int32 psign; + int32 lsign; + + if (lat >= (double)84.0 || lat < (double)-80.0) { + return 0; + } + + psign = lsign = 0; + if (lon < (double)0.0) { + lsign=1; + } + if (lat < (double)0.0) { + psign=1; + } + + ilon = abs((int32)lon); + ilat = abs((int32)lat); + + if (!lsign) { + *zone = 31 + (ilon / 6); + *Mc = (double)((ilon / 6) * 6 + 3); + } else { + *zone = 30 - (ilon / 6); + *Mc = -(double)((ilon / 6) * 6 + 3); + } + + if (!psign) { + *zc = 'N' + ilat / 8; + if (*zc > 'N') { + ++*zc; } - - if(!psign) - { - *zc = 'N' + ilat / 8; - if(*zc > 'N') ++*zc; + } else { + *zc = 'M' - (ilat / 8); + if (*zc <= 'I') { + --*zc; } - else - { - *zc = 'M' - (ilat / 8); - if(*zc <= 'I') --*zc; + } + + + if (lat>=(double)56.0 && lat<(double)64.0 && lon>=(double)3.0 && + lon<(double)12.0) { + *zone = 32; + *zc = 'V'; + *Mc = (double)9.0; + } + + if (*zc=='X' && lon>=(double)0.0 && lon<(double)42.0) { + if (lon<(double)9.0) { + *zone = 31; + *Mc = (double)3.0; + } else if (lon<(double)21.0) { + *zone = 33; + *Mc = (double)15.0; + } else if (lon<(double)33.0) { + *zone = 35; + *Mc = (double)27.0; + } else { + *zone = 37; + *Mc = (double)39.0; } + } + if (!psign) { + *N0 = (double)0.0; + } else { + *N0 = (double)10000000; + } - if(lat>=(double)56.0 && lat<(double)64.0 && lon>=(double)3.0 && - lon<(double)12.0) - { - *zone = 32; - *zc = 'V'; - *Mc = (double)9.0; - } - - if(*zc=='X' && lon>=(double)0.0 && lon<(double)42.0) - { - if(lon<(double)9.0) - { - *zone = 31; - *Mc = (double)3.0; - } - else if(lon<(double)21.0) - { - *zone = 33; - *Mc = (double)15.0; - } - else if(lon<(double)33.0) - { - *zone = 35; - *Mc = (double)27.0; - } - else - { - *zone = 37; - *Mc = (double)39.0; - } - } - - if(!psign) - *N0 = (double)0.0; - else - *N0 = (double)10000000; - - *E0 = (double)500000; - *F0 = (double)0.9996; - - return 1; + *E0 = (double)500000; + *F0 = (double)0.9996; + + return 1; } @@ -2072,29 +2084,30 @@ static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32 *zone, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc) +int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double* E, + double* N, int32* zone, char* zc) { - double phi0; - double lambda0; - double N0; - double E0; - double F0; - double a; - double b; + double phi0; + double lambda0; + double N0; + double E0; + double F0; + double a; + double b; - if(!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, - &N0,&F0)) - return 0; + if (!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, + &N0,&F0)) { + return 0; + } - phi0 = (double)0.0; + phi0 = (double)0.0; - a = (double) GPS_Ellipse[21].a; - b = a - (a/GPS_Ellipse[21].invf); + a = (double) GPS_Ellipse[21].a; + b = a - (a/GPS_Ellipse[21].invf); - GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); + GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); - return 1; + return 1; } @@ -2112,18 +2125,19 @@ int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc) +int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double* E, + double* N, int32* zone, char* zc) { - double phi; - double lambda; - double H; - - GPS_Math_WGS84_To_Known_Datum_M(lat,lon,0,&phi,&lambda,&H,77); - if(!GPS_Math_NAD83_To_UTM_EN(phi,lambda,E,N,zone,zc)) - return 0; - - return 1; + double phi; + double lambda; + double H; + + GPS_Math_WGS84_To_Known_Datum_M(lat,lon,0,&phi,&lambda,&H,77); + if (!GPS_Math_NAD83_To_UTM_EN(phi,lambda,E,N,zone,zc)) { + return 0; + } + + return 1; } @@ -2142,39 +2156,47 @@ int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, ** ** @return [int32] success ************************************************************************/ -static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, - double *E0, double *N0, double *F0) +static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double* Mc, + double* E0, double* N0, double* F0) { - if(zone>60 || zone<0 || zc<'C' || zc>'X') - return 0; - - if(zone > 30) - *Mc = (double)((zone-31)*6) + (double)3.0; - else - *Mc = (double) -(((30-zone)*6)+3); - - if(zone==32 && zc=='V') - *Mc = (double)9.0; - - if(zone==31 && zc=='X') - *Mc = (double)3.0; - if(zone==33 && zc=='X') - *Mc = (double)15.0; - if(zone==35 && zc=='X') - *Mc = (double)27.0; - if(zone==37 && zc=='X') - *Mc = (double)39.0; - - if(zc>'M') - *N0 = (double)0.0; - else - *N0 = (double)10000000; - - *E0 = (double)500000; - *F0 = (double)0.9996; - - return 1; + if (zone>60 || zone<0 || zc<'C' || zc>'X') { + return 0; + } + + if (zone > 30) { + *Mc = (double)((zone-31)*6) + (double)3.0; + } else { + *Mc = (double) -(((30-zone)*6)+3); + } + + if (zone==32 && zc=='V') { + *Mc = (double)9.0; + } + + if (zone==31 && zc=='X') { + *Mc = (double)3.0; + } + if (zone==33 && zc=='X') { + *Mc = (double)15.0; + } + if (zone==35 && zc=='X') { + *Mc = (double)27.0; + } + if (zone==37 && zc=='X') { + *Mc = (double)39.0; + } + + if (zc>'M') { + *N0 = (double)0.0; + } else { + *N0 = (double)10000000; + } + + *E0 = (double)500000; + *F0 = (double)0.9996; + + return 1; } @@ -2192,10 +2214,10 @@ static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, - double N, int32 zone, char zc) +int32 GPS_Math_UTM_EN_To_NAD83(double* lat, double* lon, double E, + double N, int32 zone, char zc) { - return GPS_Math_UTM_EN_To_Known_Datum(lat, lon, E, N, zone, zc, 77); + return GPS_Math_UTM_EN_To_Known_Datum(lat, lon, E, N, zone, zc, 77); } @@ -2213,18 +2235,20 @@ int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, - double N, int32 zone, char zc) +int32 GPS_Math_UTM_EN_To_WGS84(double* lat, double* lon, double E, + double N, int32 zone, char zc) { - double lambda0; - double N0; - double E0; - double F0; + double lambda0; + double N0; + double E0; + double F0; - if (!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) return 0; + if (!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) { + return 0; + } - GPS_Math_UTM_EN_to_LatLon(GPS_Datum[118].ellipse, N, E, lat, lon, lambda0, E0, N0); - return 1; + GPS_Math_UTM_EN_to_LatLon(GPS_Datum[118].ellipse, N, E, lat, lon, lambda0, E0, N0); + return 1; } @@ -2242,31 +2266,32 @@ int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc, const int n) +int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double* E, + double* N, int32* zone, char* zc, const int n) { - double phi0; - double lambda0; - double N0; - double E0; - double F0; - double a; - double b; - int32 idx; - - if(!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, - &N0,&F0)) - return 0; - - phi0 = (double)0.0; - - idx = GPS_Datum[n].ellipse; - a = (double) GPS_Ellipse[idx].a; - b = a - (a/GPS_Ellipse[idx].invf); - - GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); - - return 1; + double phi0; + double lambda0; + double N0; + double E0; + double F0; + double a; + double b; + int32 idx; + + if (!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, + &N0,&F0)) { + return 0; + } + + phi0 = (double)0.0; + + idx = GPS_Datum[n].ellipse; + a = (double) GPS_Ellipse[idx].a; + b = a - (a/GPS_Ellipse[idx].invf); + + GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); + + return 1; } /* @func GPS_Math_UTM_EN_To_Known_Datum ********************************* @@ -2283,18 +2308,20 @@ int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, ** ** @return [int32] success ************************************************************************/ -int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, - double N, int32 zone, char zc, const int n) +int32 GPS_Math_UTM_EN_To_Known_Datum(double* lat, double* lon, double E, + double N, int32 zone, char zc, const int n) { - double lambda0; - double N0; - double E0; - double F0; + double lambda0; + double N0; + double E0; + double F0; - if (!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) return 0; + if (!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) { + return 0; + } - GPS_Math_UTM_EN_to_LatLon(GPS_Datum[n].ellipse, N, E, lat, lon, lambda0, E0, N0); - return 1; + GPS_Math_UTM_EN_to_LatLon(GPS_Datum[n].ellipse, N, E, lat, lon, lambda0, E0, N0); + return 1; } /* !!! copied from unused gpsproj.c !!! */ @@ -2316,65 +2343,65 @@ int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, ** ** @return [void] ***************************************************************************/ -void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, - double *N,double phi0,double lambda0, - double E0, double N0, double a, double b) +void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double* E, + double* N,double phi0,double lambda0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double esq; - double e; - double c; - double ephi0p; - double phip; - double sphip; - double phid; - double slambda2; - double lambda1; - double lambda2; - double K; - double po4; - double w; - double R; - - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - - po4=GPS_PI/(double)4.0; - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); - - ephi0p = asin(sin(phi0)/c); - - K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - - e/(double)2. * log(((double)1.+e*sin(phi0)) / - ((double)1.-e*sin(phi0)))); - lambda1 = c*(lambda-lambda0); - w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * - log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; - - - phip = (double)2. * (atan(exp(w)) - po4); - - sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); - phid = asin(sphip); - - slambda2 = cos(phip)*sin(lambda1) / cos(phid); - lambda2 = asin(slambda2); - - R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); - - *N = R*log(tan(po4 + phid/(double)2.)) + N0; - *E = R*lambda2 + E0; - return; + double a2; + double b2; + double esq; + double e; + double c; + double ephi0p; + double phip; + double sphip; + double phid; + double slambda2; + double lambda1; + double lambda2; + double K; + double po4; + double w; + double R; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + + po4=GPS_PI/(double)4.0; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); + + ephi0p = asin(sin(phi0)/c); + + K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - + e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + lambda1 = c*(lambda-lambda0); + w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; + + + phip = (double)2. * (atan(exp(w)) - po4); + + sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); + phid = asin(sphip); + + slambda2 = cos(phip)*sin(lambda1) / cos(phid); + lambda2 = asin(slambda2); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + *N = R*log(tan(po4 + phid/(double)2.)) + N0; + *E = R*lambda2 + E0; + return; } /* !!! copied from unused gpsproj.c !!! */ @@ -2397,160 +2424,158 @@ void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] *************************************************************************/ -void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b) +void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double esq; - double e; - double R; - double c; - double po4; - double phid; - double phi1; - double lambdad; - double lambda1; - double slambda1; - double ephi0p; - double sphip; - double tol; - double cr; - double C; - double K; - - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - - po4=GPS_PI/(double)4.0; - tol=(double)0.00001; - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); - - phid = (double)2.*(atan(exp((N - N0)/R)) - po4); - lambdad = (E - E0)/R; - - c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / - ((double)1.-esq))); - ephi0p = asin(sin(phi0) / c); - - sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); - phi1 = asin(sphip); - - slambda1 = cos(phid)*sin(lambdad)/cos(phi1); - lambda1 = asin(slambda1); - - *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); - - K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) - - e/(double)2. * log(((double)1.+e*sin(phi0)) / - ((double)1.-e*sin(phi0)))); - C = (K - log(tan(po4 + phi1/(double)2.)))/c; - - do - { - cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * - log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * - ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / - ((double)1.-esq)); - phi1 -= cr; - } - while (fabs(cr) > tol); - - *phi = GPS_Math_Rad_To_Deg(phi1); - - return; + double a2; + double b2; + double esq; + double e; + double R; + double c; + double po4; + double phid; + double phi1; + double lambdad; + double lambda1; + double slambda1; + double ephi0p; + double sphip; + double tol; + double cr; + double C; + double K; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + + po4=GPS_PI/(double)4.0; + tol=(double)0.00001; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + phid = (double)2.*(atan(exp((N - N0)/R)) - po4); + lambdad = (E - E0)/R; + + c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / + ((double)1.-esq))); + ephi0p = asin(sin(phi0) / c); + + sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); + phi1 = asin(sphip); + + slambda1 = cos(phid)*sin(lambdad)/cos(phi1); + lambda1 = asin(slambda1); + + *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); + + K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) + - e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + C = (K - log(tan(po4 + phi1/(double)2.)))/c; + + do { + cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * + ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / + ((double)1.-esq)); + phi1 -= cr; + } while (fabs(cr) > tol); + + *phi = GPS_Math_Rad_To_Deg(phi1); + + return; } /********************************************************************/ -void GPS_Math_UTM_EN_to_LatLon(int ReferenceEllipsoid, - const double UTMNorthing, const double UTMEasting, - double *Lat, double *Lon, - const double lambda0, - const double E0, - const double N0) +void GPS_Math_UTM_EN_to_LatLon(int ReferenceEllipsoid, + const double UTMNorthing, const double UTMEasting, + double* Lat, double* Lon, + const double lambda0, + const double E0, + const double N0) { -//converts UTM coords to lat/long. Equations from USGS Bulletin 1532 -//East Longitudes are positive, West longitudes are negative. +//converts UTM coords to lat/long. Equations from USGS Bulletin 1532 +//East Longitudes are positive, West longitudes are negative. //North latitudes are positive, South latitudes are negative -//Lat and Long are in decimal degrees. +//Lat and Long are in decimal degrees. //based on code witten by Chuck Gantz- chuck.gantz@globalstar.com //found at http://www.gpsy.com/gpsinfo/geotoutm/index.html - double k0 = 0.9996; - double a, b; - double eccSquared; - double eccPrimeSquared; - double e1; - double N1, T1, C1, R1, D, M; - double mu, phi1, phi1Rad; - double x, y; - - a = GPS_Ellipse[ReferenceEllipsoid].a; - b = 1 / GPS_Ellipse[ReferenceEllipsoid].invf; - eccSquared = b * (2.0 - b); - e1 = (1-sqrt(1-eccSquared))/(1+sqrt(1-eccSquared)); - - x = UTMEasting - E0; //remove false easting - y = UTMNorthing - N0; //remove false northing - - eccPrimeSquared = (eccSquared)/(1-eccSquared); - - M = y / k0; - mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256)); - - phi1Rad = mu+ (3*e1/2-27*e1*e1*e1/32)*sin(2*mu) + - (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu) + - (151*e1*e1*e1/96)*sin(6*mu); - phi1 = GPS_Math_Rad_To_Deg(phi1Rad); - - N1 = a/sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad)); - T1 = tan(phi1Rad)*tan(phi1Rad); - C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad); - R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5); - D = x/(N1*k0); - - *Lat = phi1Rad - (N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24 - +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720); - *Lat = GPS_Math_Rad_To_Deg(*Lat); - - *Lon = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)*D*D*D*D*D/120)/cos(phi1Rad); - *Lon = lambda0 + GPS_Math_Rad_To_Deg(*Lon); + double k0 = 0.9996; + double a, b; + double eccSquared; + double eccPrimeSquared; + double e1; + double N1, T1, C1, R1, D, M; + double mu, phi1, phi1Rad; + double x, y; + + a = GPS_Ellipse[ReferenceEllipsoid].a; + b = 1 / GPS_Ellipse[ReferenceEllipsoid].invf; + eccSquared = b * (2.0 - b); + e1 = (1-sqrt(1-eccSquared))/(1+sqrt(1-eccSquared)); + + x = UTMEasting - E0; //remove false easting + y = UTMNorthing - N0; //remove false northing + + eccPrimeSquared = (eccSquared)/(1-eccSquared); + + M = y / k0; + mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256)); + + phi1Rad = mu+ (3*e1/2-27*e1*e1*e1/32)*sin(2*mu) + + (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu) + + (151*e1*e1*e1/96)*sin(6*mu); + phi1 = GPS_Math_Rad_To_Deg(phi1Rad); + + N1 = a/sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad)); + T1 = tan(phi1Rad)*tan(phi1Rad); + C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad); + R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5); + D = x/(N1*k0); + + *Lat = phi1Rad - (N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24 + +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720); + *Lat = GPS_Math_Rad_To_Deg(*Lat); + + *Lon = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)*D*D*D*D*D/120)/cos(phi1Rad); + *Lon = lambda0 + GPS_Math_Rad_To_Deg(*Lon); } /********************************************************************/ -int32 GPS_Lookup_Datum_Index(const char *n) +int32 GPS_Lookup_Datum_Index(const char* n) { - GPS_PDatum dp; - GPS_PDatum_Alias al; - - for (al = GPS_DatumAlias; al->alias; al++) { - if (case_ignore_strcmp(al->alias, n) == 0) { - return al->datum; - } - } - - for (dp = GPS_Datum; dp->name; dp++) { - if (0 == case_ignore_strcmp(dp->name, n)) { - return dp - GPS_Datum; - } - } - - return -1; + GPS_PDatum dp; + GPS_PDatum_Alias al; + + for (al = GPS_DatumAlias; al->alias; al++) { + if (case_ignore_strcmp(al->alias, n) == 0) { + return al->datum; + } + } + + for (dp = GPS_Datum; dp->name; dp++) { + if (0 == case_ignore_strcmp(dp->name, n)) { + return dp - GPS_Datum; + } + } + + return -1; } -char * +char* GPS_Math_Get_Datum_Name(const int datum_index) { - return GPS_Datum[datum_index].name; + return GPS_Datum[datum_index].name; } diff --git a/gpsbabel/jeeps/gpsmath.h b/gpsbabel/jeeps/gpsmath.h index dbd8b51a5..c1ac21145 100644 --- a/gpsbabel/jeeps/gpsmath.h +++ b/gpsbabel/jeeps/gpsmath.h @@ -14,134 +14,134 @@ extern "C" #define GPS_FLTMAX 3.402823466E+38 -double GPS_Math_Deg_To_Rad(double v); -double GPS_Math_Rad_To_Deg(double v); - -double GPS_Math_Metres_To_Feet(double v); -double GPS_Math_Feet_To_Metres(double v); - -int32 GPS_Math_Deg_To_Semi(double v); -double GPS_Math_Semi_To_Deg(int32 v); - -time_t GPS_Math_Utime_To_Gtime(time_t v); -time_t GPS_Math_Gtime_To_Utime(time_t v); - -void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m); -void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg); -void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s); -void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg); - - -void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, - double *N); -void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, - double *N); -int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, - double *mN, char *map); -int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, - double *E, double *N); - -void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z, - double a, double b); -void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z, - double a, double b); - -void GPS_Math_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double N0, double E0, - double phi0, double lambda0, - double F0, double a, double b); -void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, - double lambda, double N0, double E0, - double phi0, double lambda0, - double F0, double a, double b); - -void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, - double *lambda); -void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, - double *lambda); - - -void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z); -void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z); -void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z); -void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z); - -void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, - double Sif, double *Dphi, double *Dlam, - double *DH, double Da, double Dif, double dx, - double dy, double dz); -void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n); -void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n); -void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n); -void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n); - -void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, - double *DH, int32 n1, int32 n2); -void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, - double *DH, int32 n1, int32 n2); - -int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, - double *mN, char *map); -int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, - double *lat, double *lon); -int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, - double *mN, char *map); -int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, - double *lat, double *lon); - - -int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc); -int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc); - -int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, - double N, int32 zone, char zc); -int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, - double N, int32 zone, char zc); - -int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc, const int n); -int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, - double N, int32 zone, char zc, const int n); - -void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, - double *N,double phi0,double lambda0, - double E0, double N0, double a, double b); -void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b); - -int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double *E, - double *N); -void GPS_Math_ICS_EN_To_WGS84(double E, double N, double *lat, double *lon); - -int32 GPS_Math_WGS84_To_Swiss_EN(double phi, double lambda, double *E, double *N); -void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double *lat, double *lon); - -void GPS_Math_UTM_EN_to_LatLon(int ReferenceEllipsoid, - const double UTMNorthing, const double UTMEasting, - double *Lat, double *Lon, - const double lambda0, const double E0, const double N0); - -int32 GPS_Lookup_Datum_Index(const char *n); -char *GPS_Math_Get_Datum_Name(const int datum_index); + double GPS_Math_Deg_To_Rad(double v); + double GPS_Math_Rad_To_Deg(double v); + + double GPS_Math_Metres_To_Feet(double v); + double GPS_Math_Feet_To_Metres(double v); + + int32 GPS_Math_Deg_To_Semi(double v); + double GPS_Math_Semi_To_Deg(int32 v); + + time_t GPS_Math_Utime_To_Gtime(time_t v); + time_t GPS_Math_Gtime_To_Utime(time_t v); + + void GPS_Math_Deg_To_DegMin(double v, int32* d, double* m); + void GPS_Math_DegMin_To_Deg(int32 d, double m, double* deg); + void GPS_Math_Deg_To_DegMinSec(double v, int32* d, int32* m, double* s); + void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double* deg); + + + void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double* E, + double* N); + void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double* E, + double* N); + int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double* mE, + double* mN, char* map); + int32 GPS_Math_UKOSNG_Map_To_EN(char* map, double mapE, double mapN, + double* E, double* N); + + void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, + double* x, double* y, double* z, + double a, double b); + void GPS_Math_XYZ_To_LatLonH(double* phi, double* lambda, double* H, + double x, double y, double z, + double a, double b); + + void GPS_Math_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b); + void GPS_Math_LatLon_To_EN(double* E, double* N, double phi, + double lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b); + + void GPS_Math_NGENToAiry1830LatLon(double E, double N, double* phi, + double* lambda); + void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double* phi, + double* lambda); + + + void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, + double* x, double* y, double* z); + void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, + double* x, double* y, double* z); + void GPS_Math_XYZ_To_Airy1830LatLonH(double* phi, double* lambda, double* H, + double x, double y, double z); + void GPS_Math_XYZ_To_WGS84LatLonH(double* phi, double* lambda, double* H, + double x, double y, double z); + + void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, + double Sif, double* Dphi, double* Dlam, + double* DH, double Da, double Dif, double dx, + double dy, double dz); + void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, + double* Dphi, double* Dlam, double* DH, + int32 n); + void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, + double* Dphi, double* Dlam, double* DH, + int32 n); + void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, + double* Dphi, double* Dlam, double* DH, + int32 n); + void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, + double* Dphi, double* Dlam, double* DH, + int32 n); + + void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, + double* Dphi, double* Dlam, + double* DH, int32 n1, int32 n2); + void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, + double* Dphi, double* Dlam, + double* DH, int32 n1, int32 n2); + + int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double* mE, + double* mN, char* map); + int32 GPS_Math_UKOSMap_To_WGS84_M(char* map, double mE, double mN, + double* lat, double* lon); + int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double* mE, + double* mN, char* map); + int32 GPS_Math_UKOSMap_To_WGS84_C(char* map, double mE, double mN, + double* lat, double* lon); + + + int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double* E, + double* N, int32* zone, char* zc); + int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double* E, + double* N, int32* zone, char* zc); + + int32 GPS_Math_UTM_EN_To_WGS84(double* lat, double* lon, double E, + double N, int32 zone, char zc); + int32 GPS_Math_UTM_EN_To_NAD83(double* lat, double* lon, double E, + double N, int32 zone, char zc); + + int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double* E, + double* N, int32* zone, char* zc, const int n); + int32 GPS_Math_UTM_EN_To_Known_Datum(double* lat, double* lon, double E, + double N, int32 zone, char zc, const int n); + + void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double* E, + double* N,double phi0,double lambda0, + double E0, double N0, double a, double b); + void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double lambda0, + double E0, double N0, double a, double b); + + int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double* E, + double* N); + void GPS_Math_ICS_EN_To_WGS84(double E, double N, double* lat, double* lon); + + int32 GPS_Math_WGS84_To_Swiss_EN(double phi, double lambda, double* E, double* N); + void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double* lat, double* lon); + + void GPS_Math_UTM_EN_to_LatLon(int ReferenceEllipsoid, + const double UTMNorthing, const double UTMEasting, + double* Lat, double* Lon, + const double lambda0, const double E0, const double N0); + + int32 GPS_Lookup_Datum_Index(const char* n); + char* GPS_Math_Get_Datum_Name(const int datum_index); #endif diff --git a/gpsbabel/jeeps/gpsmem.c b/gpsbabel/jeeps/gpsmem.c index 8425422ec..bc0923532 100644 --- a/gpsbabel/jeeps/gpsmem.c +++ b/gpsbabel/jeeps/gpsmem.c @@ -2,23 +2,23 @@ ** @source JEEPS constructor and deconstructor functions ** ** @author Copyright (C) 1999,2000 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified December 28th 1999 Alan Bleasby. First version ** @modified June 29th 2000 Alan Bleasby. NMEA additions ** @modified Copyright (C) 2006 Robert Lipe ** @modified Copyright (C) 2007 Achim Schumacher ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -39,25 +39,24 @@ GPS_PPacket GPS_Packet_New(void) { - GPS_PPacket ret; - int hdr_size = sizeof(GPS_OPacket) ; - if(!(ret=(GPS_PPacket )calloc(1, hdr_size))) - - { - perror("malloc"); - fprintf(stderr,"GPS_Packet_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - if(!(ret->data = (UC *)calloc(1, MAX_GPS_PACKET_SIZE*sizeof(UC)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Packet_New: Insufficient data memory"); - fflush(stderr); - return NULL; - } - - return ret; + GPS_PPacket ret; + int hdr_size = sizeof(GPS_OPacket) ; + if (!(ret=(GPS_PPacket)calloc(1, hdr_size))) + + { + perror("malloc"); + fprintf(stderr,"GPS_Packet_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + if (!(ret->data = (UC*)calloc(1, MAX_GPS_PACKET_SIZE*sizeof(UC)))) { + perror("malloc"); + fprintf(stderr,"GPS_Packet_New: Insufficient data memory"); + fflush(stderr); + return NULL; + } + + return ret; } @@ -70,12 +69,12 @@ GPS_PPacket GPS_Packet_New(void) ** @return [void] **********************************************************************/ -void GPS_Packet_Del(GPS_PPacket *thys) +void GPS_Packet_Del(GPS_PPacket* thys) { - free((void *)(*thys)->data); - free((void *)*thys); + free((void*)(*thys)->data); + free((void*)*thys); - return; + return; } @@ -89,17 +88,16 @@ void GPS_Packet_Del(GPS_PPacket *thys) GPS_PPvt_Data GPS_Pvt_New(void) { - GPS_PPvt_Data ret; - - if(!(ret=(GPS_PPvt_Data)calloc(1, sizeof(GPS_OPvt_Data)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Pvt_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - return ret; + GPS_PPvt_Data ret; + + if (!(ret=(GPS_PPvt_Data)calloc(1, sizeof(GPS_OPvt_Data)))) { + perror("malloc"); + fprintf(stderr,"GPS_Pvt_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; } @@ -113,11 +111,11 @@ GPS_PPvt_Data GPS_Pvt_New(void) ** @return [void] **********************************************************************/ -void GPS_Pvt_Del(GPS_PPvt_Data *thys) +void GPS_Pvt_Del(GPS_PPvt_Data* thys) { - free((void *)*thys); + free((void*)*thys); - return; + return; } @@ -131,21 +129,20 @@ void GPS_Pvt_Del(GPS_PPvt_Data *thys) GPS_PAlmanac GPS_Almanac_New(void) { - GPS_PAlmanac ret; - - if(!(ret=(GPS_PAlmanac)calloc(1, sizeof(GPS_OAlmanac)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Almanac_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - ret->svid=0xff; - ret->wn = -1; - ret->hlth=0xff; - - return ret; + GPS_PAlmanac ret; + + if (!(ret=(GPS_PAlmanac)calloc(1, sizeof(GPS_OAlmanac)))) { + perror("malloc"); + fprintf(stderr,"GPS_Almanac_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + ret->svid=0xff; + ret->wn = -1; + ret->hlth=0xff; + + return ret; } @@ -159,11 +156,11 @@ GPS_PAlmanac GPS_Almanac_New(void) ** @return [void] **********************************************************************/ -void GPS_Almanac_Del(GPS_PAlmanac *thys) +void GPS_Almanac_Del(GPS_PAlmanac* thys) { - free((void *)*thys); + free((void*)*thys); - return; + return; } @@ -177,17 +174,16 @@ void GPS_Almanac_Del(GPS_PAlmanac *thys) GPS_PTrack GPS_Track_New(void) { - GPS_PTrack ret; - - if(!(ret=(GPS_PTrack)calloc(1,sizeof(GPS_OTrack)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Track_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - return ret; + GPS_PTrack ret; + + if (!(ret=(GPS_PTrack)calloc(1,sizeof(GPS_OTrack)))) { + perror("malloc"); + fprintf(stderr,"GPS_Track_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; } @@ -201,11 +197,11 @@ GPS_PTrack GPS_Track_New(void) ** @return [void] **********************************************************************/ -void GPS_Track_Del(GPS_PTrack *thys) +void GPS_Track_Del(GPS_PTrack* thys) { - free((void *)*thys); + free((void*)*thys); - return; + return; } @@ -219,62 +215,65 @@ void GPS_Track_Del(GPS_PTrack *thys) GPS_PWay GPS_Way_New(void) { - GPS_PWay ret; - int32 i; - - if(!(ret=(GPS_PWay)xcalloc(sizeof(GPS_OWay),1))) - { - perror("malloc"); - fprintf(stderr,"GPS_Way_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - /* - * It turns out that the Way struct, initialized with zeros (not the - * random stuff that we got with malloc, but REALLY initialized with - * zeros from the calloc above actually does use C strings and it's - * up to the various way_blah_send functions to zero/string pad things - * as it goes. So neutralize this. - */ + GPS_PWay ret; + int32 i; + + if (!(ret=(GPS_PWay)xcalloc(sizeof(GPS_OWay),1))) { + perror("malloc"); + fprintf(stderr,"GPS_Way_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + /* + * It turns out that the Way struct, initialized with zeros (not the + * random stuff that we got with malloc, but REALLY initialized with + * zeros from the calloc above actually does use C strings and it's + * up to the various way_blah_send functions to zero/string pad things + * as it goes. So neutralize this. + */ #if 0 - /* - * Mark all as "unused". These appear in the same order as in the struct. - */ + /* + * Mark all as "unused". These appear in the same order as in the struct. + */ #define BLANK(x) memset(x, ' ',sizeof(x)) - BLANK(ret->ident); - BLANK(ret->cmnt); - BLANK(ret->wpt_ident); - BLANK(ret->lnk_ident); - BLANK(ret->subclass); - BLANK(ret->name); - BLANK(ret->facility); - BLANK(ret->addr); - BLANK(ret->cross_road); - BLANK(ret->city); - BLANK(ret->rte_cmnt); - BLANK(ret->rte_ident); - BLANK(ret->rte_link_subclass); - BLANK(ret->rte_link_ident); - BLANK(ret->state); - BLANK(ret->cc); - - ret->facility[0] = 0; - ret->addr[0] = 0; - ret->wpt_ident[0] = 0; + BLANK(ret->ident); + BLANK(ret->cmnt); + BLANK(ret->wpt_ident); + BLANK(ret->lnk_ident); + BLANK(ret->subclass); + BLANK(ret->name); + BLANK(ret->facility); + BLANK(ret->addr); + BLANK(ret->cross_road); + BLANK(ret->city); + BLANK(ret->rte_cmnt); + BLANK(ret->rte_ident); + BLANK(ret->rte_link_subclass); + BLANK(ret->rte_link_ident); + BLANK(ret->state); + BLANK(ret->cc); + + ret->facility[0] = 0; + ret->addr[0] = 0; + ret->wpt_ident[0] = 0; #endif - - ret->lat = ret->lon = GPS_FLTMAX; - ret->dst = 0; - ret->smbl = ret->dspl = ret->colour = ret->alt = ret->prot = INT_MAX; - - ret->dst = 0; - ret->attr = 0x60; - for(i=0;i<7;++i) ret->subclass[i] = 0; - for(i=6;i<18;++i) ret->subclass[i] = 0xff; - - return ret; + + ret->lat = ret->lon = GPS_FLTMAX; + ret->dst = 0; + ret->smbl = ret->dspl = ret->colour = ret->alt = ret->prot = INT_MAX; + + ret->dst = 0; + ret->attr = 0x60; + for (i=0; i<7; ++i) { + ret->subclass[i] = 0; + } + for (i=6; i<18; ++i) { + ret->subclass[i] = 0xff; + } + + return ret; } @@ -288,11 +287,11 @@ GPS_PWay GPS_Way_New(void) ** @return [void] **********************************************************************/ -void GPS_Way_Del(GPS_PWay *thys) +void GPS_Way_Del(GPS_PWay* thys) { - xfree((void *)*thys); + xfree((void*)*thys); - return; + return; } /* @func GPS_Lap_New *********************************************** @@ -304,17 +303,16 @@ void GPS_Way_Del(GPS_PWay *thys) GPS_PLap GPS_Lap_New(void) { - GPS_PLap ret; - - if(!(ret=(GPS_PLap)calloc(1,sizeof(GPS_OLap)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Lap_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - return ret; + GPS_PLap ret; + + if (!(ret=(GPS_PLap)calloc(1,sizeof(GPS_OLap)))) { + perror("malloc"); + fprintf(stderr,"GPS_Lap_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; } @@ -328,11 +326,11 @@ GPS_PLap GPS_Lap_New(void) ** @return [void] **********************************************************************/ -void GPS_Lap_Del(GPS_PLap *thys) +void GPS_Lap_Del(GPS_PLap* thys) { - free((void *)*thys); + free((void*)*thys); - return; + return; } @@ -344,17 +342,16 @@ void GPS_Lap_Del(GPS_PLap *thys) **********************************************************************/ GPS_PCourse GPS_Course_New(void) { - GPS_PCourse ret; + GPS_PCourse ret; - if(!(ret=(GPS_PCourse)calloc(1,sizeof(GPS_OCourse)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Course_New: Insufficient memory"); - fflush(stderr); - return NULL; - } + if (!(ret=(GPS_PCourse)calloc(1,sizeof(GPS_OCourse)))) { + perror("malloc"); + fprintf(stderr,"GPS_Course_New: Insufficient memory"); + fflush(stderr); + return NULL; + } - return ret; + return ret; } @@ -367,11 +364,11 @@ GPS_PCourse GPS_Course_New(void) ** ** @return [void] **********************************************************************/ -void GPS_Course_Del(GPS_PCourse *thys) +void GPS_Course_Del(GPS_PCourse* thys) { - free((void *)*thys); + free((void*)*thys); - return; + return; } /* @func GPS_Course_Lap_New *********************************************** @@ -383,17 +380,16 @@ void GPS_Course_Del(GPS_PCourse *thys) GPS_PCourse_Lap GPS_Course_Lap_New(void) { - GPS_PCourse_Lap ret; + GPS_PCourse_Lap ret; - if(!(ret=(GPS_PCourse_Lap)calloc(1,sizeof(GPS_OCourse_Lap)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Course_Lap_New: Insufficient memory"); - fflush(stderr); - return NULL; - } + if (!(ret=(GPS_PCourse_Lap)calloc(1,sizeof(GPS_OCourse_Lap)))) { + perror("malloc"); + fprintf(stderr,"GPS_Course_Lap_New: Insufficient memory"); + fflush(stderr); + return NULL; + } - return ret; + return ret; } @@ -407,11 +403,11 @@ GPS_PCourse_Lap GPS_Course_Lap_New(void) ** @return [void] **********************************************************************/ -void GPS_Course_Lap_Del(GPS_PCourse_Lap *thys) +void GPS_Course_Lap_Del(GPS_PCourse_Lap* thys) { - free((void *)*thys); + free((void*)*thys); - return; + return; } /* @func GPS_Course_Point_New *********************************************** @@ -423,17 +419,16 @@ void GPS_Course_Lap_Del(GPS_PCourse_Lap *thys) GPS_PCourse_Point GPS_Course_Point_New(void) { - GPS_PCourse_Point ret; + GPS_PCourse_Point ret; - if(!(ret=(GPS_PCourse_Point)calloc(1,sizeof(GPS_OCourse_Point)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Course_Point_New: Insufficient memory"); - fflush(stderr); - return NULL; - } + if (!(ret=(GPS_PCourse_Point)calloc(1,sizeof(GPS_OCourse_Point)))) { + perror("malloc"); + fprintf(stderr,"GPS_Course_Point_New: Insufficient memory"); + fflush(stderr); + return NULL; + } - return ret; + return ret; } @@ -447,9 +442,9 @@ GPS_PCourse_Point GPS_Course_Point_New(void) ** @return [void] **********************************************************************/ -void GPS_Course_Point_Del(GPS_PCourse_Point *thys) +void GPS_Course_Point_Del(GPS_PCourse_Point* thys) { - free((void *)*thys); + free((void*)*thys); - return; + return; } diff --git a/gpsbabel/jeeps/gpsmem.h b/gpsbabel/jeeps/gpsmem.h index 91292f7d6..bcf9e71cc 100644 --- a/gpsbabel/jeeps/gpsmem.h +++ b/gpsbabel/jeeps/gpsmem.h @@ -9,24 +9,24 @@ extern "C" #include "gps.h" -GPS_PPacket GPS_Packet_New(void); -void GPS_Packet_Del(GPS_PPacket *thys); -GPS_PPvt_Data GPS_Pvt_New(void); -void GPS_Pvt_Del(GPS_PPvt_Data *thys); -GPS_PAlmanac GPS_Almanac_New(void); -void GPS_Almanac_Del(GPS_PAlmanac *thys); -GPS_PTrack GPS_Track_New(void); -void GPS_Track_Del(GPS_PTrack *thys); -GPS_PWay GPS_Way_New(void); -void GPS_Way_Del(GPS_PWay *thys); -GPS_PLap GPS_Lap_New(void); -void GPS_Lap_Del(GPS_PLap *thys); -GPS_PCourse GPS_Course_New(void); -void GPS_Course_Del(GPS_PCourse *thys); -GPS_PCourse_Lap GPS_Course_Lap_New(void); -void GPS_Course_Lap_Del(GPS_PCourse_Lap *thys); -GPS_PCourse_Point GPS_Course_Point_New(void); -void GPS_Course_Point_Del(GPS_PCourse_Point *thys); + GPS_PPacket GPS_Packet_New(void); + void GPS_Packet_Del(GPS_PPacket* thys); + GPS_PPvt_Data GPS_Pvt_New(void); + void GPS_Pvt_Del(GPS_PPvt_Data* thys); + GPS_PAlmanac GPS_Almanac_New(void); + void GPS_Almanac_Del(GPS_PAlmanac* thys); + GPS_PTrack GPS_Track_New(void); + void GPS_Track_Del(GPS_PTrack* thys); + GPS_PWay GPS_Way_New(void); + void GPS_Way_Del(GPS_PWay* thys); + GPS_PLap GPS_Lap_New(void); + void GPS_Lap_Del(GPS_PLap* thys); + GPS_PCourse GPS_Course_New(void); + void GPS_Course_Del(GPS_PCourse* thys); + GPS_PCourse_Lap GPS_Course_Lap_New(void); + void GPS_Course_Lap_Del(GPS_PCourse_Lap* thys); + GPS_PCourse_Point GPS_Course_Point_New(void); + void GPS_Course_Point_Del(GPS_PCourse_Point* thys); #endif diff --git a/gpsbabel/jeeps/gpsproj.c b/gpsbabel/jeeps/gpsproj.c index c2634b370..3ecbcf71d 100644 --- a/gpsbabel/jeeps/gpsproj.c +++ b/gpsbabel/jeeps/gpsproj.c @@ -2,20 +2,20 @@ ** @source JEEPS projection functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Feb 04 2000 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -46,117 +46,120 @@ ** ** @return [void] ************************************************************************/ -void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) { - double dlambda; - double phis; - double phic; - double e; - double esq; - double esqs; - double omesqs2; - - double a2; - double b2; - double q; - double q0; - double q1; - double q2; - double m1; - double m2; - double n; - double phi0s; - double phi1s; - double phi1c; - double phi2s; - double phi2c; - double ess; - double om0; - double m1sq; - double C; - double nq; - double nq0; - double rho; - double rho0; - double theta; - - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi1 = GPS_Math_Deg_To_Rad(phi1); - phi2 = GPS_Math_Deg_To_Rad(phi2); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - dlambda = lambda - M0; - if(dlambda > GPS_PI) - dlambda -= ((double)2.0 * GPS_PI); - if(dlambda < -GPS_PI) - dlambda += ((double)2.0 * GPS_PI); - - phis = sin(phi); - phic = cos(phi); - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - - phi0s = sin(phi0); - ess = e * phi0s; - om0 = ((double)1.0 - ess*ess); - q0 = ((double)1.0 - esq) * (phi0s / om0-((double)1.0/(e+e)) * - log(((double)1.0-ess)/((double)1.0+ess))); - phi1s = sin(phi1); - phi1c = cos(phi1); - ess = e * phi1s; - om0 = ((double)1.0 - ess*ess); - m1 = phi1c/pow(om0,(double)0.5); - q1 = ((double)1.0 - esq) * (phi1s / om0-((double)1.0/(e+e)) * - log(((double)1.0-ess)/((double)1.0+ess))); - - m1sq = m1*m1; - if(fabs(phi1-phi2)>1.0e-10) - { - phi2s = sin(phi2); - phi2c = cos(phi2); - ess = e * phi2s; - om0 = ((double)1.0 - ess*ess); - m2 = phi2c/pow(om0,(double)0.5); - q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * - log(((double)1.0-ess)/((double)1.0+ess))); - n = (m1sq - m2*m2) / (q2-q1); - } - else - n = phi1s; - - C = m1sq + n*q1; - nq0 = n * q0; - if(C < nq0) - rho0 = (double)0.; - else - rho0 = (a/n) * pow(C-nq0,(double)0.5); - - - esqs = e * phis; - omesqs2 = ((double)1.0 - esqs*esqs); - q = ((double)1.0 - esq) * (phis / omesqs2-((double)1.0/(e+e)) * - log(((double)1.0-esqs)/((double)1.0+esqs))); - nq = n*q; - if(C GPS_PI) { + dlambda -= ((double)2.0 * GPS_PI); + } + if (dlambda < -GPS_PI) { + dlambda += ((double)2.0 * GPS_PI); + } + + phis = sin(phi); + phic = cos(phi); + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + + phi0s = sin(phi0); + ess = e * phi0s; + om0 = ((double)1.0 - ess*ess); + q0 = ((double)1.0 - esq) * (phi0s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + om0 = ((double)1.0 - ess*ess); + m1 = phi1c/pow(om0,(double)0.5); + q1 = ((double)1.0 - esq) * (phi1s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + + m1sq = m1*m1; + if (fabs(phi1-phi2)>1.0e-10) { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + om0 = ((double)1.0 - ess*ess); + m2 = phi2c/pow(om0,(double)0.5); + q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + n = (m1sq - m2*m2) / (q2-q1); + } else { + n = phi1s; + } + + C = m1sq + n*q1; + nq0 = n * q0; + if (C < nq0) { + rho0 = (double)0.; + } else { + rho0 = (a/n) * pow(C-nq0,(double)0.5); + } + + + esqs = e * phis; + omesqs2 = ((double)1.0 - esqs*esqs); + q = ((double)1.0 - esq) * (phis / omesqs2-((double)1.0/(e+e)) * + log(((double)1.0-esqs)/((double)1.0+esqs))); + nq = n*q; + if (C1.0e-10) - { - phi2s = sin(phi2); - phi2c = cos(phi2); - ess = e * phi2s; - om0 = ((double)1.0 - ess*ess); - m2 = phi2c/pow(om0,(double)0.5); - q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * - log(((double)1.0-ess)/((double)1.0+ess))); - n = (m1sq - m2*m2) / (q2-q1); + double po2; + double rho; + double rho0; + double C; + double a2; + double b2; + double esq; + double e; + double phi0s; + double q0; + double q1; + double q2; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double m1; + double m1sq; + double m2; + double n; + double nq0; + + double dx; + double dy; + double rhom; + double q; + double qc; + double qd2; + double rhon; + double lat; + double dphi; + double phis; + double ess; + double om0; + double theta; + double tol; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + M0 = GPS_Math_Deg_To_Rad(M0); + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + + phi0s = sin(phi0); + ess = e * phi0s; + om0 = ((double)1.0 - ess*ess); + q0 = ((double)1.0 - esq) * (phi0s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + om0 = ((double)1.0 - ess*ess); + m1 = phi1c/pow(om0,(double)0.5); + q1 = ((double)1.0 - esq) * (phi1s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + + m1sq = m1*m1; + if (fabs(phi1-phi2)>1.0e-10) { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + om0 = ((double)1.0 - ess*ess); + m2 = phi2c/pow(om0,(double)0.5); + q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + n = (m1sq - m2*m2) / (q2-q1); + } else { + n = phi1s; + } + + C = m1sq + n*q1; + nq0 = n * q0; + if (C < nq0) { + rho0 = (double)0.; + } else { + rho0 = (a/n) * pow(C-nq0,(double)0.5); + } + + + dphi = (double) 1.0; + theta = (double) 0.0; + tol = (double) 4.85e-10; + po2 = (double)GPS_PI / (double)2.0; + + dy = N-N0; + dx = E-E0; + rhom = rho0-dy; + rho = pow(dx*dx+rhom*rhom,(double)0.5); + + if (n<0.0) { + rho *= (double)-1.0; + dx *= (double)-1.0; + dy *= (double)-1.0; + rhom *= (double)-1.0; + } + + if (rho) { + theta = atan2(dx,rhom); + } + rhon = rho*n; + q = (C - (rhon*rhon) / a2) / n; + qc = (double)1.0 - ((double)1.0 / (e+e)) * + log(((double)1.0-e)/((double)1.0+e)); + if (fabs(fabs(qc)-fabs(q))>1.9e-6) { + qd2 = q/(double)2.0; + if (qd2>1.0) { + *phi = po2; + } else if (qd2<-1.0) { + *phi = -po2; + } else { + lat = asin(qd2); + if (e<1.0e-10) { + *phi = lat; + } else { + while (fabs(dphi)>tol) { + phis = sin(lat); + ess = e*phis; + om0 = ((double)1.0 - ess*ess); + dphi = (om0*om0) / ((double)2.0*cos(lat))* + (q/((double)1.0-esq) - phis / om0 + + (log(((double)1.0-ess)/((double)1.0+ess)) / + (e+e))); + lat += dphi; + } + *phi = lat; + } + + if (*phi > po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } } - else - n = phi1s; - - C = m1sq + n*q1; - nq0 = n * q0; - if(C < nq0) - rho0 = (double)0.; - else - rho0 = (a/n) * pow(C-nq0,(double)0.5); - - - dphi = (double) 1.0; - theta = (double) 0.0; - tol = (double) 4.85e-10; - po2 = (double)GPS_PI / (double)2.0; - - dy = N-N0; - dx = E-E0; - rhom = rho0-dy; - rho = pow(dx*dx+rhom*rhom,(double)0.5); - - if(n<0.0) - { - rho *= (double)-1.0; - dx *= (double)-1.0; - dy *= (double)-1.0; - rhom *= (double)-1.0; + } else { + if (q>=0.0) { + *phi = po2; + } else { + *phi = -po2; } - - if(rho) - theta = atan2(dx,rhom); - rhon = rho*n; - q = (C - (rhon*rhon) / a2) / n; - qc = (double)1.0 - ((double)1.0 / (e+e)) * - log(((double)1.0-e)/((double)1.0+e)); - if(fabs(fabs(qc)-fabs(q))>1.9e-6) - { - qd2 = q/(double)2.0; - if(qd2>1.0) - *phi = po2; - else if(qd2<-1.0) - *phi = -po2; - else - { - lat = asin(qd2); - if(e<1.0e-10) - *phi = lat; - else - { - while(fabs(dphi)>tol) - { - phis = sin(lat); - ess = e*phis; - om0 = ((double)1.0 - ess*ess); - dphi = (om0*om0) / ((double)2.0*cos(lat))* - (q/((double)1.0-esq) - phis / om0 + - (log(((double)1.0-ess)/((double)1.0+ess)) / - (e+e))); - lat += dphi; - } - *phi = lat; - } - - if(*phi > po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - } - } - else - { - if(q>=0.0) - *phi = po2; - else - *phi = -po2; - } - - *lambda = M0 + theta / n; - if(*lambda > GPS_PI) - *lambda -= GPS_PI * (double)2.0; - if(*lambda < -GPS_PI) - *lambda += GPS_PI * (double)2.0; - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda = -GPS_PI; - - *phi = GPS_Math_Rad_To_Deg(*phi); - *lambda = GPS_Math_Rad_To_Deg(*lambda); - - return; + } + + *lambda = M0 + theta / n; + if (*lambda > GPS_PI) { + *lambda -= GPS_PI * (double)2.0; + } + if (*lambda < -GPS_PI) { + *lambda += GPS_PI * (double)2.0; + } + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda = -GPS_PI; + } + + *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + + return; } @@ -375,113 +377,112 @@ void GPS_Math_Albers_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b) +void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) { - double po2; - double po4; - double a2; - double b2; - double phi0s; - double e; - double esq; - double ed2; - double ess; - double t0; - double t1; - double t2; - double m1; - double m2; - double phi1s; - double phi1c; - double phi2s; - double phi2c; - double n; - double F; - double Fa; - double rho; - double rho0; - double phis; - double t; - double theta; - double dphi; - - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi1 = GPS_Math_Deg_To_Rad(phi1); - phi2 = GPS_Math_Deg_To_Rad(phi2); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - - po2 = (double)GPS_PI / (double)2.0; - po4 = (double)GPS_PI / (double)4.0; - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - ed2 = e / (double)2.0; - - phi0s = sin(phi0); - ess = e * phi0s; - t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - - - phi1s = sin(phi1); - phi1c = cos(phi1); - ess = e * phi1s; - m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); - t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - - if(fabs(phi1-phi2)>1.0e-10) - { - phi2s = sin(phi2); - phi2c = cos(phi2); - ess = e * phi2s; - m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); - t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - n = log(m1/m2) / log(t1/t2); - } - else - n = phi1s; - - F = m1 / (n*pow(t1,n)); - Fa = F*a; - - rho0 = pow(t0,n) * Fa; - - if(fabs(fabs(phi)-po2)>1.0e-10) - { - phis = sin(phi); - ess = e * phis; - t = tan(po4-phi/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - rho = pow(t,n) * Fa; - } - else - { - if((phi*n)<=(double)0.0) - return; - rho = (double)0.0; + double po2; + double po4; + double a2; + double b2; + double phi0s; + double e; + double esq; + double ed2; + double ess; + double t0; + double t1; + double t2; + double m1; + double m2; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double n; + double F; + double Fa; + double rho; + double rho0; + double phis; + double t; + double theta; + double dphi; + + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + + po2 = (double)GPS_PI / (double)2.0; + po4 = (double)GPS_PI / (double)4.0; + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + ed2 = e / (double)2.0; + + phi0s = sin(phi0); + ess = e * phi0s; + t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); + t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + if (fabs(phi1-phi2)>1.0e-10) { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); + t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + n = log(m1/m2) / log(t1/t2); + } else { + n = phi1s; + } + + F = m1 / (n*pow(t1,n)); + Fa = F*a; + + rho0 = pow(t0,n) * Fa; + + if (fabs(fabs(phi)-po2)>1.0e-10) { + phis = sin(phi); + ess = e * phis; + t = tan(po4-phi/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + rho = pow(t,n) * Fa; + } else { + if ((phi*n)<=(double)0.0) { + return; } - - dphi = lambda - M0; - if(dphi>GPS_PI) - dphi -= (double)GPS_PI * (double)2.0; - if(dphi<-GPS_PI) - dphi += (double)GPS_PI * (double)2.0; - theta = dphi*n; - - *E = rho * sin(theta) + E0; - *N = rho0 - rho * cos(theta) + N0; - - return; + rho = (double)0.0; + } + + dphi = lambda - M0; + if (dphi>GPS_PI) { + dphi -= (double)GPS_PI * (double)2.0; + } + if (dphi<-GPS_PI) { + dphi += (double)GPS_PI * (double)2.0; + } + theta = dphi*n; + + *E = rho * sin(theta) + E0; + *N = rho0 - rho * cos(theta) + N0; + + return; } @@ -507,152 +508,151 @@ void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b) +void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) { - double po2; - double po4; - double a2; - double b2; - double phi0s; - double e; - double esq; - double ed2; - double ess; - double t0; - double t1; - double t2; - double m1; - double m2; - double phi1s; - double phi1c; - double phi2s; - double phi2c; - double n; - double F; - double Fa; - double rho; - double rho0; - double phis; - double t; - double theta; - - double dx; - double dy; - double rhom; - double lat; - double tlat; - double tol; - - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi1 = GPS_Math_Deg_To_Rad(phi1); - phi2 = GPS_Math_Deg_To_Rad(phi2); - M0 = GPS_Math_Deg_To_Rad(M0); - - - po2 = (double)GPS_PI / (double)2.0; - po4 = (double)GPS_PI / (double)4.0; - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - ed2 = e / (double)2.0; - - phi0s = sin(phi0); - ess = e * phi0s; - t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - + double po2; + double po4; + double a2; + double b2; + double phi0s; + double e; + double esq; + double ed2; + double ess; + double t0; + double t1; + double t2; + double m1; + double m2; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double n; + double F; + double Fa; + double rho; + double rho0; + double phis; + double t; + double theta; + + double dx; + double dy; + double rhom; + double lat; + double tlat; + double tol; + + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + M0 = GPS_Math_Deg_To_Rad(M0); + + + po2 = (double)GPS_PI / (double)2.0; + po4 = (double)GPS_PI / (double)4.0; + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + ed2 = e / (double)2.0; + + phi0s = sin(phi0); + ess = e * phi0s; + t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); + t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + if (fabs(phi1-phi2)>1.0e-10) { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); + t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + n = log(m1/m2) / log(t1/t2); + } else { + n = phi1s; + } + + F = m1 / (n*pow(t1,n)); + Fa = F*a; + + rho0 = pow(t0,n) * Fa; + + tlat = theta = (double)0.0; + tol = (double)4.85e-10; + + dx = E - E0; + dy = N - N0; + rhom = rho0 - dy; + rho = pow(dx*dx + rhom*rhom,(double)0.5); + + if (n<0.0) { + rhom *= (double)-1.0; + dy *= (double)-1.0; + dx *= (double)-1.0; + rho *= (double)-1.0; + } + + if (rho) { + theta = atan2(dx,rhom); + t = pow(rho/Fa,(double)1.0/n); + lat = po2 - (double)2.0*atan(t); + while (fabs(lat-tlat)>tol) { + tlat = lat; + phis = sin(lat); + ess = e * phis; + lat = po2 - (double)2.0 * atan(t*pow(((double)1.0-ess) / + ((double)1.0+ess), + e / (double)2.0)); + } + *phi = lat; + *lambda = theta/n + M0; - phi1s = sin(phi1); - phi1c = cos(phi1); - ess = e * phi1s; - m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); - t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - - if(fabs(phi1-phi2)>1.0e-10) - { - phi2s = sin(phi2); - phi2c = cos(phi2); - ess = e * phi2s; - m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); - t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - n = log(m1/m2) / log(t1/t2); + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + if (*lambda>GPS_PI) { + *lambda -= (double)GPS_PI * (double)2.0; } - else - n = phi1s; - - F = m1 / (n*pow(t1,n)); - Fa = F*a; - - rho0 = pow(t0,n) * Fa; - - tlat = theta = (double)0.0; - tol = (double)4.85e-10; - - dx = E - E0; - dy = N - N0; - rhom = rho0 - dy; - rho = pow(dx*dx + rhom*rhom,(double)0.5); - - if(n<0.0) - { - rhom *= (double)-1.0; - dy *= (double)-1.0; - dx *= (double)-1.0; - rho *= (double)-1.0; + if (*lambda<-GPS_PI) { + *lambda += (double)GPS_PI * (double)2.0; } - if(rho) - { - theta = atan2(dx,rhom); - t = pow(rho/Fa,(double)1.0/n); - lat = po2 - (double)2.0*atan(t); - while(fabs(lat-tlat)>tol) - { - tlat = lat; - phis = sin(lat); - ess = e * phis; - lat = po2 - (double)2.0 * atan(t*pow(((double)1.0-ess) / - ((double)1.0+ess), - e / (double)2.0)); - } - *phi = lat; - *lambda = theta/n + M0; - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - if(*lambda>GPS_PI) - *lambda -= (double)GPS_PI * (double)2.0; - if(*lambda<-GPS_PI) - *lambda += (double)GPS_PI * (double)2.0; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda = -GPS_PI; + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda = -GPS_PI; } - else - { - if(n>0.0) - *phi = po2; - else - *phi = -po2; - *lambda = M0; + } else { + if (n>0.0) { + *phi = po2; + } else { + *phi = -po2; } + *lambda = M0; + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -675,52 +675,55 @@ void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double R; - double e2; - double e4; - double e6; - double p2; - double po2; - double phis; - double dlam; - - - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- - (double)67.0*e6/(double)3024.0); - - if(M0>GPS_PI) - M0 -= p2; - - phis = sin((double)0.8 * phi); - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam-=p2; - if(dlam<-GPS_PI) - dlam+=p2; - - *E = R*dlam+E0; - *N = (R/(double)1.6) * log(((double)1.0+phis) / ((double)1.0-phis)) + N0; - - return; + double a2; + double b2; + double R; + double e2; + double e4; + double e6; + double p2; + double po2; + double phis; + double dlam; + + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + + if (M0>GPS_PI) { + M0 -= p2; + } + + phis = sin((double)0.8 * phi); + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam-=p2; + } + if (dlam<-GPS_PI) { + dlam+=p2; + } + + *E = R*dlam+E0; + *N = (R/(double)1.6) * log(((double)1.0+phis) / ((double)1.0-phis)) + N0; + + return; } @@ -743,63 +746,68 @@ void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Miller_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double R; - double e; - double e2; - double e4; - double e6; - double p2; - double po2; - double dx; - double dy; - - dx = E - E0; - dy = N - N0; - - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - e = pow(e2,(double)0.5); - - R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- - (double)67.0*e6/(double)3024.0); - if(M0>GPS_PI) - M0 -= p2; - - *phi = atan(sinh((double)0.8*dy/R)) / (double)0.8; - *lambda = M0+dx/R; - - if(*phi>po2) - *phi=po2; - else if (*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda-=p2; - if(*lambda<-GPS_PI) - *lambda+=p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double R; + double e; + double e2; + double e4; + double e6; + double p2; + double po2; + double dx; + double dy; + + dx = E - E0; + dy = N - N0; + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + e = pow(e2,(double)0.5); + + R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + if (M0>GPS_PI) { + M0 -= p2; + } + + *phi = atan(sinh((double)0.8*dy/R)) / (double)0.8; + *lambda = M0+dx/R; + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda-=p2; + } + if (*lambda<-GPS_PI) { + *lambda+=p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -823,128 +831,132 @@ void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, double E0, + double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double M1; - double m1; - double c0; - double c1; - double c2; - double c3; - double j; - double te4; - double E1; - double E2; - double E3; - double E4; - double x; - double phi0s; - double lat; - double phi0c; - double phi0s2; - double phi0s4; - double phi0s6; - double as; - - double phis; - double phic; - double phis2; - double phis4; - double phis6; - double dlam; - double mm; - double MM; - double rho; - double EE; - double tol; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - phi0s = sin(phi0); - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - phi0c = cos(phi0); - m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - M1 = a*(lat-phi0s2+phi0s4-phi0s6); - - x = pow((double)1.0-e2,(double)0.5); - E1 = ((double)1.0-x) / ((double)1.0+x); - E2 = E1*E1; - E3 = E2*E1; - E4 = E3*E1; - - if(!phi0s) - as = (double)0.0; - else - as = a*m1/phi0s; - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double M1; + double m1; + double c0; + double c1; + double c2; + double c3; + double j; + double te4; + double E1; + double E2; + double E3; + double E4; + double x; + double phi0s; + double lat; + double phi0c; + double phi0s2; + double phi0s4; + double phi0s6; + double as; + + double phis; + double phic; + double phis2; + double phis4; + double phis6; + double dlam; + double mm; + double MM; + double rho; + double EE; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + phi0s = sin(phi0); + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + phi0c = cos(phi0); + m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + M1 = a*(lat-phi0s2+phi0s4-phi0s6); + + x = pow((double)1.0-e2,(double)0.5); + E1 = ((double)1.0-x) / ((double)1.0+x); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + if (!phi0s) { + as = (double)0.0; + } else { + as = a*m1/phi0s; + } + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + phic = cos(phi); + + tol = (double)0.0001; + if (!(phi-phi0) && (((po2-tol)GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - phi0c = cos(phi0); - m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - M1 = a*(lat-phi0s2+phi0s4-phi0s6); - - x = pow((double)1.0-e2,(double)0.5); - E1 = ((double)1.0-x) / ((double)1.0+x); - E2 = E1*E1; - E3 = E2*E1; - E4 = E3*E1; - A0 = (double)3.0*E1/(double)2.0-(double)27.0*E3/(double)32.0; - A1 = (double)21.0*E2/(double)16.0-(double)55.0*E4/(double)32.0; - A2 = (double)151.0*E3/(double)96.0; - A3 = (double)1097.0*E4/(double)512.0; - if(!phi0s) - as = (double)0.0; - else - as = a*m1/phi0s; - - - dx = E - E0; - dy = N - N0; - asdy = as - dy; - rho = pow(dx*dx+asdy*asdy,(double)0.5); - if(phi0<(double)0.0) - rho=-rho; - MM = as+M1-rho; - - mu = MM / (a*c0); - smu2 = A0 * sin((double)2.0*mu); - smu4 = A1 * sin((double)4.0*mu); - smu6 = A2 * sin((double)6.0*mu); - smu8 = A3 * sin((double)8.0*mu); - *phi = mu+smu2+smu4+smu6+smu8; - - tol = (double)0.00001; - if(((po2-tol)GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + phi0c = cos(phi0); + m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + M1 = a*(lat-phi0s2+phi0s4-phi0s6); + + x = pow((double)1.0-e2,(double)0.5); + E1 = ((double)1.0-x) / ((double)1.0+x); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + A0 = (double)3.0*E1/(double)2.0-(double)27.0*E3/(double)32.0; + A1 = (double)21.0*E2/(double)16.0-(double)55.0*E4/(double)32.0; + A2 = (double)151.0*E3/(double)96.0; + A3 = (double)1097.0*E4/(double)512.0; + if (!phi0s) { + as = (double)0.0; + } else { + as = a*m1/phi0s; + } + + + dx = E - E0; + dy = N - N0; + asdy = as - dy; + rho = pow(dx*dx+asdy*asdy,(double)0.5); + if (phi0<(double)0.0) { + rho=-rho; + } + MM = as+M1-rho; + + mu = MM / (a*c0); + smu2 = A0 * sin((double)2.0*mu); + smu4 = A1 * sin((double)4.0*mu); + smu6 = A2 * sin((double)6.0*mu); + smu8 = A3 * sin((double)8.0*mu); + *phi = mu+smu2+smu4+smu6+smu8; + + tol = (double)0.00001; + if (((po2-tol)po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + *lambda = M0 + rho * (atan2(dx,asdy)) / (a * mm); + } + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -1139,127 +1156,129 @@ void GPS_Math_Bonne_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double om0; - double A0; - double A1; - double A2; - double A3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - double lat; - double x; - double E1; - double E2; - double E3; - double E4; - - double phis; - double phic; - double phit; - double phis2; - double phis4; - double phis6; - double RD; - double dlam; - double NN; - double TT; - double WW; - double WW2; - double WW3; - double WW4; - double WW5; - double CC; - double MM; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - te4 = (double)3.0 * e4; - j = (double)45. * e6 / (double)1024.; - c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; - c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - - lat = c0*phi0; - phi0s2 = c1 * sin((double)2.*phi0); - phi0s4 = c2 * sin((double)4.*phi0); - phi0s6 = c3 * sin((double)6.*phi0); - AM0 = a * (lat-phi0s2+phi0s4-phi0s6); - - om0 = (double)1.0 - e2; - x = pow(om0,(double)0.5); - E1 = ((double)1.0 - x) / ((double)1.0 + x); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - phis = sin(phi); - phic = cos(phi); - phit = tan(phi); - RD = pow((double)1.-e2*phis*phis,(double).5); - NN = a/RD; - TT = phit*phit; - WW = dlam*phic; - WW2 = WW*WW; - WW3 = WW*WW2; - WW4 = WW*WW3; - WW5 = WW*WW4; - CC = e2*phic*phic/om0; - lat = c0*phi; - phis2 = c1 * sin((double)2.*phi); - phis4 = c2 * sin((double)4.*phi); - phis6 = c3 * sin((double)6.*phi); - MM = a * (lat-phis2+phis4-phis6); - - *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* - (TT*WW5/(double)120.)) + E0; - *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * - WW4/(double)24.) + N0; - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double om0; + double A0; + double A1; + double A2; + double A3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + double lat; + double x; + double E1; + double E2; + double E3; + double E4; + + double phis; + double phic; + double phit; + double phis2; + double phis4; + double phis6; + double RD; + double dlam; + double NN; + double TT; + double WW; + double WW2; + double WW3; + double WW4; + double WW5; + double CC; + double MM; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + te4 = (double)3.0 * e4; + j = (double)45. * e6 / (double)1024.; + c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; + c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + + lat = c0*phi0; + phi0s2 = c1 * sin((double)2.*phi0); + phi0s4 = c2 * sin((double)4.*phi0); + phi0s6 = c3 * sin((double)6.*phi0); + AM0 = a * (lat-phi0s2+phi0s4-phi0s6); + + om0 = (double)1.0 - e2; + x = pow(om0,(double)0.5); + E1 = ((double)1.0 - x) / ((double)1.0 + x); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + phic = cos(phi); + phit = tan(phi); + RD = pow((double)1.-e2*phis*phis,(double).5); + NN = a/RD; + TT = phit*phit; + WW = dlam*phic; + WW2 = WW*WW; + WW3 = WW*WW2; + WW4 = WW*WW3; + WW5 = WW*WW4; + CC = e2*phic*phic/om0; + lat = c0*phi; + phis2 = c1 * sin((double)2.*phi); + phis4 = c2 * sin((double)4.*phi); + phis6 = c3 * sin((double)6.*phi); + MM = a * (lat-phis2+phis4-phis6); + + *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* + (TT*WW5/(double)120.)) + E0; + *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * + WW4/(double)24.) + N0; + return; } @@ -1283,162 +1302,161 @@ void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double om0; - double A0; - double A1; - double A2; - double A3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - double lat; - double x; - double E1; - double E2; - double E3; - double E4; - - double dx; - double dy; - double mu; - double mus2; - double mus4; - double mus6; - double mus8; - double M1; - double phi1; - double phi1s; - double phi1c; - double phi1t; - double T; - double T1; - double N1; - double R1; - double RD; - double DD; - double D2; - double D3; - double D4; - double D5; - double tol; - - M0 = GPS_Math_Deg_To_Rad(M0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - te4 = (double)3.0 * e4; - j = (double)45. * e6 / (double)1024.; - c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; - c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - - lat = c0*phi0; - phi0s2 = c1 * sin((double)2.*phi0); - phi0s4 = c2 * sin((double)4.*phi0); - phi0s6 = c3 * sin((double)6.*phi0); - AM0 = a * (lat-phi0s2+phi0s4-phi0s6); - - om0 = (double)1.0 - e2; - x = pow(om0,(double)0.5); - E1 = ((double)1.0 - x) / ((double)1.0 + x); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - - tol = (double)1.e-5; - - dx = E - E0; - dy = N - N0; - M1 = AM0 + dy; - mu = M1 / (a*c0); - mus2 = A0 * sin((double)2.*mu); - mus4 = A1 * sin((double)4.*mu); - mus6 = A2 * sin((double)6.*mu); - mus8 = A3 * sin((double)8.*mu); - phi1 = mu + mus2 + mus4 + mus6 + mus8; - - if((((po2-tol)po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; } - else if((((-po2-tol)po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; } + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -1462,74 +1480,77 @@ void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double e; - double e2; - double e4; - double e6; - double k0; - double ak0; - double k2; - double c0; - double c1; - double c2; - double p2; - double po2; - double phi0s; - double phi0c; - - double dlam; - double qq; - double x; - double phis; - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - e = pow(e2,(double).5); - c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* - e6/(double)5040.; - c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; - c2 = (double)761.*e6/(double)45360.; - - phi0s = sin(phi0); - phi0c = cos(phi0); - k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); - ak0 = a*k0; - k2 = k0 * (double)2.; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam-=p2; - if(dlam<-GPS_PI) - dlam+=p2; - - phis = sin(phi); - x = e * phis; - qq = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* - log(((double)1.-x)/((double)1.+x))); - *E = ak0 * dlam + E0; - *N = a * qq / k2 + N0; - - return; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double k0; + double ak0; + double k2; + double c0; + double c1; + double c2; + double p2; + double po2; + double phi0s; + double phi0c; + + double dlam; + double qq; + double x; + double phis; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + c2 = (double)761.*e6/(double)45360.; + + phi0s = sin(phi0); + phi0c = cos(phi0); + k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); + ak0 = a*k0; + k2 = k0 * (double)2.; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam-=p2; + } + if (dlam<-GPS_PI) { + dlam+=p2; + } + + phis = sin(phi); + x = e * phis; + qq = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* + log(((double)1.-x)/((double)1.+x))); + *E = ak0 * dlam + E0; + *N = a * qq / k2 + N0; + + return; } @@ -1553,104 +1574,110 @@ void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double e; - double e2; - double e4; - double e6; - double k0; - double ak0; - double k2; - double c0; - double c1; - double c2; - double p2; - double po2; - double phi0s; - double phi0c; - - double dx; - double dy; - double qp; - double bt; - double phis; - double i; - double x; - double bs2; - double bs4; - double bs6; - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - e = pow(e2,(double).5); - c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* - e6/(double)5040.; - c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; - c2 = (double)761.*e6/(double)45360.; - - phi0s = sin(phi0); - phi0c = cos(phi0); - k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); - ak0 = a*k0; - k2 = k0 * (double)2.; - - dx = E - E0; - dy = N - N0; - phis = sin(po2); - x = e*phis; - qp = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* - log(((double)1.-x)/((double)1.+x))); - i = k2*dy/(a*qp); - if(i>(double)1.) - i=(double)1.; - else if(i<(double)-1.) - i=(double)-1.; - bt = asin(i); - bs2 = c0 * sin((double)2.*bt); - bs4 = c1 * sin((double)4.*bt); - bs6 = c2 * sin((double)6.*bt); - - *phi = bt+bs2+bs4+bs6; - *lambda = M0 + dx/ak0; - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double k0; + double ak0; + double k2; + double c0; + double c1; + double c2; + double p2; + double po2; + double phi0s; + double phi0c; + + double dx; + double dy; + double qp; + double bt; + double phis; + double i; + double x; + double bs2; + double bs4; + double bs6; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + c2 = (double)761.*e6/(double)45360.; + + phi0s = sin(phi0); + phi0c = cos(phi0); + k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); + ak0 = a*k0; + k2 = k0 * (double)2.; + + dx = E - E0; + dy = N - N0; + phis = sin(po2); + x = e*phis; + qp = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* + log(((double)1.-x)/((double)1.+x))); + i = k2*dy/(a*qp); + if (i>(double)1.) { + i=(double)1.; + } else if (i<(double)-1.) { + i=(double)-1.; + } + bt = asin(i); + bs2 = c0 * sin((double)2.*bt); + bs4 = c1 * sin((double)4.*bt); + bs6 = c2 * sin((double)6.*bt); + + *phi = bt+bs2+bs4+bs6; + *lambda = M0 + dx/ak0; + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -1673,78 +1700,80 @@ void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, double N0, - double a, double b) +void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, double N0, + double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra0; - double Ra1; - double po2; - double p2; - - double Ra; - - double phis; - double theta; - double dtheta; - double thetas; - double thetac; - double n; - double dlam; - double tol; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2) / a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - Ra0 = Ra * (double)0.4222382; - Ra1 = Ra * (double)1.3265004; - - theta = phi / (double)2.; - dtheta = (double)1.; - tol = (double)4.85e-10; - phis = sin(phi); - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - while(fabs(dtheta)>tol) - { - thetas = sin(theta); - thetac = cos(theta); - n = theta+thetas*thetac+(double)2.*thetas; - dtheta = -(n-((double)2.+po2)*phis) / - ((double)2.*thetac*((double)1.+thetac)); - theta += dtheta; - } + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra0; + double Ra1; + double po2; + double p2; + + double Ra; + + double phis; + double theta; + double dtheta; + double thetas; + double thetac; + double n; + double dlam; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Ra0 = Ra * (double)0.4222382; + Ra1 = Ra * (double)1.3265004; + + theta = phi / (double)2.; + dtheta = (double)1.; + tol = (double)4.85e-10; + phis = sin(phi); + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + while (fabs(dtheta)>tol) { + thetas = sin(theta); + thetac = cos(theta); + n = theta+thetas*thetac+(double)2.*thetas; + dtheta = -(n-((double)2.+po2)*phis) / + ((double)2.*thetac*((double)1.+thetac)); + theta += dtheta; + } - *E = Ra0*dlam*((double)1.+cos(theta))+E0; - *N = Ra1*sin(theta)+N0; + *E = Ra0*dlam*((double)1.+cos(theta))+E0; + *N = Ra1*sin(theta)+N0; - return; + return; } @@ -1767,86 +1796,92 @@ void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) +void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra0; - double Ra1; - double po2; - double p2; - - double Ra; - double theta; - double thetas; - double thetac; - double n; - double dx; - double dy; - double i; - - - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2) / a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - Ra0 = Ra * (double)0.4222382; - Ra1 = Ra * (double)1.3265004; - - dx = E - E0; - dy = N - N0; - i = dy/Ra1; - if(i>(double)1.) - i=(double)1.; - else if(i<(double)-1.) - i=(double)-1.; - - theta = asin(i); - thetas = sin(theta); - thetac = cos(theta); - n = theta+thetas*thetac+(double)2.*thetas; - - *phi = asin(n/((double)2. + po2)); - *lambda = M0 + dx / (Ra0*((double)1.+thetac)); - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra0; + double Ra1; + double po2; + double p2; + + double Ra; + double theta; + double thetas; + double thetac; + double n; + double dx; + double dy; + double i; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Ra0 = Ra * (double)0.4222382; + Ra1 = Ra * (double)1.3265004; + + dx = E - E0; + dy = N - N0; + i = dy/Ra1; + if (i>(double)1.) { + i=(double)1.; + } else if (i<(double)-1.) { + i=(double)-1.; + } + + theta = asin(i); + thetas = sin(theta); + thetac = cos(theta); + n = theta+thetas*thetac+(double)2.*thetas; + + *phi = asin(n/((double)2. + po2)); + *lambda = M0 + dx / (Ra0*((double)1.+thetac)); + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } - + @@ -1868,71 +1903,73 @@ void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, double N0, - double a, double b) +void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, double N0, + double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double Rsq; - double IRa; - double po2; - double p2; - - double phis; - double theta; - double dtheta; - double dlam; - double tol; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2) / a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - Rsq = Ra/pow((double)2.+GPS_PI,(double).5); - IRa = (double)1./Rsq; - - phis = sin(phi); - theta = phi; - dtheta = (double)1.; - tol = (double)4.85e-10; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - while(fabs(dtheta)>tol) - { - dtheta = -(theta+sin(theta)-((double)1.+po2)*phis) / - ((double)1.+cos(theta)); - theta += dtheta; - } - - *E = Rsq*dlam*((double)1.+cos(theta))+E0; - *N = (double)2.*Rsq*theta+N0; - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rsq; + double IRa; + double po2; + double p2; + + double phis; + double theta; + double dtheta; + double dlam; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Rsq = Ra/pow((double)2.+GPS_PI,(double).5); + IRa = (double)1./Rsq; + + phis = sin(phi); + theta = phi; + dtheta = (double)1.; + tol = (double)4.85e-10; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + while (fabs(dtheta)>tol) { + dtheta = -(theta+sin(theta)-((double)1.+po2)*phis) / + ((double)1.+cos(theta)); + theta += dtheta; + } + + *E = Rsq*dlam*((double)1.+cos(theta))+E0; + *N = (double)2.*Rsq*theta+N0; + + return; } @@ -1955,80 +1992,86 @@ void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) +void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double Rsq; - double IRa; - double po2; - double p2; - - double Ra; - double theta; - double dx; - double dy; - double i; - - - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2) / a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - Rsq = Ra/pow((double)2.+GPS_PI,(double).5); - IRa = (double)1./Rsq; - - - dx = E - E0; - dy = N - N0; - theta = IRa * dy / (double)2.; - i = (theta+sin(theta)) / ((double)1.+po2); - if(i>(double)1.) - *phi = po2; - else if(i<(double)-1.) - *phi = -po2; - else - *phi= asin(i); - *lambda = M0 + IRa * dx / ((double)1.+cos(theta)); - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double Rsq; + double IRa; + double po2; + double p2; + + double Ra; + double theta; + double dx; + double dy; + double i; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Rsq = Ra/pow((double)2.+GPS_PI,(double).5); + IRa = (double)1./Rsq; + + + dx = E - E0; + dy = N - N0; + theta = IRa * dy / (double)2.; + i = (theta+sin(theta)) / ((double)1.+po2); + if (i>(double)1.) { + *phi = po2; + } else if (i<(double)-1.) { + *phi = -po2; + } else { + *phi= asin(i); + } + *lambda = M0 + IRa * dx / ((double)1.+cos(theta)); + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } - + @@ -2051,54 +2094,57 @@ void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, double E0, + double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double Rac; - double phi0c; - - double dlam; - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - phi0c = cos(phi0); - Rac = Ra * phi0c; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - *E = Rac * dlam + E0; - *N = Ra * phi + N0; - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rac; + double phi0c; + + double dlam; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + phi0c = cos(phi0); + Rac = Ra * phi0c; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + *E = Rac * dlam + E0; + *N = Ra * phi + N0; + + return; } @@ -2122,73 +2168,79 @@ void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double Rac; - double phi0c; - - double dx; - double dy; - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - phi0c = cos(phi0); - Rac = Ra * phi0c; - - dx = E - E0; - dy = N - N0; - - if(!Rac) - *lambda = (double)0.; - else - *lambda = M0 + dx / Rac; - - *phi = dy/Ra; - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rac; + double phi0c; + + double dx; + double dy; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + phi0c = cos(phi0); + Rac = Ra * phi0c; + + dx = E - E0; + dy = N - N0; + + if (!Rac) { + *lambda = (double)0.; + } else { + *lambda = M0 + dx / Rac; + } + + *phi = dy/Ra; + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -2211,111 +2263,114 @@ void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b) +void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, + double N0, double a, double b) { - double po2; - double p2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double pRa; - - double gg; - double pp; - double pp2; - double gm0; - double ppa; - double thetai; - double theta; - double thetas; - double thetac; - double qq; - double tol; - double aa; - double aa2; - double dlam; - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* - e6/(double)3024.); - pRa = (double)GPS_PI * Ra; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - tol = (double)1.0e-5; - - if(!phi) - { - *N = (double)0.0; - *E = Ra*dlam+E0; + double po2; + double p2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double pRa; + + double gg; + double pp; + double pp2; + double gm0; + double ppa; + double thetai; + double theta; + double thetas; + double thetac; + double qq; + double tol; + double aa; + double aa2; + double dlam; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + pRa = (double)GPS_PI * Ra; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + tol = (double)1.0e-5; + + if (!phi) { + *N = (double)0.0; + *E = Ra*dlam+E0; + } else if (!dlam || (((po2-tol)(double)1.) { + thetai=(double)1.; + } else if (thetai<(double)-1.) { + thetai=(double)-1.; + } + + theta = asin(thetai); + *E = 0; + *N = pRa * tan(theta/(double)2.) * N0; + if (phi<(double)0.0) { + *N *= (double)-1.; } - else if(!dlam || (((po2-tol)(double)1.) - thetai=(double)1.; - else if(thetai<(double)-1.) - thetai=(double)-1.; - - theta = asin(thetai); - *E = 0; - *N = pRa * tan(theta/(double)2.) * N0; - if(phi<(double)0.0) - *N *= (double)-1.; + } else { + aa = (double).5*fabs((double)GPS_PI/dlam - dlam/(double)GPS_PI); + thetai = fabs(((double)2./(double)GPS_PI) * phi); + if (thetai>(double)1.) { + thetai=(double)1.; + } else if (thetai<(double)-1.) { + thetai=(double)-1.; + } + + theta = asin(thetai); + thetas = sin(theta); + thetac = cos(theta); + gg = thetac/(thetas+thetac-(double)1.); + pp = gg*((double)2./thetas-(double)1.); + aa2 = aa*aa; + pp2 = pp*pp; + gm0 = gg-pp2; + ppa = pp2+aa2; + qq = aa2+gg; + *E = pRa*(aa*gm0+pow(aa2*gm0*gm0-ppa*(gg*gg-pp2),(double).5))/ppa+E0; + if (dlam<(double)0.0) { + *E *= (double)-1.; } - else - { - aa = (double).5*fabs((double)GPS_PI/dlam - dlam/(double)GPS_PI); - thetai = fabs(((double)2./(double)GPS_PI) * phi); - if(thetai>(double)1.) - thetai=(double)1.; - else if(thetai<(double)-1.) - thetai=(double)-1.; - - theta = asin(thetai); - thetas = sin(theta); - thetac = cos(theta); - gg = thetac/(thetas+thetac-(double)1.); - pp = gg*((double)2./thetas-(double)1.); - aa2 = aa*aa; - pp2 = pp*pp; - gm0 = gg-pp2; - ppa = pp2+aa2; - qq = aa2+gg; - *E = pRa*(aa*gm0+pow(aa2*gm0*gm0-ppa*(gg*gg-pp2),(double).5))/ppa+E0; - if(dlam<(double)0.0) - *E *= (double)-1.; - *N = pRa*(pp*qq-aa*pow((aa2+(double)1.)*ppa-qq*qq,(double).5))/ppa+N0; - if(phi<(double)0.0) - *N *= (double)-1.; + *N = pRa*(pp*qq-aa*pow((aa2+(double)1.)*ppa-qq*qq,(double).5))/ppa+N0; + if (phi<(double)0.0) { + *N *= (double)-1.; } + } - return; + return; } @@ -2338,119 +2393,123 @@ void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) +void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b) { - double po2; - double p2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double pRa; - - double dx; - double dy; - double xx; - double xx2; - double yy; - double yy2; - double tyy2; - double xpy; - double c1; - double c2; - double c3; - double c3c3; - double co; - double dd; - double a1; - double m1; - double i; - double theta; - - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* - e6/(double)3024.); - pRa = (double)GPS_PI * Ra; - - - dx = E - E0; - dy = N - N0; - xx = dx/pRa; - yy = dy/pRa; - xx2 = xx*xx; - yy2 = yy*yy; - xpy = xx2+yy2; - tyy2 = yy2*(double)2.; - - if(!N) - *phi=(double)0.0; - else - { - c1 = -fabs(yy)*((double)1.+xpy); - c2 = c1-tyy2+xx2; - c3 = (double)-2.*c1+(double)1.+tyy2+xpy*xpy; - co = c2/((double)3.*c3); - c3c3 = c3*c3; - dd = yy2/c3+(((double)2.*c2*c2*c2)/(c3c3*c3)-((double)9.*c1*c2)/ - c3c3)/(double)27.; - a1 = (c1-c2*co)/c3; - m1 = (double)2.* pow(-((double)1./(double)3.)*a1,(double).5); - i = (double)3.*dd/(a1*m1); - if((i>(double)1.)||(i<(double)-1.)) - *phi=po2; - else - { - theta = ((double)1./(double)3.)*acos((double)3.*dd/(a1*m1)); - *phi = (double)GPS_PI*(-m1*cos(theta+(double)GPS_PI/(double)3.)- - co); - } + double po2; + double p2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double pRa; + + double dx; + double dy; + double xx; + double xx2; + double yy; + double yy2; + double tyy2; + double xpy; + double c1; + double c2; + double c3; + double c3c3; + double co; + double dd; + double a1; + double m1; + double i; + double theta; + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + pRa = (double)GPS_PI * Ra; + + + dx = E - E0; + dy = N - N0; + xx = dx/pRa; + yy = dy/pRa; + xx2 = xx*xx; + yy2 = yy*yy; + xpy = xx2+yy2; + tyy2 = yy2*(double)2.; + + if (!N) { + *phi=(double)0.0; + } else { + c1 = -fabs(yy)*((double)1.+xpy); + c2 = c1-tyy2+xx2; + c3 = (double)-2.*c1+(double)1.+tyy2+xpy*xpy; + co = c2/((double)3.*c3); + c3c3 = c3*c3; + dd = yy2/c3+(((double)2.*c2*c2*c2)/(c3c3*c3)-((double)9.*c1*c2)/ + c3c3)/(double)27.; + a1 = (c1-c2*co)/c3; + m1 = (double)2.* pow(-((double)1./(double)3.)*a1,(double).5); + i = (double)3.*dd/(a1*m1); + if ((i>(double)1.)||(i<(double)-1.)) { + *phi=po2; + } else { + theta = ((double)1./(double)3.)*acos((double)3.*dd/(a1*m1)); + *phi = (double)GPS_PI*(-m1*cos(theta+(double)GPS_PI/(double)3.)- + co); } - - if(N<(double)0.0) - *phi *= (double)-1.0; - - if(!xx) - *lambda = M0; - else - *lambda = (double)GPS_PI * (xpy-(double)1.+ - pow((double)1.+((double)2.*xx2-tyy2)+xpy*xpy,(double).5)) / - ((double)2.*xx) + M0; - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + } + + if (N<(double)0.0) { + *phi *= (double)-1.0; + } + + if (!xx) { + *lambda = M0; + } else + *lambda = (double)GPS_PI * (xpy-(double)1.+ + pow((double)1.+((double)2.*xx2-tyy2)+xpy*xpy,(double).5)) / + ((double)2.*xx) + M0; + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -2474,124 +2533,119 @@ void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double lambda1, - double E0, double N0, double a, double b) +void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi1, double lambda1, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4=(double)0.; - double e; - double eo2; - double sh; - double mc; - double tc=(double)0.; - double amc=(double)0.; - double ta; - double phi1s; - double phi1c; - double es; - double op; - double om; - double pe; - double polat; - double polon; - - double dlam; - double phis; - double t; - double rho; - - - lambda1 = GPS_Math_Deg_To_Rad(lambda1); - phi1 = GPS_Math_Deg_To_Rad(phi1); - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - - ta = a * (double)2.0; - if(lambda1>GPS_PI) - lambda1 -= p2; - if(phi1<(double)0.0) - { - sh=(double)1.0; - polat = -phi1; - polon = -lambda1; - } - else - { - sh=(double)0.0; - polat = phi1; - polon = lambda1; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4=(double)0.; + double e; + double eo2; + double sh; + double mc; + double tc=(double)0.; + double amc=(double)0.; + double ta; + double phi1s; + double phi1c; + double es; + double op; + double om; + double pe; + double polat; + double polon; + + double dlam; + double phis; + double t; + double rho; + + + lambda1 = GPS_Math_Deg_To_Rad(lambda1); + phi1 = GPS_Math_Deg_To_Rad(phi1); + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + + ta = a * (double)2.0; + if (lambda1>GPS_PI) { + lambda1 -= p2; + } + if (phi1<(double)0.0) { + sh=(double)1.0; + polat = -phi1; + polon = -lambda1; + } else { + sh=(double)0.0; + polat = phi1; + polon = lambda1; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e = pow(e2,(double).5); + eo2 = e/(double)2.; + + if (fabs(fabs(polat)-po2)>(double)1.0e-10) { + phi1s = sin(polat); + phi1c = cos(polat); + es = e*phi1s; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + mc = phi1c / pow((double)1.-es*es,(double).5); + amc = mc * a; + tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + } else { + op = (double)1. + e; + om = (double)1. - e; + e4 = pow(pow(op,op)*pow(om,om),(double).5); + } + + + + if (fabs(fabs(phi)-po2)<(double)1.0e-10) { + *E = *N = (double)0.0; + } else { + if (sh) { + phi *= (double)-1.0; + lambda *= (double)-1.0; } - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e = pow(e2,(double).5); - eo2 = e/(double)2.; - - if(fabs(fabs(polat)-po2)>(double)1.0e-10) - { - phi1s = sin(polat); - phi1c = cos(polat); - es = e*phi1s; - pe = pow(((double)1.-es)/((double)1.+es),eo2); - mc = phi1c / pow((double)1.-es*es,(double).5); - amc = mc * a; - tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + dlam = lambda - polon; + if (dlam>GPS_PI) { + dlam -= p2; } - else - { - op = (double)1. + e; - om = (double)1. - e; - e4 = pow(pow(op,op)*pow(om,om),(double).5); + if (dlam<-GPS_PI) { + dlam += p2; + } + phis = sin(phi); + es = e * phis; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + t = tan(((double)GPS_PI/(double)4.)-phi/(double)2.) / pe; + + if (fabs(fabs(polat)-po2)>(double)1.0e-10) { + rho = amc * t / tc; + } else { + rho = ta * t / e4; } - - - - if(fabs(fabs(phi)-po2)<(double)1.0e-10) - *E = *N = (double)0.0; - else - { - if(sh) - { - phi *= (double)-1.0; - lambda *= (double)-1.0; - } - - dlam = lambda - polon; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - phis = sin(phi); - es = e * phis; - pe = pow(((double)1.-es)/((double)1.+es),eo2); - t = tan(((double)GPS_PI/(double)4.)-phi/(double)2.) / pe; - - if(fabs(fabs(polat)-po2)>(double)1.0e-10) - rho = amc * t / tc; - else - rho = ta * t / e4; - *E = rho * sin(dlam) + E0; - - if(sh) - { - *E *= (double)-1.; - *N = rho * cos(dlam) + N0; - } - else - *N = -rho * cos(dlam) + N0; + *E = rho * sin(dlam) + E0; + + if (sh) { + *E *= (double)-1.; + *N = rho * cos(dlam) + N0; + } else { + *N = -rho * cos(dlam) + N0; } - - return; + } + + return; } @@ -2615,145 +2669,139 @@ void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double lambda1, - double E0, double N0, double a, double b) +void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi1, double lambda1, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4=(double)0.; - double e; - double eo2; - double sh; - double mc; - double tc=(double)0.; - double amc=(double)0.; - double ta; - double phi1s; - double phi1c; - double es; - double op; - double om; - double pe; - double polat; - double polon; - - double dx; - double dy; - double t; - double rho; - double PHI; - double PHIS; - double TPHI; - - - lambda1 = GPS_Math_Deg_To_Rad(lambda1); - phi1 = GPS_Math_Deg_To_Rad(phi1); - - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - - ta = a * (double)2.0; - if(lambda1>GPS_PI) - lambda1 -= p2; - if(phi1<(double)0.0) - { - sh=(double)1.0; - polat = -phi1; - polon = -lambda1; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4=(double)0.; + double e; + double eo2; + double sh; + double mc; + double tc=(double)0.; + double amc=(double)0.; + double ta; + double phi1s; + double phi1c; + double es; + double op; + double om; + double pe; + double polat; + double polon; + + double dx; + double dy; + double t; + double rho; + double PHI; + double PHIS; + double TPHI; + + + lambda1 = GPS_Math_Deg_To_Rad(lambda1); + phi1 = GPS_Math_Deg_To_Rad(phi1); + + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + + ta = a * (double)2.0; + if (lambda1>GPS_PI) { + lambda1 -= p2; + } + if (phi1<(double)0.0) { + sh=(double)1.0; + polat = -phi1; + polon = -lambda1; + } else { + sh=(double)0.0; + polat = phi1; + polon = lambda1; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e = pow(e2,(double).5); + eo2 = e/(double)2.; + + if (fabs(fabs(polat)-po2)>(double)1.0e-10) { + phi1s = sin(polat); + phi1c = cos(polat); + es = e*phi1s; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + mc = phi1c / pow((double)1.-es*es,(double).5); + amc = mc * a; + tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + } else { + op = (double)1. + e; + om = (double)1. - e; + e4 = pow(pow(op,op)*pow(om,om),(double).5); + } + + + dx = E - E0; + dy = N - N0; + if (!dx && !dy) { + *phi = po2; + *lambda = polon; + } else { + if (sh) { + dx *= (double)-1.; + dy *= (double)-1.; } - else - { - sh=(double)0.0; - polat = phi1; - polon = lambda1; + rho = pow(dx*dx+dy*dy,(double).5); + if (fabs(fabs(polat)-po2)>(double)1.0e-10) { + t = rho * tc / amc; + } else { + t = rho * e4 / ta; } - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e = pow(e2,(double).5); - eo2 = e/(double)2.; - - if(fabs(fabs(polat)-po2)>(double)1.0e-10) - { - phi1s = sin(polat); - phi1c = cos(polat); - es = e*phi1s; - pe = pow(((double)1.-es)/((double)1.+es),eo2); - mc = phi1c / pow((double)1.-es*es,(double).5); - amc = mc * a; - tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + TPHI = (double)0.0; + PHI = po2 - (double)2.*atan(t); + while (fabs(PHI-TPHI)>(double)1.0e-10) { + TPHI=PHI; + PHIS = sin(PHI); + es = e * PHIS; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + PHI = po2 - (double)2. * atan(t*pe); } - else - { - op = (double)1. + e; - om = (double)1. - e; - e4 = pow(pow(op,op)*pow(om,om),(double).5); + *phi = PHI; + *lambda = polon + atan2(dx,-dy); + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; } - - - dx = E - E0; - dy = N - N0; - if(!dx && !dy) - { - *phi = po2; - *lambda = polon; + + if (*lambda>GPS_PI) { + *lambda -= p2; } - else - { - if(sh) - { - dx *= (double)-1.; - dy *= (double)-1.; - } - rho = pow(dx*dx+dy*dy,(double).5); - if(fabs(fabs(polat)-po2)>(double)1.0e-10) - t = rho * tc / amc; - else - t = rho * e4 / ta; - TPHI = (double)0.0; - PHI = po2 - (double)2.*atan(t); - while(fabs(PHI-TPHI)>(double)1.0e-10) - { - TPHI=PHI; - PHIS = sin(PHI); - es = e * PHIS; - pe = pow(((double)1.-es)/((double)1.+es),eo2); - PHI = po2 - (double)2. * atan(t*pe); - } - *phi = PHI; - *lambda = polon + atan2(dx,-dy); - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + if (*lambda<-GPS_PI) { + *lambda += p2; } - if(sh) - { - *phi *= (double)-1.; - *lambda *= (double)1.; + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; } + } + if (sh) { + *phi *= (double)-1.; + *lambda *= (double)1.; + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -2776,69 +2824,71 @@ void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double p2; - double po2; - double Ra; - double sRa2; - double sRa8; - - double ps; - double dlam; - double theta; - double thetap; - double d; - double tol; - - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- - (double)67.0*e6/(double)3024.0); - sRa2 = pow((double)2.,(double).5) * Ra; - sRa8 = pow((double)8.,(double).5) * Ra; - - if(M0>GPS_PI) - M0 -= p2; - - ps = sin(phi) * (double)GPS_PI; - d = (double)0.1745329; - tol = (double)4.85e-10; - thetap = phi; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam-=p2; - if(dlam<-GPS_PI) - dlam+=p2; - - while(fabs(d)>tol) - { - d = -(thetap+sin(thetap)-ps)/((double)1.+cos(thetap)); - thetap += d; - } - theta = thetap / (double)2.; - *E = (sRa8/(double)GPS_PI) * dlam * cos(theta) + E0; - *N = sRa2 * sin(theta) + N0; - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double Ra; + double sRa2; + double sRa8; + + double ps; + double dlam; + double theta; + double thetap; + double d; + double tol; + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + sRa2 = pow((double)2.,(double).5) * Ra; + sRa8 = pow((double)8.,(double).5) * Ra; + + if (M0>GPS_PI) { + M0 -= p2; + } + + ps = sin(phi) * (double)GPS_PI; + d = (double)0.1745329; + tol = (double)4.85e-10; + thetap = phi; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam-=p2; + } + if (dlam<-GPS_PI) { + dlam+=p2; + } + + while (fabs(d)>tol) { + d = -(thetap+sin(thetap)-ps)/((double)1.+cos(thetap)); + thetap += d; + } + theta = thetap / (double)2.; + *E = (sRa8/(double)GPS_PI) * dlam * cos(theta) + E0; + *N = sRa2 * sin(theta) + N0; + + return; } @@ -2861,85 +2911,89 @@ void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double p2; - double po2; - double Ra; - double sRa2; - double sRa8; - - double dx; - double dy; - double theta=(double)0.; - double tt; - double i; - - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- - (double)67.0*e6/(double)3024.0); - sRa2 = pow((double)2.,(double).5) * Ra; - sRa8 = pow((double)8.,(double).5) * Ra; - - if(M0>GPS_PI) - M0 -= p2; - - dx = E - E0; - dy = N - N0; - i = dy/sRa2; - if(fabs(i)>(double)1.) - { - *phi = po2; - if(N<(double)0.0) - *phi *= (double)-1.; + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double Ra; + double sRa2; + double sRa8; + + double dx; + double dy; + double theta=(double)0.; + double tt; + double i; + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + sRa2 = pow((double)2.,(double).5) * Ra; + sRa8 = pow((double)8.,(double).5) * Ra; + + if (M0>GPS_PI) { + M0 -= p2; + } + + dx = E - E0; + dy = N - N0; + i = dy/sRa2; + if (fabs(i)>(double)1.) { + *phi = po2; + if (N<(double)0.0) { + *phi *= (double)-1.; } - else - { - theta = asin(i); - tt = theta * (double)2.; - *phi = asin((tt+sin(tt))/(double)GPS_PI); - if(*phi>po2) - *phi=po2; - else if (*phi<-po2) - *phi=-po2; + } else { + theta = asin(i); + tt = theta * (double)2.; + *phi = asin((tt+sin(tt))/(double)GPS_PI); + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; } + } - if(fabs(fabs(*phi)-po2)<(double)1.0e-10) - *lambda = M0; - else - *lambda = M0 + (double)GPS_PI * dx / (sRa8 * cos(theta)); + if (fabs(fabs(*phi)-po2)<(double)1.0e-10) { + *lambda = M0; + } else { + *lambda = M0 + (double)GPS_PI * dx / (sRa8 * cos(theta)); + } - if(*lambda>GPS_PI) - *lambda-=p2; - if(*lambda<-GPS_PI) - *lambda+=p2; + if (*lambda>GPS_PI) { + *lambda-=p2; + } + if (*lambda<-GPS_PI) { + *lambda+=p2; + } - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -2963,63 +3017,66 @@ void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double a, double b) +void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double phi0s; - double phi0c; - - double phis; - double phic; - double dlam; - double clc; - double cc; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(lambda0>GPS_PI) - lambda0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* - e6/(double)3024.); - phi0s = sin(phi0); - phi0c = cos(phi0); - - dlam = lambda - lambda0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - - phis = sin(phi); - phic = cos(phi); - clc = phic * cos(dlam); - cc = phi0s * phis + phi0c * clc; - - *E = Ra * phic * sin(dlam) + E0; - *N = Ra * (phi0c * phis - phi0s * clc) + N0; - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double phi0s; + double phi0c; + + double phis; + double phic; + double dlam; + double clc; + double cc; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (lambda0>GPS_PI) { + lambda0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + phi0s = sin(phi0); + phi0c = cos(phi0); + + dlam = lambda - lambda0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + + phis = sin(phi); + phic = cos(phi); + clc = phic * cos(dlam); + cc = phi0s * phis + phi0c * clc; + + *E = Ra * phic * sin(dlam) + E0; + *N = Ra * (phi0c * phis - phi0s * clc) + N0; + + return; } @@ -3043,98 +3100,102 @@ void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b) +void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double phi0s; - double phi0c; - - double dx; - double dy; - double rho; - double adod; - double ror; - double cc; - double ccs; - double ccc; - - - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(lambda0>GPS_PI) - lambda0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* - e6/(double)3024.); - phi0s = sin(phi0); - phi0c = cos(phi0); - - - dx = E - E0; - dy = N - N0; - adod = atan(dx/dy); - rho = pow(dx*dx+dy*dy,(double).5); - if(!rho) - { - *phi = phi0; - *lambda = lambda0; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double phi0s; + double phi0c; + + double dx; + double dy; + double rho; + double adod; + double ror; + double cc; + double ccs; + double ccc; + + + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (lambda0>GPS_PI) { + lambda0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + phi0s = sin(phi0); + phi0c = cos(phi0); + + + dx = E - E0; + dy = N - N0; + adod = atan(dx/dy); + rho = pow(dx*dx+dy*dy,(double).5); + if (!rho) { + *phi = phi0; + *lambda = lambda0; + } else { + ror = rho/Ra; + if (ror>(double)1.) { + ror=(double)1.; + } else if (ror<(double)-1.) { + ror=(double)-1.; } - else - { - ror = rho/Ra; - if(ror>(double)1.) - ror=(double)1.; - else if(ror<(double)-1.) - ror=(double)-1.; - cc = asin(ror); - ccs = sin(cc); - ccc = cos(cc); - *phi = asin(ccc*phi0s+(dy*ccs*phi0c/rho)); - if(phi0==po2) - *lambda = lambda0 - adod; - else if(phi0==-po2) - *lambda = lambda0 + adod; - else - *lambda = lambda0+atan(dx*ccs/(rho*phi0c*ccc-dy*phi0s*ccs)); + cc = asin(ror); + ccs = sin(cc); + ccc = cos(cc); + *phi = asin(ccc*phi0s+(dy*ccs*phi0c/rho)); + if (phi0==po2) { + *lambda = lambda0 - adod; + } else if (phi0==-po2) { + *lambda = lambda0 + adod; + } else { + *lambda = lambda0+atan(dx*ccs/(rho*phi0c*ccc-dy*phi0s*ccs)); } - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + } + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -3158,100 +3219,100 @@ void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - - double phis; - double phis2; - double phis4; - double phis6; - double dlam; - double NN; - double NNot; - double MM; - double EE; - double lat; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - AM0 = a*(lat-phi0s2+phi0s4-phi0s6); - - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - phis = sin(phi); - - if(!phi) - { - *E = a * dlam + E0; - *N = -AM0 + N0; - } - else - { - NN = a / pow((double)1.-e2*phis*phis,(double).5); - NNot = NN / tan(phi); - lat = c0 * phi; - phis2 = c1 * sin((double)2.0*phi); - phis4 = c2 * sin((double)4.0*phi); - phis6 = c3 * sin((double)6.0*phi); - MM = a*(lat-phis2+phis4-phis6); - EE = dlam *phis; - *E = NNot * sin(EE) + E0; - *N = MM - AM0 + NNot * ((double)1.-cos(EE)) + N0; - } - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + + double phis; + double phis2; + double phis4; + double phis6; + double dlam; + double NN; + double NNot; + double MM; + double EE; + double lat; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + + if (!phi) { + *E = a * dlam + E0; + *N = -AM0 + N0; + } else { + NN = a / pow((double)1.-e2*phis*phis,(double).5); + NNot = NN / tan(phi); + lat = c0 * phi; + phis2 = c1 * sin((double)2.0*phi); + phis4 = c2 * sin((double)4.0*phi); + phis6 = c3 * sin((double)6.0*phi); + MM = a*(lat-phis2+phis4-phis6); + EE = dlam *phis; + *E = NNot * sin(EE) + E0; + *N = MM - AM0 + NNot * ((double)1.-cos(EE)) + N0; + } + + return; } @@ -3275,144 +3336,146 @@ void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - - double dx; - double dy; - double dxoa; - double AA; - double BB; - double CC=(double)0.; - double PHIn; - double PHId; - double PHIs; - double PHI; - double PHIs2; - double PHIs4; - double PHIs6; - double Mn; - double Mnp; - double Ma; - double AAMa; - double mpb; - double AAmin; - double tol; - double lat; - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - AM0 = a*(lat-phi0s2+phi0s4-phi0s6); - - tol = (double)1.0e-12; - - dx = E - E0; - dy = N - N0; - dxoa = dx/a; - if((((-AM0-(double)1.)GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + tol = (double)1.0e-12; + + dx = E - E0; + dy = N - N0; + dxoa = dx/a; + if ((((-AM0-(double)1.)tol) { + PHIs = sin(PHIn); + CC = pow((double)1.-e2*PHIs*PHIs,(double).5) * tan(PHIn); + PHI = PHIn * c0; + PHIs2 = c1 * sin((double)2.0*PHIn); + PHIs4 = c2 * sin((double)4.0*PHIn); + PHIs6 = c3 * sin((double)6.0*PHIn); + Mn = a*(PHI-PHIs2+PHIs4-PHIs6); + Mnp = c0 - (double)2.*c1*cos((double)2.*PHIn)+(double)4.*c2* + cos((double)4.*PHIn)-(double)6.*c3*cos((double)6.*PHIn); + Ma = Mn / a; + AAMa = AA * Ma; + mpb = Ma*Ma+BB; + AAmin = AA - Ma; + PHId = (AAMa*CC+AAmin-(double).5*mpb*CC)/ + (e2*PHIs2*(mpb-(double)2.*AAMa) / + (double)4.*CC+AAmin*(CC*Mnp-(double)2./PHIs2)-Mnp); + PHIn -= PHId; } - else - { - AA = (AM0+dy) / a; - BB = dxoa * dxoa + (AA*AA); - PHIn = AA; - PHId = (double)1.; - - while(fabs(PHId)>tol) - { - PHIs = sin(PHIn); - CC = pow((double)1.-e2*PHIs*PHIs,(double).5) * tan(PHIn); - PHI = PHIn * c0; - PHIs2 = c1 * sin((double)2.0*PHIn); - PHIs4 = c2 * sin((double)4.0*PHIn); - PHIs6 = c3 * sin((double)6.0*PHIn); - Mn = a*(PHI-PHIs2+PHIs4-PHIs6); - Mnp = c0 - (double)2.*c1*cos((double)2.*PHIn)+(double)4.*c2* - cos((double)4.*PHIn)-(double)6.*c3*cos((double)6.*PHIn); - Ma = Mn / a; - AAMa = AA * Ma; - mpb = Ma*Ma+BB; - AAmin = AA - Ma; - PHId = (AAMa*CC+AAmin-(double).5*mpb*CC)/ - (e2*PHIs2*(mpb-(double)2.*AAMa) / - (double)4.*CC+AAmin*(CC*Mnp-(double)2./PHIs2)-Mnp); - PHIn -= PHId; - } - *phi = PHIn; - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if((((po2-(double).00001)po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; } - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + if ((((po2-(double).00001)GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } - return; + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -3435,94 +3498,97 @@ void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double p2; - double po2; - double c0; - double c1; - double c2; - double c3; - double A1; - double A0; - double A2; - double A3; - double E1; - double E2; - double E3; - double E4; - double j; - double om0; - double som0; - - double phis; - double phis2; - double phis4; - double phis6; - double mm; - double MM; - double dlam; - - - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - j = (double)45.*e6/(double)1024.; - c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* - e6/(double)256.; - c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - om0 = (double)1. - e2; - som0 = pow(om0,(double).5); - E1 = ((double)1.-som0)/((double)1.+som0); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - if(M0>GPS_PI) - M0 -= p2; - - phis = sin(phi); - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam-=p2; - if(dlam<-GPS_PI) - dlam+=p2; - - mm = pow((double)1.-e2*phis*phis,(double).5); - phis2 = c1 * sin((double)2.*phi); - phis4 = c2 * sin((double)4.*phi); - phis6 = c3 * sin((double)6.*phi); - MM = a * (c0*phi-phis2+phis4-phis6); - - - - *E = a*dlam*cos(phi)/mm+E0; - *N = MM + N0; - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double c0; + double c1; + double c2; + double c3; + double A1; + double A0; + double A2; + double A3; + double E1; + double E2; + double E3; + double E4; + double j; + double om0; + double som0; + + double phis; + double phis2; + double phis4; + double phis6; + double mm; + double MM; + double dlam; + + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + j = (double)45.*e6/(double)1024.; + c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* + e6/(double)256.; + c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + om0 = (double)1. - e2; + som0 = pow(om0,(double).5); + E1 = ((double)1.-som0)/((double)1.+som0); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + if (M0>GPS_PI) { + M0 -= p2; + } + + phis = sin(phi); + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam-=p2; + } + if (dlam<-GPS_PI) { + dlam+=p2; + } + + mm = pow((double)1.-e2*phis*phis,(double).5); + phis2 = c1 * sin((double)2.*phi); + phis4 = c2 * sin((double)4.*phi); + phis6 = c3 * sin((double)6.*phi); + MM = a * (c0*phi-phis2+phis4-phis6); + + + + *E = a*dlam*cos(phi)/mm+E0; + *N = MM + N0; + + return; } @@ -3545,109 +3611,112 @@ void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) +void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double p2; - double po2; - double c0; - double c1; - double c2; - double c3; - double A1; - double A0; - double A2; - double A3; - double E1; - double E2; - double E3; - double E4; - double j; - double om0; - double som0; - - double dx; - double dy; - double mu; - double mu2s; - double mu4s; - double mu6s; - double mu8s; - double phis; - - - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - j = (double)45.*e6/(double)1024.; - c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* - e6/(double)256.; - c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - om0 = (double)1. - e2; - som0 = pow(om0,(double).5); - E1 = ((double)1.-som0)/((double)1.+som0); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - dx = E - E0; - dy = N - N0; - - mu = dy/(c0*a); - mu2s = A0 * sin((double)2.*mu); - mu4s = A1 * sin((double)4.*mu); - mu6s = A2 * sin((double)6.*mu); - mu8s = A3 * sin((double)8.*mu); - *phi = mu + mu2s + mu4s + mu6s + mu8s; - - if(*phi>po2) - *phi=po2; - else if (*phi<-po2) - *phi=-po2; - - if((((po2-(double)1.0e-8)GPS_PI) - *lambda-=p2; - if(*lambda<-GPS_PI) - *lambda+=p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double c0; + double c1; + double c2; + double c3; + double A1; + double A0; + double A2; + double A3; + double E1; + double E2; + double E3; + double E4; + double j; + double om0; + double som0; + + double dx; + double dy; + double mu; + double mu2s; + double mu4s; + double mu6s; + double mu8s; + double phis; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + j = (double)45.*e6/(double)1024.; + c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* + e6/(double)256.; + c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + om0 = (double)1. - e2; + som0 = pow(om0,(double).5); + E1 = ((double)1.-som0)/((double)1.+som0); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + dx = E - E0; + dy = N - N0; + + mu = dy/(c0*a); + mu2s = A0 * sin((double)2.*mu); + mu4s = A1 * sin((double)4.*mu); + mu6s = A2 * sin((double)6.*mu); + mu8s = A3 * sin((double)8.*mu); + *phi = mu + mu2s + mu4s + mu6s + mu8s; + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if ((((po2-(double)1.0e-8)GPS_PI) { + *lambda-=p2; + } + if (*lambda<-GPS_PI) { + *lambda+=p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -3671,176 +3740,176 @@ void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b) +void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, double E0, + double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e; - double e2; - double e4; - double e6; - double AM0; - double qp; - double om; - double oo; - double c0; - double c1; - double c2; - double c3; - double b0; - double b1; - double B2; - double b3; - double A0; - double A1; - double A2; - double sf; - double x; - double som; - double phis; - double j; - double te4; - double lat; - double phi0s2; - double phi0s4; - double phi0s6; - double E1; - double E2; - double E3; - double E4; - - double dlam; - double qq; - double qqo; - double bt; - double btc; - double PHI; - double PHIs2; - double PHIs4; - double PHIs6; - double bts2; - double bts4; - double bts6; - double PHIc; - double PHIcs; - double Mc; - - - - sf = (double)1.0; /* scale factor */ - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - e = pow(e2,(double).5); - om = (double)1.-e2; - som = pow(om,(double).5); - oo = (double)1./((double)2.*e); - - phis = sin(po2); - x = e * phis; - qp = om*(phis/((double)1.-e2*phis*phis)-oo* - log(((double)1.-x)/((double)1.+x))); - - A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* - e6/(double)5040.; - A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; - A2 = (double)761.*e6/(double)45360.; - - E1 = ((double)1.0-som) / ((double)1.0+som); - E2 = E1*E1; - E3 = E2*E1; - E4 = E3*E1; - - b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - B2 = (double)151.*E3/(double)96.; - b3 = (double)1097.*E4/(double)512.; - - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - AM0 = a*(lat-phi0s2+phi0s4-phi0s6); - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - phis = sin(phi); - - if(phi==po2) - { - qq = qp; - qqo = (double)1.; - } - else - { - x = e * phis; - qq = om*(phis/((double)1.-e2*phis*phis)-oo* - log(((double)1.-x)/((double)1.+x))); - qqo = qq/qp; - } - - if(qqo>(double)1.) - qqo = (double)1.; - else if(qqo<(double)-1.) - qqo = (double)-1.; - - bt = asin(qqo); - btc = atan(tan(bt)/cos(dlam)); - - if((fabs(btc)-po2)>(double)1.0e-8) - PHIc = btc; - else - { - bts2 = A0 * sin((double)2.0*btc); - bts4 = A1 * sin((double)4.0*btc); - bts6 = A2 * sin((double)6.0*btc); - PHIc = btc + bts2 + bts4 + bts6; - } - - PHIcs = sin(PHIc); - *E = a*cos(bt)*cos(PHIc)*sin(dlam)/(sf*cos(btc)* - pow((double)1.-e2*PHIcs*PHIcs, - (double).5)) + E0; - PHI = c0 * PHIc; - PHIs2 = c1 * sin((double)2.0*PHIc); - PHIs4 = c2 * sin((double)4.0*PHIc); - PHIs6 = c3 * sin((double)6.0*PHIc); - Mc = a*(PHI-PHIs2+PHIs4-PHIs6); - - *N = sf * (Mc-AM0) + N0; - - return; + double p2; + double po2; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double AM0; + double qp; + double om; + double oo; + double c0; + double c1; + double c2; + double c3; + double b0; + double b1; + double B2; + double b3; + double A0; + double A1; + double A2; + double sf; + double x; + double som; + double phis; + double j; + double te4; + double lat; + double phi0s2; + double phi0s4; + double phi0s6; + double E1; + double E2; + double E3; + double E4; + + double dlam; + double qq; + double qqo; + double bt; + double btc; + double PHI; + double PHIs2; + double PHIs4; + double PHIs6; + double bts2; + double bts4; + double bts6; + double PHIc; + double PHIcs; + double Mc; + + + + sf = (double)1.0; /* scale factor */ + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + om = (double)1.-e2; + som = pow(om,(double).5); + oo = (double)1./((double)2.*e); + + phis = sin(po2); + x = e * phis; + qp = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + + A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + A2 = (double)761.*e6/(double)45360.; + + E1 = ((double)1.0-som) / ((double)1.0+som); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + B2 = (double)151.*E3/(double)96.; + b3 = (double)1097.*E4/(double)512.; + + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + + if (phi==po2) { + qq = qp; + qqo = (double)1.; + } else { + x = e * phis; + qq = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + qqo = qq/qp; + } + + if (qqo>(double)1.) { + qqo = (double)1.; + } else if (qqo<(double)-1.) { + qqo = (double)-1.; + } + + bt = asin(qqo); + btc = atan(tan(bt)/cos(dlam)); + + if ((fabs(btc)-po2)>(double)1.0e-8) { + PHIc = btc; + } else { + bts2 = A0 * sin((double)2.0*btc); + bts4 = A1 * sin((double)4.0*btc); + bts6 = A2 * sin((double)6.0*btc); + PHIc = btc + bts2 + bts4 + bts6; + } + + PHIcs = sin(PHIc); + *E = a*cos(bt)*cos(PHIc)*sin(dlam)/(sf*cos(btc)* + pow((double)1.-e2*PHIcs*PHIcs, + (double).5)) + E0; + PHI = c0 * PHIc; + PHIs2 = c1 * sin((double)2.0*PHIc); + PHIs4 = c2 * sin((double)4.0*PHIc); + PHIs6 = c3 * sin((double)6.0*PHIc); + Mc = a*(PHI-PHIs2+PHIs4-PHIs6); + + *N = sf * (Mc-AM0) + N0; + + return; } @@ -3864,183 +3933,190 @@ void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) +void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e; - double e2; - double e4; - double e6; - double AM0; - double qp; - double om; - double oo; - double c0; - double c1; - double c2; - double c3; - double b0; - double b1; - double B2; - double b3; - double A0; - double A1; - double A2; - double sf; - double x; - double som; - double phis; - double j; - double te4; - double lat; - double phi0s2; - double phi0s4; - double phi0s6; - double E1; - double E2; - double E3; - double E4; - - double dx; - double dy; - double bt; - double btc; - double btp; - double btcc; - double Mc; - double Muc; - double mus2; - double mus4; - double mus6; - double mus8; - double bts2; - double bts4; - double bts6; - double PHIc; - double Qc; - double Qco; - double t; - - - sf = (double)1.0; /* scale factor */ - - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - e = pow(e2,(double).5); - om = (double)1.-e2; - som = pow(om,(double).5); - oo = (double)1./((double)2.*e); - - phis = sin(po2); - x = e * phis; - qp = om*(phis/((double)1.-e2*phis*phis)-oo* - log(((double)1.-x)/((double)1.+x))); - - A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* - e6/(double)5040.; - A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; - A2 = (double)761.*e6/(double)45360.; - - E1 = ((double)1.0-som) / ((double)1.0+som); - E2 = E1*E1; - E3 = E2*E1; - E4 = E3*E1; - - b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - B2 = (double)151.*E3/(double)96.; - b3 = (double)1097.*E4/(double)512.; - - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - AM0 = a*(lat-phi0s2+phi0s4-phi0s6); - - - - dx = E - E0; - dy = N - N0; - Mc = AM0 + dy/sf; - Muc = Mc / (c0*a); - - mus2 = b0 * sin((double)2.0*Muc); - mus4 = b1 * sin((double)4.0*Muc); - mus6 = B2 * sin((double)6.0*Muc); - mus8 = b3 * sin((double)6.0*Muc); - PHIc = Muc + mus2 + mus4 + mus6 + mus8; - - phis = sin(PHIc); - x = e * phis; - Qc = om*(phis/((double)1.-e2*phis*phis)-oo* - log(((double)1.-x)/((double)1.+x))); - Qco = Qc/qp; - - if(Qco>(double)1.) - Qco = (double)1.; - else if(Qco<(double)-1.) - Qco = (double)-1.; - - btc = asin(Qco); - btcc = cos(btc); - t = sf*dx*btcc*pow((double)1.-e2*phis*phis,(double).5)/(a*cos(PHIc)); - if(t>(double)1.) - t=(double)1.; - else if(t<(double)-1.) - t=(double)-1.; - btp = -asin(t); - bt = asin(cos(btp)*sin(btc)); - - bts2 = A0 * sin((double)2.0*bt); - bts4 = A1 * sin((double)4.0*bt); - bts6 = A2 * sin((double)6.0*bt); - *phi = bt + bts2 + bts4 + bts6; - *lambda = M0 - atan(tan(btp)/btcc); - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double p2; + double po2; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double AM0; + double qp; + double om; + double oo; + double c0; + double c1; + double c2; + double c3; + double b0; + double b1; + double B2; + double b3; + double A0; + double A1; + double A2; + double sf; + double x; + double som; + double phis; + double j; + double te4; + double lat; + double phi0s2; + double phi0s4; + double phi0s6; + double E1; + double E2; + double E3; + double E4; + + double dx; + double dy; + double bt; + double btc; + double btp; + double btcc; + double Mc; + double Muc; + double mus2; + double mus4; + double mus6; + double mus8; + double bts2; + double bts4; + double bts6; + double PHIc; + double Qc; + double Qco; + double t; + + + sf = (double)1.0; /* scale factor */ + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + om = (double)1.-e2; + som = pow(om,(double).5); + oo = (double)1./((double)2.*e); + + phis = sin(po2); + x = e * phis; + qp = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + + A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + A2 = (double)761.*e6/(double)45360.; + + E1 = ((double)1.0-som) / ((double)1.0+som); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + B2 = (double)151.*E3/(double)96.; + b3 = (double)1097.*E4/(double)512.; + + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + + dx = E - E0; + dy = N - N0; + Mc = AM0 + dy/sf; + Muc = Mc / (c0*a); + + mus2 = b0 * sin((double)2.0*Muc); + mus4 = b1 * sin((double)4.0*Muc); + mus6 = B2 * sin((double)6.0*Muc); + mus8 = b3 * sin((double)6.0*Muc); + PHIc = Muc + mus2 + mus4 + mus6 + mus8; + + phis = sin(PHIc); + x = e * phis; + Qc = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + Qco = Qc/qp; + + if (Qco>(double)1.) { + Qco = (double)1.; + } else if (Qco<(double)-1.) { + Qco = (double)-1.; + } + + btc = asin(Qco); + btcc = cos(btc); + t = sf*dx*btcc*pow((double)1.-e2*phis*phis,(double).5)/(a*cos(PHIc)); + if (t>(double)1.) { + t=(double)1.; + } else if (t<(double)-1.) { + t=(double)-1.; + } + btp = -asin(t); + bt = asin(cos(btp)*sin(btc)); + + bts2 = A0 * sin((double)2.0*bt); + bts4 = A1 * sin((double)4.0*bt); + bts6 = A2 * sin((double)6.0*bt); + *phi = bt + bts2 + bts4 + bts6; + *lambda = M0 - atan(tan(btp)/btcc); + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -4064,84 +4140,88 @@ void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double a, double b) +void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e3; - double e; - double es; - double ab; - double bb; - double cb; - double db; - double ml; - double phi0s; - double sf; - - double dlam; - double ct; - double ex; - double tt; - double pt; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - ml = ((double)GPS_PI*(double)89.5)/(double)180.; - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(lambda0>GPS_PI) - lambda0 -= p2; - a2 = a*a; - b2 = b*b; - es = (a2-b2)/a2; - e2 = es*es; - e3 = e2*es; - e4 = e3*es; - - e = pow(es,(double).5); - phi0s = sin(phi0); - sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); - - ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* - e4/(double)360.; - bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ - (double)811.*e4/(double)11520.; - cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; - db = (double)4279.*e4/(double)161280.; - - - - if(lambda>(double)GPS_PI) - lambda -= p2; - - dlam = lambda - lambda0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - - ex = e * sin(phi); - tt = tan((double)GPS_PI/(double)4.+phi/(double)2.); - pt = pow((((double)1.-ex)/((double)1.+ex)),(e/(double)2.)); - - ct = tt * pt; - *N = sf * a * log(ct) + N0; - *E = sf * a * dlam + E0; - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e3; + double e; + double es; + double ab; + double bb; + double cb; + double db; + double ml; + double phi0s; + double sf; + + double dlam; + double ct; + double ex; + double tt; + double pt; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + ml = ((double)GPS_PI*(double)89.5)/(double)180.; + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (lambda0>GPS_PI) { + lambda0 -= p2; + } + a2 = a*a; + b2 = b*b; + es = (a2-b2)/a2; + e2 = es*es; + e3 = e2*es; + e4 = e3*es; + + e = pow(es,(double).5); + phi0s = sin(phi0); + sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); + + ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* + e4/(double)360.; + bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ + (double)811.*e4/(double)11520.; + cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; + db = (double)4279.*e4/(double)161280.; + + + + if (lambda>(double)GPS_PI) { + lambda -= p2; + } + + dlam = lambda - lambda0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + + ex = e * sin(phi); + tt = tan((double)GPS_PI/(double)4.+phi/(double)2.); + pt = pow((((double)1.-ex)/((double)1.+ex)),(e/(double)2.)); + + ct = tt * pt; + *N = sf * a * log(ct) + N0; + *E = sf * a * dlam + E0; + + return; } @@ -4165,86 +4245,91 @@ void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, - double lambda0, double E0, double N0, - double a, double b) +void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, + double lambda0, double E0, double N0, + double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e3; - double e; - double es; - double ab; - double bb; - double cb; - double db; - double ml; - double phi0s; - double sf; - - double dx; - double dy; - double x; - - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - ml = ((double)GPS_PI*(double)89.5)/(double)180.; - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(lambda0>GPS_PI) - lambda0 -= p2; - a2 = a*a; - b2 = b*b; - es = (a2-b2)/a2; - e2 = es*es; - e3 = e2*es; - e4 = e3*es; - - e = pow(es,(double).5); - phi0s = sin(phi0); - sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); - - ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* - e4/(double)360.; - bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ - (double)811.*e4/(double)11520.; - cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; - db = (double)4279.*e4/(double)161280.; - - dx = E - E0; - dy = N - N0; - *lambda = lambda0 + dx / (sf*a); - x = (double)GPS_PI / (double)2. - - (double)2.*atan((double)1./exp(dy/(sf*a))); - *phi = x+ab*sin((double)2.*x)+bb*sin((double)4.*x)+cb*sin((double)6.*x) - + db*sin((double)8.*x); - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e3; + double e; + double es; + double ab; + double bb; + double cb; + double db; + double ml; + double phi0s; + double sf; + + double dx; + double dy; + double x; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + ml = ((double)GPS_PI*(double)89.5)/(double)180.; + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (lambda0>GPS_PI) { + lambda0 -= p2; + } + a2 = a*a; + b2 = b*b; + es = (a2-b2)/a2; + e2 = es*es; + e3 = e2*es; + e4 = e3*es; + + e = pow(es,(double).5); + phi0s = sin(phi0); + sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); + + ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* + e4/(double)360.; + bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ + (double)811.*e4/(double)11520.; + cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; + db = (double)4279.*e4/(double)161280.; + + dx = E - E0; + dy = N - N0; + *lambda = lambda0 + dx / (sf*a); + x = (double)GPS_PI / (double)2. - + (double)2.*atan((double)1./exp(dy/(sf*a))); + *phi = x+ab*sin((double)2.*x)+bb*sin((double)4.*x)+cb*sin((double)6.*x) + + db*sin((double)8.*x); + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -4269,14 +4354,14 @@ void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ************************************************************************/ -void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double F0, - double a, double b) +void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b) { - GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - - return; + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; } @@ -4301,14 +4386,14 @@ void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, ** ** @return [void] ************************************************************************/ -void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double F0, - double a, double b) +void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b) { - GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - - return; + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; } @@ -4331,65 +4416,65 @@ void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, ** ** @return [void] ***************************************************************************/ -void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, - double *N,double phi0,double lambda0, - double E0, double N0, double a, double b) +void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double* E, + double* N,double phi0,double lambda0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double esq; - double e; - double c; - double ephi0p; - double phip; - double sphip; - double phid; - double slambda2; - double lambda1; - double lambda2; - double K; - double po4; - double w; - double R; - - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - - po4=GPS_PI/(double)4.0; - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); - - ephi0p = asin(sin(phi0)/c); - - K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - - e/(double)2. * log(((double)1.+e*sin(phi0)) / - ((double)1.-e*sin(phi0)))); - lambda1 = c*(lambda-lambda0); - w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * - log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; - - - phip = (double)2. * (atan(exp(w)) - po4); - - sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); - phid = asin(sphip); - - slambda2 = cos(phip)*sin(lambda1) / cos(phid); - lambda2 = asin(slambda2); - - R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); - - *N = R*log(tan(po4 + phid/(double)2.)) + N0; - *E = R*lambda2 + E0; - return; + double a2; + double b2; + double esq; + double e; + double c; + double ephi0p; + double phip; + double sphip; + double phid; + double slambda2; + double lambda1; + double lambda2; + double K; + double po4; + double w; + double R; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + + po4=GPS_PI/(double)4.0; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); + + ephi0p = asin(sin(phi0)/c); + + K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - + e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + lambda1 = c*(lambda-lambda0); + w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; + + + phip = (double)2. * (atan(exp(w)) - po4); + + sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); + phid = asin(sphip); + + slambda2 = cos(phip)*sin(lambda1) / cos(phid); + lambda2 = asin(slambda2); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + *N = R*log(tan(po4 + phid/(double)2.)) + N0; + *E = R*lambda2 + E0; + return; } @@ -4413,73 +4498,71 @@ void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] *************************************************************************/ -void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b) +void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double esq; - double e; - double R; - double c; - double po4; - double phid; - double phi1; - double lambdad; - double lambda1; - double slambda1; - double ephi0p; - double sphip; - double tol; - double cr; - double C; - double K; - - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - - po4=GPS_PI/(double)4.0; - tol=(double)0.00001; - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); - - phid = (double)2.*(atan(exp((N - N0)/R)) - po4); - lambdad = (E - E0)/R; - - c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / - ((double)1.-esq))); - ephi0p = asin(sin(phi0) / c); - - sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); - phi1 = asin(sphip); - - slambda1 = cos(phid)*sin(lambdad)/cos(phi1); - lambda1 = asin(slambda1); - - *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); - - K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) - - e/(double)2. * log(((double)1.+e*sin(phi0)) / - ((double)1.-e*sin(phi0)))); - C = (K - log(tan(po4 + phi1/(double)2.)))/c; - - do - { - cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * - log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * - ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / - ((double)1.-esq)); - phi1 -= cr; - } - while (fabs(cr) > tol); - - *phi = GPS_Math_Rad_To_Deg(phi1); - - return; + double a2; + double b2; + double esq; + double e; + double R; + double c; + double po4; + double phid; + double phi1; + double lambdad; + double lambda1; + double slambda1; + double ephi0p; + double sphip; + double tol; + double cr; + double C; + double K; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + + po4=GPS_PI/(double)4.0; + tol=(double)0.00001; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + phid = (double)2.*(atan(exp((N - N0)/R)) - po4); + lambdad = (E - E0)/R; + + c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / + ((double)1.-esq))); + ephi0p = asin(sin(phi0) / c); + + sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); + phi1 = asin(sphip); + + slambda1 = cos(phid)*sin(lambdad)/cos(phi1); + lambda1 = asin(slambda1); + + *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); + + K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) + - e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + C = (K - log(tan(po4 + phi1/(double)2.)))/c; + + do { + cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * + ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / + ((double)1.-esq)); + phi1 -= cr; + } while (fabs(cr) > tol); + + *phi = GPS_Math_Rad_To_Deg(phi1); + + return; } diff --git a/gpsbabel/jeeps/gpsproj.h b/gpsbabel/jeeps/gpsproj.h index 6922a47e0..7206b06d5 100644 --- a/gpsbabel/jeeps/gpsproj.h +++ b/gpsbabel/jeeps/gpsproj.h @@ -9,146 +9,146 @@ extern "C" #include "gps.h" -void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Albers_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b); - - -void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Bonne_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b); -void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b); -void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, double N0, - double a, double b); -void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, double N0, - double a, double b); -void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b); -void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double lambda1, - double E0, double N0, double a, double b); -void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double lambda1, - double E0, double N0, double a, double b); - -void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double a, double b); -void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b); - -void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b); -void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double a, double b); -void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, - double lambda0, double E0, double N0, - double a, double b); - -void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double F0, - double a, double b); -void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double F0, - double a, double b); - -void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, - double *N,double phi0,double lambda0, - double E0, double N0, double a, double b); -void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b); + void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Albers_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + + + void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Miller_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Bonne_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, + double E0, double N0, double a, double b); + void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, + double E0, double N0, double a, double b); + void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, double N0, + double a, double b); + void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, double N0, + double a, double b); + void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, + double N0, double a, double b); + void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi1, double lambda1, + double E0, double N0, double a, double b); + void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi1, double lambda1, + double E0, double N0, double a, double b); + + void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double lambda0, + double E0, double N0, double a, double b); + void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double lambda0, + double E0, double N0, double a, double b); + + void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, + double E0, double N0, double a, double b); + void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double lambda0, + double E0, double N0, double a, double b); + void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, + double lambda0, double E0, double N0, + double a, double b); + + void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double* E, + double* N, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b); + void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b); + + void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double* E, + double* N,double phi0,double lambda0, + double E0, double N0, double a, double b); + void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double* phi, + double* lambda, double phi0, double lambda0, + double E0, double N0, double a, double b); #endif diff --git a/gpsbabel/jeeps/gpsprot.c b/gpsbabel/jeeps/gpsprot.c index 93bf9c971..85304bfee 100644 --- a/gpsbabel/jeeps/gpsprot.c +++ b/gpsbabel/jeeps/gpsprot.c @@ -2,26 +2,27 @@ ** @source JEEPS protocol table lookup functions (GPS' without A001) ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @modified Copyright (C) 2006 Robert Lipe ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ********************************************************************/ +#define COMMON #include "gps.h" #include @@ -34,212 +35,264 @@ static int32 gps_n_tag_unknown = 0; -struct COMMANDDATA COMMAND_ID[2]= -{ - /* Device Command Protocol 1 (A010) */ - { - 0,1,2,3,4,5,6,7,8,49,50,92,117,121,450,451,452,453,454,561,562,563,564,565 - } - , - /* Device Command Protocol 2 (A011) */ - { - 0,4,0,17,8,20,0,21,26,0,0 - } +struct COMMANDDATA COMMAND_ID[2]= { + /* Device Command Protocol 1 (A010) */ + { + 0,1,2,3,4,5,6,7,8,49,50,92,117,121,450,451,452,453,454,561,562,563,564,565 + } + , + /* Device Command Protocol 2 (A011) */ + { + 0,4,0,17,8,20,0,21,26,0,0 + } }; -struct LINKDATA LINK_ID[3]= -{ - /* Basic Link Protocol (L000) */ - { - 253,254,255,248, - 6,0,0,0,0,0,21,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - } - , - /* Link Protocol 1 (L001) */ - { - 253,254,255,248, - 6,10,12,14,17,19,21,27,29,30,31, - 34,35,51,98,99, - 134,149,152,990,991,992,993,994,1061,1062,1063,1064,1065,1066,222 - } - , - /* Link Protocol 2 (L002) */ - { - 253,254,255,248, - 6,11,12,20,24,0,21,35,37,39,4, - 0,43,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - } +struct LINKDATA LINK_ID[3]= { + /* Basic Link Protocol (L000) */ + { + 253,254,255,248, + 6,0,0,0,0,0,21,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + , + /* Link Protocol 1 (L001) */ + { + 253,254,255,248, + 6,10,12,14,17,19,21,27,29,30,31, + 34,35,51,98,99, + 134,149,152,990,991,992,993,994,1061,1062,1063,1064,1065,1066,222 + } + , + /* Link Protocol 2 (L002) */ + { + 253,254,255,248, + 6,11,12,20,24,0,21,35,37,39,4, + 0,43,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } }; -struct GPS_MODEL_PROTOCOL GPS_MP[]= -{ - { 7,pL001,pA010,pA100,pD100,pA200,pD200,-1,-1,-1,-1,-1, - pA500,pD500 - }, - { 13,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 14,pL001,pA010,pA100,pD100,pA200,pD200,pD100,-1,-1,pA400,pD400, - pA500,pD500 - }, - { 15,pL001,pA010,pA100,pD151,pA200,pD200,pD151,-1,-1,pA400,pD151, - pA500,pD500 - }, - { 18,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 20,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD550 - }, - { 22,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, - pA500,pD500 - }, - { 23,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 24,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 25,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 29,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, - pA500,pD500 - }, - { 929,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, - pA500,pD500 - }, - { 31,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 33,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD550 - }, - { 34,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD550 - }, - { 35,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 36,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, - pA500,pD500 - }, - { 936,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 39,pL001,pA010,pA100,pD151,pA200,pD201,pD151,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 41,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 42,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 44,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, - pA500,pD500 - }, - { 45,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 47,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 48,pL001,pA010,pA100,pD154,pA200,pD201,pD154,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 49,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, - pA500,pD501 - }, - { 50,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 52,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD550 - }, - { 53,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 55,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 56,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 59,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 61,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 62,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 64,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD551 - }, - { 71,pL001,pA010,pA100,pD155,pA200,pD201,pD155,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 72,pL001,pA010,pA100,pD104,pA200,pD201,pD104,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 73,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 74,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 76,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, - pA500,pD501 - }, - { 77,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,pA400,pD400, - pA500,pD501 - }, - { 777,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 877,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 977,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 87,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 88,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, - pA500,pD501 - }, - { 95,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 96,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 97,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 98,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD551 - }, - { 100,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 105,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 106,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 112,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 - } +struct GPS_MODEL_PROTOCOL GPS_MP[]= { + { + 7,pL001,pA010,pA100,pD100,pA200,pD200,-1,-1,-1,-1,-1, + pA500,pD500 + }, + { + 13,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 14,pL001,pA010,pA100,pD100,pA200,pD200,pD100,-1,-1,pA400,pD400, + pA500,pD500 + }, + { + 15,pL001,pA010,pA100,pD151,pA200,pD200,pD151,-1,-1,pA400,pD151, + pA500,pD500 + }, + { + 18,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 20,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { + 22,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, + pA500,pD500 + }, + { + 23,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 24,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 25,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 29,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, + pA500,pD500 + }, + { + 929,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD500 + }, + { + 31,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 33,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { + 34,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { + 35,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 36,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, + pA500,pD500 + }, + { + 936,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 39,pL001,pA010,pA100,pD151,pA200,pD201,pD151,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 41,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 42,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 44,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, + pA500,pD500 + }, + { + 45,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 47,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 48,pL001,pA010,pA100,pD154,pA200,pD201,pD154,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 49,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { + 50,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 52,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { + 53,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 55,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 56,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 59,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 61,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 62,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 64,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD551 + }, + { + 71,pL001,pA010,pA100,pD155,pA200,pD201,pD155,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 72,pL001,pA010,pA100,pD104,pA200,pD201,pD104,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 73,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 74,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 76,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { + 77,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,pA400,pD400, + pA500,pD501 + }, + { + 777,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 877,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 977,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 87,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 88,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { + 95,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 96,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 97,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 98,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD551 + }, + { + 100,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 105,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 106,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 112,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } }; @@ -253,28 +306,30 @@ struct GPS_MODEL_PROTOCOL GPS_MP[]= ** ** @return [void] ************************************************************************/ - + US GPS_Protocol_Version_Change(US id, US version) { - if(id==29) - if(version>=400) - id = 929; - - if(id==36) - if(version>=300) - id = 936; - - if(id==77) - { - if(version>=301 && version<350) - id = 777; - else if(version>=350 && version<361) - id = 877; - else if(version>=361) - id = 977; + if (id==29) + if (version>=400) { + id = 929; + } + + if (id==36) + if (version>=300) { + id = 936; + } + + if (id==77) { + if (version>=301 && version<350) { + id = 777; + } else if (version>=350 && version<361) { + id = 877; + } else if (version>=361) { + id = 977; } + } - return id; + return id; } @@ -291,38 +346,36 @@ US GPS_Protocol_Version_Change(US id, US version) int32 GPS_Protocol_Table_Set(US id) { - int32 i; - US v; - char s[GPS_ARB_LEN]; - - i=0; - while((v=GPS_MP[i].id)) - { - if(v==id) - { - gps_link_type = GPS_MP[i].link; - gps_device_command = GPS_MP[i].command-10; - gps_waypt_transfer = GPS_MP[i].wayptt; - gps_waypt_type = GPS_MP[i].wayptd; - gps_route_transfer = GPS_MP[i].rtea; - gps_rte_hdr_type = GPS_MP[i].rted0; - gps_rte_type = GPS_MP[i].rted1; - gps_trk_transfer = GPS_MP[i].trka; - gps_trk_type = GPS_MP[i].trkd; - gps_prx_waypt_transfer = GPS_MP[i].prxa; - gps_prx_waypt_type = GPS_MP[i].prxd; - gps_almanac_transfer = GPS_MP[i].alma; - gps_almanac_type = GPS_MP[i].almd; - return 1; - } - ++i; + int32 i; + US v; + char s[GPS_ARB_LEN]; + + i=0; + while ((v=GPS_MP[i].id)) { + if (v==id) { + gps_link_type = GPS_MP[i].link; + gps_device_command = GPS_MP[i].command-10; + gps_waypt_transfer = GPS_MP[i].wayptt; + gps_waypt_type = GPS_MP[i].wayptd; + gps_route_transfer = GPS_MP[i].rtea; + gps_rte_hdr_type = GPS_MP[i].rted0; + gps_rte_type = GPS_MP[i].rted1; + gps_trk_transfer = GPS_MP[i].trka; + gps_trk_type = GPS_MP[i].trkd; + gps_prx_waypt_transfer = GPS_MP[i].prxa; + gps_prx_waypt_type = GPS_MP[i].prxd; + gps_almanac_transfer = GPS_MP[i].alma; + gps_almanac_type = GPS_MP[i].almd; + return 1; } + ++i; + } - (void)sprintf(s,"INIT: No table entry for ID %d\n",id); - GPS_Error(s); + (void)sprintf(s,"INIT: No table entry for ID %d\n",id); + GPS_Error(s); - return GPS_UNSUPPORTED; + return GPS_UNSUPPORTED; } @@ -336,21 +389,20 @@ int32 GPS_Protocol_Table_Set(US id) ** ** @return [void] ************************************************************************/ - + void GPS_Protocol_Error(US tag, US data) { - char s[GPS_ARB_LEN]; + char s[GPS_ARB_LEN]; - (void) sprintf(s,"PROTOCOL ERROR: Unknown tag/data [%c/%d]\n",tag,data); - GPS_Error(s); + (void) sprintf(s,"PROTOCOL ERROR: Unknown tag/data [%c/%d]\n",tag,data); + GPS_Error(s); - if(gps_n_tag_unknown < GPS_TAGUNK) - { - gps_tag_unknown[gps_n_tag_unknown] = tag; - gps_tag_data_unknown[gps_n_tag_unknown++] = data; - } - - return; + if (gps_n_tag_unknown < GPS_TAGUNK) { + gps_tag_unknown[gps_n_tag_unknown] = tag; + gps_tag_data_unknown[gps_n_tag_unknown++] = data; + } + + return; } @@ -362,18 +414,19 @@ void GPS_Protocol_Error(US tag, US data) ** ** @return [void] ************************************************************************/ - + void GPS_Unknown_Protocol_Print(void) { - int32 i; + int32 i; - (void) fprintf(stdout,"\nUnknown protocols: "); - if(!gps_n_tag_unknown) - (void) fprintf(stdout,"None"); - (void) fprintf(stdout,"\n"); + (void) fprintf(stdout,"\nUnknown protocols: "); + if (!gps_n_tag_unknown) { + (void) fprintf(stdout,"None"); + } + (void) fprintf(stdout,"\n"); - for(i=0; idata; - - start = GPS_Time_Now(); - GPS_Diag("Rx Data:"); - while(GPS_Time_Now() < start+GPS_TIME_OUT) - { - if((n=GPS_Serial_Chars_Ready(fd))) - { - if(GPS_Serial_Read(fd,&u,1)==-1) - { - perror("read"); - GPS_Error("GPS_Packet_Read: Read error"); - gps_errno = FRAMING_ERROR; - return 0; - } - - GPS_Diag("%02x ", u); - - if(!len) - { - if(u != DLE) - { - (void) fprintf(stderr,"GPS_Packet_Read: No DLE. Data received, but probably not a garmin packet.\n"); - (void) fflush(stderr); - return 0; - } - ++len; - continue; - } - - if(len==1) - { - (*packet)->type = u; - ++len; - continue; - } - - if(u == DLE) - { - if(isDLE) - { - isDLE = gpsFalse; - continue; - } - isDLE = gpsTrue; - } - - if(len == 2) - { - (*packet)->n = u; - len = -1; - continue; - } - - if(u == ETX) - if(isDLE) - { - if(p-(*packet)->data-2 != (*packet)->n) - { - GPS_Error("GPS_Packet_Read: Bad count"); - gps_errno = FRAMING_ERROR; - return 0; - } - chk_read = *(p-2); - - for(i=0,p=(*packet)->data;i<(*packet)->n;++i) - chk -= *p++; - chk -= (*packet)->type; - chk -= (*packet)->n; - if(chk != chk_read) - { - GPS_Error("CHECKSUM: Read error\n"); - gps_errno = FRAMING_ERROR; - return 0; - } - - m1 = Get_Pkt_Type((*packet)->type, (*packet)->data[0], &m2); - if (gps_show_bytes) { - GPS_Diag(" "); - for (i = 0; i < (*packet)->n; i++) { - char c = (*packet)->data[i]; - GPS_Diag("%c", isalnum(c) ? c : '.'); - } - GPS_Diag(" "); - } - GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); - return (*packet)->n; - } - - if (p - (*packet)->data >= MAX_GPS_PACKET_SIZE) - { - GPS_Error("GPS_Serial_Packet_Read: Bad payload size/no ETX found"); - gps_errno = FRAMING_ERROR; - return 0; - } - *p++ = u; - } + time_t start; + int32 n; + int32 len; + UC u; + int32 isDLE; + UC* p; + int32 i; + UC chk=0, chk_read; + const char* m1; + const char* m2; + + len = 0; + isDLE = gpsFalse; + p = (*packet)->data; + + start = GPS_Time_Now(); + GPS_Diag("Rx Data:"); + while (GPS_Time_Now() < start+GPS_TIME_OUT) { + if ((n=GPS_Serial_Chars_Ready(fd))) { + if (GPS_Serial_Read(fd,&u,1)==-1) { + perror("read"); + GPS_Error("GPS_Packet_Read: Read error"); + gps_errno = FRAMING_ERROR; + return 0; + } + + GPS_Diag("%02x ", u); + + if (!len) { + if (u != DLE) { + (void) fprintf(stderr,"GPS_Packet_Read: No DLE. Data received, but probably not a garmin packet.\n"); + (void) fflush(stderr); + return 0; + } + ++len; + continue; + } + + if (len==1) { + (*packet)->type = u; + ++len; + continue; + } + + if (u == DLE) { + if (isDLE) { + isDLE = gpsFalse; + continue; + } + isDLE = gpsTrue; + } + + if (len == 2) { + (*packet)->n = u; + len = -1; + continue; + } + + if (u == ETX) + if (isDLE) { + if (p-(*packet)->data-2 != (*packet)->n) { + GPS_Error("GPS_Packet_Read: Bad count"); + gps_errno = FRAMING_ERROR; + return 0; + } + chk_read = *(p-2); + + for (i=0,p=(*packet)->data; i<(*packet)->n; ++i) { + chk -= *p++; + } + chk -= (*packet)->type; + chk -= (*packet)->n; + if (chk != chk_read) { + GPS_Error("CHECKSUM: Read error\n"); + gps_errno = FRAMING_ERROR; + return 0; + } + + m1 = Get_Pkt_Type((*packet)->type, (*packet)->data[0], &m2); + if (gps_show_bytes) { + GPS_Diag(" "); + for (i = 0; i < (*packet)->n; i++) { + char c = (*packet)->data[i]; + GPS_Diag("%c", isalnum(c) ? c : '.'); + } + GPS_Diag(" "); + } + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + return (*packet)->n; + } + + if (p - (*packet)->data >= MAX_GPS_PACKET_SIZE) { + GPS_Error("GPS_Serial_Packet_Read: Bad payload size/no ETX found"); + gps_errno = FRAMING_ERROR; + return 0; + } + *p++ = u; } - - - GPS_Error("GPS_Packet_Read: Timeout. No data received."); - gps_errno = SERIAL_ERROR; + } - return 0; + + GPS_Error("GPS_Packet_Read: Timeout. No data received."); + gps_errno = SERIAL_ERROR; + + return 0; } @@ -202,22 +189,21 @@ int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet) ** @return [int32] true if ACK **********************************************************************/ -int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec) +int32 GPS_Serial_Get_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec) { - if(!GPS_Serial_Packet_Read(fd, rec)) - return 0; + if (!GPS_Serial_Packet_Read(fd, rec)) { + return 0; + } - if(LINK_ID[0].Pid_Ack_Byte != (*rec)->type) - { - gps_error = FRAMING_ERROR; -/* rjl return 0; */ - } - - if(*(*rec)->data != (*tra)->type) - { - gps_error = FRAMING_ERROR; - return 0; - } + if (LINK_ID[0].Pid_Ack_Byte != (*rec)->type) { + gps_error = FRAMING_ERROR; + /* rjl return 0; */ + } + + if (*(*rec)->data != (*tra)->type) { + gps_error = FRAMING_ERROR; + return 0; + } - return 1; + return 1; } diff --git a/gpsbabel/jeeps/gpsread.h b/gpsbabel/jeeps/gpsread.h index 17f3bd852..c9d280a1e 100644 --- a/gpsbabel/jeeps/gpsread.h +++ b/gpsbabel/jeeps/gpsread.h @@ -9,9 +9,9 @@ extern "C" #include "gps.h" -time_t GPS_Time_Now(void); -int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); -int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + time_t GPS_Time_Now(void); + int32 GPS_Serial_Packet_Read(gpsdevh* fd, GPS_PPacket* packet); + int32 GPS_Serial_Get_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec); #endif diff --git a/gpsbabel/jeeps/gpsrqst.c b/gpsbabel/jeeps/gpsrqst.c index 7203313c6..d65ce05e3 100644 --- a/gpsbabel/jeeps/gpsrqst.c +++ b/gpsbabel/jeeps/gpsrqst.c @@ -2,21 +2,21 @@ ** @source JEEPS time/position request from GPS functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @modified Copyright (C) 2006 Robert Lipe ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -25,8 +25,8 @@ #include "gps.h" -static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time); -static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon); +static int32 GPS_A600_Rqst(gpsdevh* fd, time_t Time); +static int32 GPS_A700_Rqst(gpsdevh* fd, double lat, double lon); @@ -40,22 +40,21 @@ static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon); ** @return [int32] true if OK ************************************************************************/ -int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time) +int32 GPS_Rqst_Send_Time(gpsdevh* fd, time_t Time) { - time_t ret=0; - - switch(gps_date_time_transfer) - { - case pA600: - ret = GPS_A600_Rqst(fd, Time); - break; - default: - GPS_Error("Rqst_Send_Time: Unknown date/time protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + time_t ret=0; + + switch (gps_date_time_transfer) { + case pA600: + ret = GPS_A600_Rqst(fd, Time); + break; + default: + GPS_Error("Rqst_Send_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -68,34 +67,36 @@ int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time) ** ** @return [int32] success ************************************************************************/ -static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time) +static int32 GPS_A600_Rqst(gpsdevh* fd, time_t Time) { - GPS_PPacket tra; - GPS_PPacket rec; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - switch(gps_date_time_type) - { - case pD600: - GPS_D600_Send(&tra,Time); - break; - default: - GPS_Error("A600_Rqst: Unknown data/time protocol"); - return PROTOCOL_ERROR; - } - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - - return 1; + GPS_PPacket tra; + GPS_PPacket rec; + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + + switch (gps_date_time_type) { + case pD600: + GPS_D600_Send(&tra,Time); + break; + default: + GPS_Error("A600_Rqst: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + return 1; } @@ -111,22 +112,21 @@ static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time) ** @return [int32] success ************************************************************************/ -int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon) +int32 GPS_Rqst_Send_Position(gpsdevh* fd, double lat, double lon) { - int32 ret=0; - - switch(gps_position_transfer) - { - case pA700: - ret = GPS_A700_Rqst(fd, lat, lon); - break; - default: - GPS_Error("Rqst_Send_Position: Unknown position protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + switch (gps_position_transfer) { + case pA700: + ret = GPS_A700_Rqst(fd, lat, lon); + break; + default: + GPS_Error("Rqst_Send_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -140,37 +140,39 @@ int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon) ** ** @return [int32] success ************************************************************************/ -static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon) +static int32 GPS_A700_Rqst(gpsdevh* fd, double lat, double lon) { - GPS_PPacket tra; - GPS_PPacket rec; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - switch(gps_position_type) - { - case pD700: - GPS_D700_Send(&tra,lat,lon); - break; - default: - GPS_Error("A700_Rqst: Unknown position protocol"); - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - return PROTOCOL_ERROR; - } - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - + GPS_PPacket tra; + GPS_PPacket rec; + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + switch (gps_position_type) { + case pD700: + GPS_D700_Send(&tra,lat,lon); + break; + default: + GPS_Error("A700_Rqst: Unknown position protocol"); GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); + return PROTOCOL_ERROR; + } + + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - return 1; + return 1; } diff --git a/gpsbabel/jeeps/gpsrqst.h b/gpsbabel/jeeps/gpsrqst.h index ec0169586..0afd29f58 100644 --- a/gpsbabel/jeeps/gpsrqst.h +++ b/gpsbabel/jeeps/gpsrqst.h @@ -9,8 +9,8 @@ extern "C" #include "gps.h" -int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time); -int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon); + int32 GPS_Rqst_Send_Time(gpsdevh* fd, time_t Time); + int32 GPS_Rqst_Send_Position(gpsdevh* fd, double lat, double lon); #endif diff --git a/gpsbabel/jeeps/gpssend.c b/gpsbabel/jeeps/gpssend.c index 80801a0c7..cd5d68a47 100644 --- a/gpsbabel/jeeps/gpssend.c +++ b/gpsbabel/jeeps/gpssend.c @@ -2,21 +2,21 @@ ** @source JEEPS packet construction, sending and ack functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @modified Copyright (C) 2006 Robert Lipe ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -42,79 +42,75 @@ static US Build_Serial_Packet(GPS_PPacket in, GPS_Serial_PPacket out) { - UC *p; - UC *q; - - int32 i; - UC chk=0; - US bytes=0; - - p = in->data; - q = out->data; - - out->dle = DLE; - out->edle = DLE; - out->etx = ETX; - out->n = in->n; - out->type = in->type; - - chk -= in->type; - - if(in->n == DLE) - { - ++bytes; - *q++ = DLE; - } - - chk -= in->n; - - for(i = 0; i < in->n; ++i) - { - if(*p == DLE) - { - ++bytes; - *q++ = DLE; - } - chk -= *p; - *q++ = *p++; - ++bytes; - } + UC* p; + UC* q; + + int32 i; + UC chk=0; + US bytes=0; + + p = in->data; + q = out->data; + + out->dle = DLE; + out->edle = DLE; + out->etx = ETX; + out->n = in->n; + out->type = in->type; - if(chk == DLE) - { - *q++ = DLE; - ++bytes; + chk -= in->type; + + if (in->n == DLE) { + ++bytes; + *q++ = DLE; + } + + chk -= in->n; + + for (i = 0; i < in->n; ++i) { + if (*p == DLE) { + ++bytes; + *q++ = DLE; } - - out->chk = chk; - - return bytes; + chk -= *p; + *q++ = *p++; + ++bytes; + } + + if (chk == DLE) { + *q++ = DLE; + ++bytes; + } + + out->chk = chk; + + return bytes; } void -Diag(void *buf, size_t sz) +Diag(void* buf, size_t sz) { - unsigned char *cbuf = (unsigned char *) buf; - while (sz--) { - GPS_Diag("%02x ", *cbuf++); - } + unsigned char* cbuf = (unsigned char*) buf; + while (sz--) { + GPS_Diag("%02x ", *cbuf++); + } } -void -DiagS(void *buf, size_t sz) +void +DiagS(void* buf, size_t sz) { - unsigned char *cbuf = (unsigned char *) buf; + unsigned char* cbuf = (unsigned char*) buf; - while (sz--) { - unsigned char c = *cbuf++; - GPS_Diag("%c", isalnum(c) ? c : '.'); - } + while (sz--) { + unsigned char c = *cbuf++; + GPS_Diag("%c", isalnum(c) ? c : '.'); + } } /* @func GPS_Write_Packet *********************************************** ** -** Forms a complete packet to send +** Forms a complete packet to send ** ** @param [w] fd [int32] file descriptor ** @param [r] packet [GPS_PPacket] packet @@ -122,72 +118,66 @@ DiagS(void *buf, size_t sz) ** @return [int32] number of bytes in the packet ************************************************************************/ -int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet) +int32 GPS_Serial_Write_Packet(gpsdevh* fd, GPS_PPacket packet) { - size_t ret; - const char *m1, *m2; - GPS_Serial_OPacket ser_pkt; - UC ser_pkt_data[MAX_GPS_PACKET_SIZE * sizeof(UC)]; - US bytes; - - if (packet->type >= 0xff || packet->n >= 0xff) { - GPS_Error("SEND: Unsupported packet type/size for serial protocol"); - return 0; - } - - ser_pkt.data = ser_pkt_data; - bytes = Build_Serial_Packet(packet, &ser_pkt); - - GPS_Diag("Tx Data:"); - Diag(&ser_pkt.dle, 3); - if((ret=GPS_Serial_Write(fd,(const void *) &ser_pkt.dle,(size_t)3)) == -1) - { - perror("write"); - GPS_Error("SEND: Write to GPS failed"); - return 0; - } - if(ret!=3) - { - GPS_Error("SEND: Incomplete write to GPS"); - return 0; - } - - Diag(ser_pkt.data, bytes); - if((ret=GPS_Serial_Write(fd,(const void *)ser_pkt.data,(size_t)bytes)) == -1) - { - perror("write"); - GPS_Error("SEND: Write to GPS failed"); - return 0; - } - if(ret!=bytes) - { - GPS_Error("SEND: Incomplete write to GPS"); - return 0; - } - - - Diag(&ser_pkt.chk, 3); - - GPS_Diag(": "); - DiagS(ser_pkt.data, bytes); - DiagS(&ser_pkt.chk, 3); - m1 = Get_Pkt_Type(ser_pkt.type, ser_pkt.data[0], &m2); - GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); - - if((ret=GPS_Serial_Write(fd,(const void *)&ser_pkt.chk,(size_t)3)) == -1) - { - perror("write"); - GPS_Error("SEND: Write to GPS failed"); - return 0; - } - if(ret!=3) - { - GPS_Error("SEND: Incomplete write to GPS"); - return 0; - } - - - return 1; + size_t ret; + const char* m1, *m2; + GPS_Serial_OPacket ser_pkt; + UC ser_pkt_data[MAX_GPS_PACKET_SIZE * sizeof(UC)]; + US bytes; + + if (packet->type >= 0xff || packet->n >= 0xff) { + GPS_Error("SEND: Unsupported packet type/size for serial protocol"); + return 0; + } + + ser_pkt.data = ser_pkt_data; + bytes = Build_Serial_Packet(packet, &ser_pkt); + + GPS_Diag("Tx Data:"); + Diag(&ser_pkt.dle, 3); + if ((ret=GPS_Serial_Write(fd,(const void*) &ser_pkt.dle,(size_t)3)) == -1) { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if (ret!=3) { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + Diag(ser_pkt.data, bytes); + if ((ret=GPS_Serial_Write(fd,(const void*)ser_pkt.data,(size_t)bytes)) == -1) { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if (ret!=bytes) { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + + Diag(&ser_pkt.chk, 3); + + GPS_Diag(": "); + DiagS(ser_pkt.data, bytes); + DiagS(&ser_pkt.chk, 3); + m1 = Get_Pkt_Type(ser_pkt.type, ser_pkt.data[0], &m2); + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + + if ((ret=GPS_Serial_Write(fd,(const void*)&ser_pkt.chk,(size_t)3)) == -1) { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if (ret!=3) { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + + return 1; } @@ -202,18 +192,17 @@ int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet) ** @return [int32] success ************************************************************************/ -int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec) +int32 GPS_Serial_Send_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec) { - UC data[2]; - - GPS_Util_Put_Short(data,(US)(*rec)->type); - GPS_Make_Packet(tra,LINK_ID[0].Pid_Ack_Byte,data,2); - if(!GPS_Write_Packet(fd,*tra)) - { - GPS_Error("Error acknowledging packet"); - gps_errno = SERIAL_ERROR; - return 0; - } + UC data[2]; + + GPS_Util_Put_Short(data,(US)(*rec)->type); + GPS_Make_Packet(tra,LINK_ID[0].Pid_Ack_Byte,data,2); + if (!GPS_Write_Packet(fd,*tra)) { + GPS_Error("Error acknowledging packet"); + gps_errno = SERIAL_ERROR; + return 0; + } - return 1; + return 1; } diff --git a/gpsbabel/jeeps/gpssend.h b/gpsbabel/jeeps/gpssend.h index 2b6fc9115..68b480291 100644 --- a/gpsbabel/jeeps/gpssend.h +++ b/gpsbabel/jeeps/gpssend.h @@ -11,10 +11,10 @@ extern "C" #define GPS_ARB_LEN 1024 -int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); -int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + int32 GPS_Serial_Write_Packet(gpsdevh* fd, GPS_PPacket packet); + int32 GPS_Serial_Send_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec); -void GPS_Make_Packet(GPS_PPacket *packet, US type, UC *data, uint32 n); + void GPS_Make_Packet(GPS_PPacket* packet, US type, UC* data, uint32 n); #endif diff --git a/gpsbabel/jeeps/gpsserial.c b/gpsbabel/jeeps/gpsserial.c index 29ae1ede1..8afd4eb09 100644 --- a/gpsbabel/jeeps/gpsserial.c +++ b/gpsbabel/jeeps/gpsserial.c @@ -7,17 +7,17 @@ ** @modified June 29th 2000 Alan Bleasby. NMEA additions ** @modified Copyright (C) 2006 Robert Lipe ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -35,24 +35,24 @@ #if 0 #define GARMULATOR 1 -char *rxdata[] = { - "10 06 02 fe 00 fa 10 03", - "10 ff 7d 97 00 0e 01 53 74 72 65 65 74 50 69 6c 6f 74 20 33 20 53 6f 66 74 77 61 72 65 20 56 65 72 73 69 6f 6e 20 32 2e 37 30 00 56 45 52 42 4d 41 50 20 41 6d 65 72 69 63 61 73 20 41 75 74 6f 72 6f 75 74 65 20 31 2e 30 30 00 56 45 52 41 55 44 20 45 6e 67 6c 69 73 68 20 33 2e 30 31 00 56 45 52 53 50 4c 53 43 52 4e 20 53 70 6c 61 73 68 20 53 63 72 65 65 6e 20 4d 69 73 73 69 6e 67 00 f1 10 03", - "10 f8 0e 56 45 52 53 4d 41 50 31 20 4e 6f 6e 65 00 fb 10 03", - - /* Guessing from here down */ - "10 06 02 fe 00 fa 10 03", /* Ack the unknown packet */ - "10 fd 24 50 00 00 4c 01 00 41 0a 00 41 64 00 44 6d 00 41 c9 00 44 ca 00 44 6d 00 44 d2 00 41 2d 01 44 36 01 44 2d 01 66 10 03", /* PTR Array */ - "10 06 02 0a 00 ee 10 03", /* Ack */ - "10 0e 08 06 04 d4 07 00 17 3a 30 84 10 03", /* DATTIME */ - "10 06 02 0a 00 ee 10 03", /* Ack */ - "10 1b 02 09 00 da 10 03", /* RECORD */ - "10 06 02 0a 00 ee 10 03", /* Ack */ - "10 23 5f 01 00 ff 70 3f 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a6 1b aa 19 6e 78 5c c2 00 00 00 00 51 59 04 69 00 00 00 00 00 00 00 00 ff ff ff ff 47 43 31 41 33 37 00 54 68 65 20 54 72 6f 6c 6c 20 62 79 20 61 31 38 32 70 69 6c 6f 74 20 26 20 46 61 6d 69 6c 79 00 00 00 00 00 59 10 03" - "10 0c 02 07 00 eb 10 03" /* XFERCMP */ +char* rxdata[] = { + "10 06 02 fe 00 fa 10 03", + "10 ff 7d 97 00 0e 01 53 74 72 65 65 74 50 69 6c 6f 74 20 33 20 53 6f 66 74 77 61 72 65 20 56 65 72 73 69 6f 6e 20 32 2e 37 30 00 56 45 52 42 4d 41 50 20 41 6d 65 72 69 63 61 73 20 41 75 74 6f 72 6f 75 74 65 20 31 2e 30 30 00 56 45 52 41 55 44 20 45 6e 67 6c 69 73 68 20 33 2e 30 31 00 56 45 52 53 50 4c 53 43 52 4e 20 53 70 6c 61 73 68 20 53 63 72 65 65 6e 20 4d 69 73 73 69 6e 67 00 f1 10 03", + "10 f8 0e 56 45 52 53 4d 41 50 31 20 4e 6f 6e 65 00 fb 10 03", + + /* Guessing from here down */ + "10 06 02 fe 00 fa 10 03", /* Ack the unknown packet */ + "10 fd 24 50 00 00 4c 01 00 41 0a 00 41 64 00 44 6d 00 41 c9 00 44 ca 00 44 6d 00 44 d2 00 41 2d 01 44 36 01 44 2d 01 66 10 03", /* PTR Array */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 0e 08 06 04 d4 07 00 17 3a 30 84 10 03", /* DATTIME */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 1b 02 09 00 da 10 03", /* RECORD */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 23 5f 01 00 ff 70 3f 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a6 1b aa 19 6e 78 5c c2 00 00 00 00 51 59 04 69 00 00 00 00 00 00 00 00 ff ff ff ff 47 43 31 41 33 37 00 54 68 65 20 54 72 6f 6c 6c 20 62 79 20 61 31 38 32 70 69 6c 6f 74 20 26 20 46 61 6d 69 6c 79 00 00 00 00 00 59 10 03" + "10 0c 02 07 00 eb 10 03" /* XFERCMP */ }; #endif -/* +/* * termio on Cygwin is apparently broken, so we revert to Windows serial. */ #if defined (__WIN32__) || defined (__CYGWIN__) @@ -60,166 +60,166 @@ char *rxdata[] = { #include typedef struct { - HANDLE comport; + HANDLE comport; } win_serial_data; /* * Display an error from the serial subsystem. */ -void GPS_Serial_Error(const char *mb, ...) +void GPS_Serial_Error(const char* mb, ...) { - va_list ap; - char msg[200]; - char *s; - int b; - - va_start(ap, mb); - b = vsnprintf(msg, sizeof(msg), mb, ap); - s = msg + b; - *s++ = ':'; - *s++ = ' '; - - FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, - GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); - GPS_Error(msg); + va_list ap; + char msg[200]; + char* s; + int b; + + va_start(ap, mb); + b = vsnprintf(msg, sizeof(msg), mb, ap); + s = msg + b; + *s++ = ':'; + *s++ = ' '; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, + GetLastError(), 0, s, sizeof(msg) - b - 2, 0); + GPS_Error(msg); } -int32 GPS_Serial_On(const char *port, gpsdevh **dh) +int32 GPS_Serial_On(const char* port, gpsdevh** dh) { - DCB tio; - COMMTIMEOUTS timeout; - HANDLE comport; - const char *xname = fix_win_serial_name(port); - win_serial_data *wsd = xcalloc(sizeof (win_serial_data), 1); - *dh = (gpsdevh*) wsd; - GPS_Diag("Opening %s\n", xname); - comport = CreateFileA(xname, GENERIC_READ|GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, 0, NULL); - - if (comport == INVALID_HANDLE_VALUE) { - GPS_Serial_Error("CreateFile on '%s' failed", xname); - gps_errno = SERIAL_ERROR; - return 0; - } - - tio.DCBlength = sizeof(DCB); - GetCommState (comport, &tio); - tio.BaudRate = CBR_9600; - tio.fBinary = TRUE; - tio.fParity = TRUE; - tio.fOutxCtsFlow = FALSE; - tio.fOutxDsrFlow = FALSE; - tio.fDtrControl = DTR_CONTROL_ENABLE; - tio.fDsrSensitivity = FALSE; - tio.fTXContinueOnXoff = TRUE; - tio.fOutX = FALSE; - tio.fInX = FALSE; - tio.fErrorChar = FALSE; - tio.fNull = FALSE; - tio.fRtsControl = RTS_CONTROL_ENABLE; - tio.fAbortOnError = FALSE; - tio.ByteSize = 8; - tio.Parity = NOPARITY; - tio.StopBits = ONESTOPBIT; - - if (!SetCommState (comport, &tio)) { - GPS_Serial_Error("SetCommState on port '%s' failed", port); - CloseHandle(comport); - comport = INVALID_HANDLE_VALUE; - gps_errno = SERIAL_ERROR; - return 0; - } - - /* - * The timeouts are kind of fictional as we always end up doing - * single byte reads. At 9600bps (the default) the individual - * character time is 104Millisecs, so these are mostly "dead-man" - * (i.e. cable unplugged, unit not turned on) values. - */ - GetCommTimeouts (comport, &timeout); - - timeout.ReadIntervalTimeout = 1000; /*like vtime. In MS. */ - timeout.ReadTotalTimeoutMultiplier = 1000; - timeout.ReadTotalTimeoutConstant = 1000; - timeout.WriteTotalTimeoutMultiplier = 1000; - timeout.WriteTotalTimeoutConstant = 1000; - if (!SetCommTimeouts (comport, &timeout)) { - GPS_Serial_Error("SetCommTimeouts"); - CloseHandle (comport); - comport = INVALID_HANDLE_VALUE; - gps_errno = SERIAL_ERROR; - return 0; - } - wsd->comport = comport; - return 1; + DCB tio; + COMMTIMEOUTS timeout; + HANDLE comport; + const char* xname = fix_win_serial_name(port); + win_serial_data* wsd = xcalloc(sizeof(win_serial_data), 1); + *dh = (gpsdevh*) wsd; + GPS_Diag("Opening %s\n", xname); + comport = CreateFileA(xname, GENERIC_READ|GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, 0, NULL); + + if (comport == INVALID_HANDLE_VALUE) { + GPS_Serial_Error("CreateFile on '%s' failed", xname); + gps_errno = SERIAL_ERROR; + return 0; + } + + tio.DCBlength = sizeof(DCB); + GetCommState(comport, &tio); + tio.BaudRate = CBR_9600; + tio.fBinary = TRUE; + tio.fParity = TRUE; + tio.fOutxCtsFlow = FALSE; + tio.fOutxDsrFlow = FALSE; + tio.fDtrControl = DTR_CONTROL_ENABLE; + tio.fDsrSensitivity = FALSE; + tio.fTXContinueOnXoff = TRUE; + tio.fOutX = FALSE; + tio.fInX = FALSE; + tio.fErrorChar = FALSE; + tio.fNull = FALSE; + tio.fRtsControl = RTS_CONTROL_ENABLE; + tio.fAbortOnError = FALSE; + tio.ByteSize = 8; + tio.Parity = NOPARITY; + tio.StopBits = ONESTOPBIT; + + if (!SetCommState(comport, &tio)) { + GPS_Serial_Error("SetCommState on port '%s' failed", port); + CloseHandle(comport); + comport = INVALID_HANDLE_VALUE; + gps_errno = SERIAL_ERROR; + return 0; + } + + /* + * The timeouts are kind of fictional as we always end up doing + * single byte reads. At 9600bps (the default) the individual + * character time is 104Millisecs, so these are mostly "dead-man" + * (i.e. cable unplugged, unit not turned on) values. + */ + GetCommTimeouts(comport, &timeout); + + timeout.ReadIntervalTimeout = 1000; /*like vtime. In MS. */ + timeout.ReadTotalTimeoutMultiplier = 1000; + timeout.ReadTotalTimeoutConstant = 1000; + timeout.WriteTotalTimeoutMultiplier = 1000; + timeout.WriteTotalTimeoutConstant = 1000; + if (!SetCommTimeouts(comport, &timeout)) { + GPS_Serial_Error("SetCommTimeouts"); + CloseHandle(comport); + comport = INVALID_HANDLE_VALUE; + gps_errno = SERIAL_ERROR; + return 0; + } + wsd->comport = comport; + return 1; } -int32 GPS_Serial_Off(gpsdevh *dh) +int32 GPS_Serial_Off(gpsdevh* dh) { - win_serial_data *wsd = (win_serial_data*)dh; - CloseHandle(wsd->comport); - wsd->comport = INVALID_HANDLE_VALUE; - xfree(wsd); - return 1; + win_serial_data* wsd = (win_serial_data*)dh; + CloseHandle(wsd->comport); + wsd->comport = INVALID_HANDLE_VALUE; + xfree(wsd); + return 1; } -int32 GPS_Serial_Chars_Ready(gpsdevh *dh) +int32 GPS_Serial_Chars_Ready(gpsdevh* dh) { - COMSTAT lpStat; - DWORD lpErrors; - win_serial_data *wsd = (win_serial_data*)dh; + COMSTAT lpStat; + DWORD lpErrors; + win_serial_data* wsd = (win_serial_data*)dh; - ClearCommError(wsd->comport, &lpErrors, &lpStat); - return (lpStat.cbInQue > 0); + ClearCommError(wsd->comport, &lpErrors, &lpStat); + return (lpStat.cbInQue > 0); } -int32 GPS_Serial_Wait(gpsdevh *fd) +int32 GPS_Serial_Wait(gpsdevh* fd) { - /* Wait a short time before testing if data is ready. - * The GPS II, in particular, has a noticable time responding - * with a response to the device inquiry and if we give up on this - * too soon, we fail to read the response to the A001 packet and - * blow our state machines when it starts streaming the capabiilties - * response packet. - */ - Sleep(usecDELAY / 1000); - return GPS_Serial_Chars_Ready(fd); + /* Wait a short time before testing if data is ready. + * The GPS II, in particular, has a noticable time responding + * with a response to the device inquiry and if we give up on this + * too soon, we fail to read the response to the A001 packet and + * blow our state machines when it starts streaming the capabiilties + * response packet. + */ + Sleep(usecDELAY / 1000); + return GPS_Serial_Chars_Ready(fd); } -int32 GPS_Serial_Flush(gpsdevh *fd) +int32 GPS_Serial_Flush(gpsdevh* fd) { - return 1; + return 1; } -int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) +int32 GPS_Serial_Write(gpsdevh* dh, const void* obuf, int size) { - win_serial_data *wsd = (win_serial_data*)dh; - DWORD len; - - /* - * Unbelievably, the Keyspan PDA serial driver 3.2, a "Windows - * Certified driver", will crash the OS on a write of zero bytes. - * We get such writes from upstream when there are zero payload - * bytes. SO we trap those here to stop Keyspan & Windows from - * nuking the system. - */ - if (size == 0) { - return 0; - } - WriteFile (wsd->comport, obuf, size, &len, NULL); - if (len != (DWORD) size) { - fatal ("Write error. Wrote %d of %d bytes.\n", (int)len, size); - } - return len; + win_serial_data* wsd = (win_serial_data*)dh; + DWORD len; + + /* + * Unbelievably, the Keyspan PDA serial driver 3.2, a "Windows + * Certified driver", will crash the OS on a write of zero bytes. + * We get such writes from upstream when there are zero payload + * bytes. SO we trap those here to stop Keyspan & Windows from + * nuking the system. + */ + if (size == 0) { + return 0; + } + WriteFile(wsd->comport, obuf, size, &len, NULL); + if (len != (DWORD) size) { + fatal("Write error. Wrote %d of %d bytes.\n", (int)len, size); + } + return len; } -int32 GPS_Serial_Read(gpsdevh * dh, void *ibuf, int size) +int32 GPS_Serial_Read(gpsdevh* dh, void* ibuf, int size) { - DWORD cnt = 0; - win_serial_data *wsd = (win_serial_data*)dh; + DWORD cnt = 0; + win_serial_data* wsd = (win_serial_data*)dh; - ReadFile(wsd->comport, ibuf, size, &cnt, NULL); - return cnt; + ReadFile(wsd->comport, ibuf, size, &cnt, NULL); + return cnt; } #else @@ -230,8 +230,8 @@ int32 GPS_Serial_Read(gpsdevh * dh, void *ibuf, int size) #include typedef struct { - int fd; /* File descriptor */ - struct termios gps_ttysave; + int fd; /* File descriptor */ + struct termios gps_ttysave; } posix_serial_data; /* @func GPS_Serial_Open *********************************************** @@ -244,107 +244,108 @@ typedef struct { ** @return [int32] false upon error ************************************************************************/ -int32 GPS_Serial_Open(gpsdevh *dh, const char *port) +int32 GPS_Serial_Open(gpsdevh* dh, const char* port) { - struct termios tty; - posix_serial_data *psd = (posix_serial_data *)dh; - - /* - * This originally had O_NDELAY | O_NOCTTY in here, but this - * causes problems with Linux USB ttys (observed on PL2303 and MCT) - * and the rest of the code doesn't _REALLY_ handle the partial - * write/retry case anyway. - robertl - */ - if((psd->fd = open(port, O_RDWR))==-1) - { - GPS_Serial_Error("XSERIAL: Cannot open serial port '%s'", port); - gps_errno = SERIAL_ERROR; - return 0; - } - - if(tcgetattr(psd->fd,&psd->gps_ttysave)==-1) - { - gps_errno = HARDWARE_ERROR; - GPS_Serial_Error("SERIAL: tcgetattr error"); - return 0; - } - tty = psd->gps_ttysave; - - tty.c_cflag &= ~(CSIZE); - tty.c_cflag |= (CREAD | CS8 | CLOCAL); - cfsetospeed(&tty,B9600); - cfsetispeed(&tty,B9600); - - tty.c_lflag &= 0x0; - tty.c_iflag &= 0x0; - tty.c_oflag &= 0x0; - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - - if(tcsetattr(psd->fd,TCSANOW|TCSAFLUSH,&tty)==-1) - { - GPS_Serial_Error("SERIAL: tcsetattr error"); - return 0; - } + struct termios tty; + posix_serial_data* psd = (posix_serial_data*)dh; + + /* + * This originally had O_NDELAY | O_NOCTTY in here, but this + * causes problems with Linux USB ttys (observed on PL2303 and MCT) + * and the rest of the code doesn't _REALLY_ handle the partial + * write/retry case anyway. - robertl + */ + if ((psd->fd = open(port, O_RDWR))==-1) { + GPS_Serial_Error("XSERIAL: Cannot open serial port '%s'", port); + gps_errno = SERIAL_ERROR; + return 0; + } - return 1; + if (tcgetattr(psd->fd,&psd->gps_ttysave)==-1) { + gps_errno = HARDWARE_ERROR; + GPS_Serial_Error("SERIAL: tcgetattr error"); + return 0; + } + tty = psd->gps_ttysave; + + tty.c_cflag &= ~(CSIZE); + tty.c_cflag |= (CREAD | CS8 | CLOCAL); + cfsetospeed(&tty,B9600); + cfsetispeed(&tty,B9600); + + tty.c_lflag &= 0x0; + tty.c_iflag &= 0x0; + tty.c_oflag &= 0x0; + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + + if (tcsetattr(psd->fd,TCSANOW|TCSAFLUSH,&tty)==-1) { + GPS_Serial_Error("SERIAL: tcsetattr error"); + return 0; + } + + return 1; } /* * Display an error from the serial subsystem. */ -void GPS_Serial_Error(const char *mb, ...) +void GPS_Serial_Error(const char* mb, ...) { - va_list ap; - char msg[200]; - char *s; - int b; - - va_start(ap, mb); - b = vsnprintf(msg, sizeof(msg), mb, ap); - s = msg + b; - *s++ = ':'; - *s++ = ' '; - *s++ = '\0'; - -// FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, + va_list ap; + char msg[200]; + char* s; + int b; + + va_start(ap, mb); + b = vsnprintf(msg, sizeof(msg), mb, ap); + s = msg + b; + *s++ = ':'; + *s++ = ' '; + *s++ = '\0'; + +// FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, // GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); - strcat(msg, strerror(errno)); - GPS_Error(msg); + strcat(msg, strerror(errno)); + GPS_Error(msg); } -int32 GPS_Serial_Read(gpsdevh *dh, void *ibuf, int size) +int32 GPS_Serial_Read(gpsdevh* dh, void* ibuf, int size) { - posix_serial_data *psd = (posix_serial_data *)dh; + posix_serial_data* psd = (posix_serial_data*)dh; #if GARMULATOR - static int l; - static char *rp; - char **rxp = &rxdata[l]; - char *hex; - char *rx = *rxp; - char *ib = ibuf; - - if (!rp) rp = rxdata[0]; - - /* Skip over nulls in our pasted strings */ - if (*rp == 0) { - rp = rxdata[++l]; - } - - *ib = strtoul(rp, &rp, 16); - if (*rp) rp++; - fprintf(stderr, "."); - return 1; + static int l; + static char* rp; + char** rxp = &rxdata[l]; + char* hex; + char* rx = *rxp; + char* ib = ibuf; + + if (!rp) { + rp = rxdata[0]; + } + + /* Skip over nulls in our pasted strings */ + if (*rp == 0) { + rp = rxdata[++l]; + } + + *ib = strtoul(rp, &rp, 16); + if (*rp) { + rp++; + } + fprintf(stderr, "."); + return 1; #else - return read(psd->fd, ibuf, size); + return read(psd->fd, ibuf, size); #endif } -int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) +int32 GPS_Serial_Write(gpsdevh* dh, const void* obuf, int size) { - posix_serial_data *psd = (posix_serial_data *)dh; - return write(psd->fd, obuf, size); + posix_serial_data* psd = (posix_serial_data*)dh; + return write(psd->fd, obuf, size); } @@ -356,18 +357,17 @@ int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) ** ** @return [int32] false upon error ************************************************************************/ -int32 GPS_Serial_Flush(gpsdevh *fd) +int32 GPS_Serial_Flush(gpsdevh* fd) { - posix_serial_data *psd = (posix_serial_data *)fd; + posix_serial_data* psd = (posix_serial_data*)fd; - if(tcflush(psd->fd,TCIOFLUSH)) - { - GPS_Serial_Error("SERIAL: tcflush error"); - gps_errno = SERIAL_ERROR; - return 0; - } + if (tcflush(psd->fd,TCIOFLUSH)) { + GPS_Serial_Error("SERIAL: tcflush error"); + gps_errno = SERIAL_ERROR; + return 0; + } - return 1; + return 1; } @@ -382,25 +382,23 @@ int32 GPS_Serial_Flush(gpsdevh *fd) ** @return [int32] false upon error ************************************************************************/ -int32 GPS_Serial_Close(gpsdevh *fd) +int32 GPS_Serial_Close(gpsdevh* fd) { - posix_serial_data *psd = (posix_serial_data *)fd; - - if(tcsetattr(psd->fd, TCSAFLUSH, &psd->gps_ttysave)==-1) - { - gps_errno = HARDWARE_ERROR; - GPS_Serial_Error("SERIAL: tcsetattr error"); - return 0; - } - - if(close(psd->fd)==-1) - { - GPS_Serial_Error("SERIAL: Error closing serial port"); - gps_errno = SERIAL_ERROR; - return 0; - } - - return 1; + posix_serial_data* psd = (posix_serial_data*)fd; + + if (tcsetattr(psd->fd, TCSAFLUSH, &psd->gps_ttysave)==-1) { + gps_errno = HARDWARE_ERROR; + GPS_Serial_Error("SERIAL: tcsetattr error"); + return 0; + } + + if (close(psd->fd)==-1) { + GPS_Serial_Error("SERIAL: Error closing serial port"); + gps_errno = SERIAL_ERROR; + return 0; + } + + return 1; } @@ -413,32 +411,34 @@ int32 GPS_Serial_Close(gpsdevh *fd) ** @return [int32] true if chars waiting ************************************************************************/ -int32 GPS_Serial_Chars_Ready(gpsdevh *dh) +int32 GPS_Serial_Chars_Ready(gpsdevh* dh) { - fd_set rec; - struct timeval t; - posix_serial_data *psd = (posix_serial_data *)dh; - int32 fd = psd->fd; + fd_set rec; + struct timeval t; + posix_serial_data* psd = (posix_serial_data*)dh; + int32 fd = psd->fd; #if GARMULATOR - static foo; - /* Return sporadic reads just to torment the rest of the code. */ - if ((foo++ & 0xf) == 0) - return 1; - else - return 0; + static foo; + /* Return sporadic reads just to torment the rest of the code. */ + if ((foo++ & 0xf) == 0) { + return 1; + } else { + return 0; + } #endif - FD_ZERO(&rec); - FD_SET(fd,&rec); + FD_ZERO(&rec); + FD_SET(fd,&rec); - t.tv_sec = 0; - t.tv_usec = 1000; - (void) select(fd+1,&rec,NULL,NULL,&t); - if(FD_ISSET(fd,&rec)) - return 1; + t.tv_sec = 0; + t.tv_usec = 1000; + (void) select(fd+1,&rec,NULL,NULL,&t); + if (FD_ISSET(fd,&rec)) { + return 1; + } - return 0; + return 0; } @@ -447,30 +447,31 @@ int32 GPS_Serial_Chars_Ready(gpsdevh *dh) ** ** Wait 80 milliseconds before testing for input. The GPS delay ** appears to be around 40-50 milliseconds. Doubling the value is to -** allow some leeway. +** allow some leeway. ** ** @param [r] fd [int32 ] file descriptor ** ** @return [int32] true if serial chars waiting ************************************************************************/ -int32 GPS_Serial_Wait(gpsdevh *dh) +int32 GPS_Serial_Wait(gpsdevh* dh) { - fd_set rec; - struct timeval t; - posix_serial_data *psd = (posix_serial_data *)dh; + fd_set rec; + struct timeval t; + posix_serial_data* psd = (posix_serial_data*)dh; - FD_ZERO(&rec); - FD_SET(psd->fd,&rec); + FD_ZERO(&rec); + FD_SET(psd->fd,&rec); - t.tv_sec = 0; - t.tv_usec = 180000; /* Microseconds before GPS sends A001 */ + t.tv_sec = 0; + t.tv_usec = 180000; /* Microseconds before GPS sends A001 */ - (void) select(psd->fd+1,&rec,NULL,NULL,&t); - if(FD_ISSET(psd->fd,&rec)) - return 1; + (void) select(psd->fd+1,&rec,NULL,NULL,&t); + if (FD_ISSET(psd->fd,&rec)) { + return 1; + } - return 0; + return 0; } @@ -485,19 +486,18 @@ int32 GPS_Serial_Wait(gpsdevh *dh) ** @return [int32] success ************************************************************************/ -int32 GPS_Serial_On(const char *port, gpsdevh **dh) +int32 GPS_Serial_On(const char* port, gpsdevh** dh) { - posix_serial_data *psd = xcalloc(sizeof (posix_serial_data), 1); - *dh = (gpsdevh*) psd; - - if(!GPS_Serial_Open((gpsdevh *) psd,port)) - { - GPS_Error("Cannot open serial port '%s'", port); - gps_errno = SERIAL_ERROR; - return 0; - } + posix_serial_data* psd = (posix_serial_data*) xcalloc(sizeof(posix_serial_data), 1); + *dh = (gpsdevh*) psd; - return 1; + if (!GPS_Serial_Open((gpsdevh*) psd,port)) { + GPS_Error("Cannot open serial port '%s'", port); + gps_errno = SERIAL_ERROR; + return 0; + } + + return 1; } @@ -512,18 +512,17 @@ int32 GPS_Serial_On(const char *port, gpsdevh **dh) ** @return [int32] success ************************************************************************/ -int32 GPS_Serial_Off(gpsdevh *dh) +int32 GPS_Serial_Off(gpsdevh* dh) { - if(!GPS_Serial_Close(dh)) - { - GPS_Error("Error Closing port"); - gps_errno = HARDWARE_ERROR; - return 0; - } - dh = NULL; - - return 1; + if (!GPS_Serial_Close(dh)) { + GPS_Error("Error Closing port"); + gps_errno = HARDWARE_ERROR; + return 0; + } + dh = NULL; + + return 1; } #endif /* __WIN32__ */ diff --git a/gpsbabel/jeeps/gpsserial.h b/gpsbabel/jeeps/gpsserial.h index bf245105e..1ebda4703 100644 --- a/gpsbabel/jeeps/gpsserial.h +++ b/gpsbabel/jeeps/gpsserial.h @@ -11,22 +11,22 @@ extern "C" #define usecDELAY 180000 /* Microseconds before GPS sends A001 */ -int32 GPS_Serial_Chars_Ready(gpsdevh * fd); + int32 GPS_Serial_Chars_Ready(gpsdevh* fd); // int32 GPS_Serial_Close(int32 fd, const char *port); // int32 GPS_Serial_Open(int32 *fd, const char *port); // int32 GPS_Serial_Open_NMEA(int32 *fd, const char *port); // int32 GPS_Serial_Restoretty(const char *port); // int32 GPS_Serial_Savetty(const char *port); -int32 GPS_Serial_On(const char *port, gpsdevh **fd); -int32 GPS_Serial_Off(gpsdevh *fd); -int32 GPS_Serial_Wait(gpsdevh *fd); -int32 GPS_Serial_Flush(gpsdevh *fd); + int32 GPS_Serial_On(const char* port, gpsdevh** fd); + int32 GPS_Serial_Off(gpsdevh* fd); + int32 GPS_Serial_Wait(gpsdevh* fd); + int32 GPS_Serial_Flush(gpsdevh* fd); // int32 GPS_Serial_On_NMEA(const char *port, gpsdevh **fd); -int32 GPS_Serial_Read(gpsdevh *fd, void *ibuf, int size); -int32 GPS_Serial_Write(gpsdevh *fd, const void *obuf, int size); -int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); -int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); -void GPS_Serial_Error(const char *hdr, ...); + int32 GPS_Serial_Read(gpsdevh* fd, void* ibuf, int size); + int32 GPS_Serial_Write(gpsdevh* fd, const void* obuf, int size); + int32 GPS_Serial_Write_Packet(gpsdevh* fd, GPS_PPacket packet); + int32 GPS_Serial_Send_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec); + void GPS_Serial_Error(const char* hdr, ...); #endif diff --git a/gpsbabel/jeeps/gpsusbcommon.c b/gpsbabel/jeeps/gpsusbcommon.c index 26d1264c3..fb3ae7306 100644 --- a/gpsbabel/jeeps/gpsusbcommon.c +++ b/gpsbabel/jeeps/gpsusbcommon.c @@ -30,242 +30,249 @@ */ enum { - rs_fromintr, - rs_frombulk + rs_fromintr, + rs_frombulk } receive_state; -static gusb_llops_t *gusb_llops; +static gusb_llops_t* gusb_llops; /* Decide when to truncate packets for debug output */ #define DEBUG_THRESH ((global_opts.debug_level < 5) && (i > 10)) /* Called from OS layer to register its low-level entry points. */ void -gusb_register_ll(gusb_llops_t *p) +gusb_register_ll(gusb_llops_t* p) { - gusb_llops = p; + gusb_llops = p; } int -gusb_close(gpsdevh *dh) +gusb_close(gpsdevh* dh) { - garmin_usb_packet scratch; + garmin_usb_packet scratch; - memset(&scratch, 0, sizeof(scratch)); + memset(&scratch, 0, sizeof(scratch)); - switch (receive_state) { - case rs_frombulk: - gusb_cmd_get(&scratch, sizeof(scratch)); - break; - default: - break; - } + switch (receive_state) { + case rs_frombulk: + gusb_cmd_get(&scratch, sizeof(scratch)); + break; + default: + break; + } - gusb_llops->llop_close(dh); - return 1; + gusb_llops->llop_close(dh); + return 1; #if BOOGER - garmin_usb_packet scratch = {0}; -abort(); - switch (receive_state) { - case rs_frombulk: - gusb_cmd_get(dh, &scratch, sizeof(scratch)); - break; - } - - return 1; + garmin_usb_packet scratch = {0}; + abort(); + switch (receive_state) { + case rs_frombulk: + gusb_cmd_get(dh, &scratch, sizeof(scratch)); + break; + } + + return 1; #endif } -int -gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz) +int +gusb_cmd_get(garmin_usb_packet* ibuf, size_t sz) { - int rv; - unsigned char *buf = (unsigned char *) &ibuf->dbuf; - int orig_receive_state; - unsigned short pkt_id; + int rv; + unsigned char* buf = (unsigned char*) &ibuf->dbuf; + int orig_receive_state; + unsigned short pkt_id; top: - orig_receive_state = receive_state; - switch (receive_state) { - case rs_fromintr: - rv = gusb_llops->llop_get_intr(ibuf, sz); - break; - case rs_frombulk: - rv = gusb_llops->llop_get_bulk(ibuf, sz); - break; - default: - fatal("Unknown receiver state %d\n", receive_state); - } - - pkt_id = le_read16(&ibuf->gusb_pkt.pkt_id); - if (gps_show_bytes) { - int i; - const char *m1, *m2; - unsigned short pkttype = le_read16(&ibuf->gusb_pkt.databuf[0]); - - GPS_Diag("RX (%s) [%d]:", - receive_state == rs_fromintr ? "intr" : "bulk", rv); - - for(i=0;i 0) && (pkt_id == GUSB_REQUEST_BULK)) { - receive_state = rs_frombulk; - goto top; - } - /* - * If we were reading from the bulk pipe and we just got - * a zero request, adjust our internal state. - * It's tempting to retry the read here to hide this "stray" - * packet from our callers, but that only works when you know - * there's another packet coming. That works in every case - * except the A000 discovery sequence. - */ - if ((receive_state == rs_frombulk) && (rv <= 0)) { - receive_state = rs_fromintr; - } - - return rv; + orig_receive_state = receive_state; + switch (receive_state) { + case rs_fromintr: + rv = gusb_llops->llop_get_intr(ibuf, sz); + break; + case rs_frombulk: + rv = gusb_llops->llop_get_bulk(ibuf, sz); + break; + default: + fatal("Unknown receiver state %d\n", receive_state); + } + + pkt_id = le_read16(&ibuf->gusb_pkt.pkt_id); + if (gps_show_bytes) { + int i; + const char* m1, *m2; + unsigned short pkttype = le_read16(&ibuf->gusb_pkt.databuf[0]); + + GPS_Diag("RX (%s) [%d]:", + receive_state == rs_fromintr ? "intr" : "bulk", rv); + + for (i=0; i 0) && (pkt_id == GUSB_REQUEST_BULK)) { + receive_state = rs_frombulk; + goto top; + } + /* + * If we were reading from the bulk pipe and we just got + * a zero request, adjust our internal state. + * It's tempting to retry the read here to hide this "stray" + * packet from our callers, but that only works when you know + * there's another packet coming. That works in every case + * except the A000 discovery sequence. + */ + if ((receive_state == rs_frombulk) && (rv <= 0)) { + receive_state = rs_fromintr; + } + + return rv; } -int -gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz) +int +gusb_cmd_send(const garmin_usb_packet* opkt, size_t sz) { - unsigned int rv, i; + unsigned int rv, i; - unsigned char *obuf = (unsigned char *) &opkt->dbuf; - const char *m1, *m2; + unsigned char* obuf = (unsigned char*) &opkt->dbuf; + const char* m1, *m2; - rv = gusb_llops->llop_send(opkt, sz); + rv = gusb_llops->llop_send(opkt, sz); - if (gps_show_bytes) { - const unsigned short pkttype = le_read16(&opkt->gusb_pkt.databuf[0]); - const unsigned short pkt_id = le_read16(&opkt->gusb_pkt.pkt_id); - GPS_Diag("TX [%d]:", sz); + if (gps_show_bytes) { + const unsigned short pkttype = le_read16(&opkt->gusb_pkt.databuf[0]); + const unsigned short pkt_id = le_read16(&opkt->gusb_pkt.pkt_id); + GPS_Diag("TX [%d]:", sz); - for(i=0;imax_tx_size)) { - gusb_cmd_send(opkt, 0); - } + if (sz && !(sz % gusb_llops->max_tx_size)) { + gusb_cmd_send(opkt, 0); + } - return (rv); + return (rv); } void gusb_list_units() { - int i; - - for (i = 0; i < GUSB_MAX_UNITS; i++) { - if (garmin_unit_info[i].serial_number) { - printf("%d %lu %lu %s\n", i, - garmin_unit_info[i].serial_number, - garmin_unit_info[i].unit_id, - garmin_unit_info[i].product_identifier - ); - } - } + int i; + + for (i = 0; i < GUSB_MAX_UNITS; i++) { + if (garmin_unit_info[i].serial_number) { + printf("%d %lu %lu %s\n", i, + garmin_unit_info[i].serial_number, + garmin_unit_info[i].unit_id, + garmin_unit_info[i].product_identifier + ); + } + } } void -gusb_id_unit(struct garmin_unit_info *gu) +gusb_id_unit(garmin_unit_info_t* gu) { - static const char oid[12] = - {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; - garmin_usb_packet iresp; - int i; - - gusb_cmd_send((garmin_usb_packet *)oid, sizeof(oid)); - - for (i = 0; i < 25; i++) { - iresp.gusb_pkt.type = 0; - if (gusb_cmd_get(&iresp, sizeof(iresp)) < 0) { - return; - } - if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { - gu->product_identifier = xstrdup((char *) iresp.gusb_pkt.databuf+4); - gu->unit_id = le_read16(iresp.gusb_pkt.databuf+0); - gu->unit_version = le_read16(iresp.gusb_pkt.databuf+2); - } - /* - * My goodnesss, this is fragile. During command syncup, - * we need to know if we're at the end. The 0xfd packet - * is promised by Garmin engineering to be the last. - */ - if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return; - } - fatal("Unable to sync with Garmin USB device in %d attempts.", i); -} + static const char oid[12] = + {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int i; + + gusb_cmd_send((garmin_usb_packet*)oid, sizeof(oid)); + + for (i = 0; i < 25; i++) { + iresp.gusb_pkt.type = 0; + if (gusb_cmd_get(&iresp, sizeof(iresp)) < 0) { + return; + } + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { + gu->product_identifier = xstrdup((char*) iresp.gusb_pkt.databuf+4); + gu->unit_id = le_read16(iresp.gusb_pkt.databuf+0); + gu->unit_version = le_read16(iresp.gusb_pkt.databuf+2); + } + /* + * My goodnesss, this is fragile. During command syncup, + * we need to know if we're at the end. The 0xfd packet + * is promised by Garmin engineering to be the last. + */ + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) { + return; + } + } + fatal("Unable to sync with Garmin USB device in %d attempts.", i); +} void gusb_syncup(void) { - static int unit_number; - static const char oinit[12] = - {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; - garmin_usb_packet iresp; - int i; - - /* - * This is our first communication with the unit. - */ - receive_state = rs_fromintr; - - for(i = 0; i < 25; i++) { - le_write16(&iresp.gusb_pkt.pkt_id, 0); - le_write32(&iresp.gusb_pkt.datasz, 0); - le_write32(&iresp.gusb_pkt.databuf, 0); - - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - gusb_cmd_get(&iresp, sizeof(iresp)); - - if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && - (le_read32(iresp.gusb_pkt.datasz) == 4)) { - unsigned serial_number = le_read32(iresp.gusb_pkt.databuf); - garmin_unit_info[unit_number].serial_number = serial_number; - gusb_id_unit(&garmin_unit_info[unit_number]); - - unit_number++; - - return; - } - } - fatal("Unable to establish USB syncup\n"); + static int unit_number; + static const char oinit[12] = + {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int i; + + /* + * This is our first communication with the unit. + */ + receive_state = rs_fromintr; + + for (i = 0; i < 25; i++) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_send((const garmin_usb_packet*) oinit, sizeof(oinit)); + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + unsigned serial_number = le_read32(iresp.gusb_pkt.databuf); + garmin_unit_info[unit_number].serial_number = serial_number; + gusb_id_unit(&garmin_unit_info[unit_number]); + + unit_number++; + + return; + } + } + fatal("Unable to establish USB syncup\n"); } diff --git a/gpsbabel/jeeps/gpsusbcommon.h b/gpsbabel/jeeps/gpsusbcommon.h index b0865f5f0..94d71f4e9 100644 --- a/gpsbabel/jeeps/gpsusbcommon.h +++ b/gpsbabel/jeeps/gpsusbcommon.h @@ -23,21 +23,21 @@ * The 'low level ops' are registered by the OS layer (win32, libusb, etc.) * to provide gruntwork features for the common USB layer. */ -typedef int (*gusb_llop_get)(garmin_usb_packet *ibuf, size_t sz); -typedef int (*gusb_llop_send)(const garmin_usb_packet *opkt, size_t sz); -typedef int (*gusb_llop_close) (gpsdevh *dh); +typedef int (*gusb_llop_get)(garmin_usb_packet* ibuf, size_t sz); +typedef int (*gusb_llop_send)(const garmin_usb_packet* opkt, size_t sz); +typedef int (*gusb_llop_close)(gpsdevh* dh); typedef struct gusb_llops { - gusb_llop_get llop_get_intr; - gusb_llop_get llop_get_bulk; - gusb_llop_send llop_send; - gusb_llop_close llop_close; - int max_tx_size; + gusb_llop_get llop_get_intr; + gusb_llop_get llop_get_bulk; + gusb_llop_send llop_send; + gusb_llop_close llop_close; + int max_tx_size; } gusb_llops_t; /* Provided by the common code. */ void gusb_syncup(void); -void gusb_register_ll(struct gusb_llops *); +void gusb_register_ll(struct gusb_llops*); void gusb_list_units(void); /* Provided by the OS layers */ diff --git a/gpsbabel/jeeps/gpsusbint.h b/gpsbabel/jeeps/gpsusbint.h index 8d91da24a..5386d7c06 100644 --- a/gpsbabel/jeeps/gpsusbint.h +++ b/gpsbabel/jeeps/gpsusbint.h @@ -21,7 +21,7 @@ */ -int32 GPS_Packet_Read_usb(gpsdevh *fd, GPS_PPacket *packet, int eatbulk); -void GPS_Make_Packet_usb(GPS_PPacket *packet, UC type, UC *data, int16 n); -int32 GPS_Write_Packet_usb(gpsdevh *fd, GPS_PPacket packet); +int32 GPS_Packet_Read_usb(gpsdevh* fd, GPS_PPacket* packet, int eatbulk); +void GPS_Make_Packet_usb(GPS_PPacket* packet, UC type, UC* data, int16 n); +int32 GPS_Write_Packet_usb(gpsdevh* fd, GPS_PPacket packet); diff --git a/gpsbabel/jeeps/gpsusbread.c b/gpsbabel/jeeps/gpsusbread.c index 5db7d36a9..7fb20386c 100644 --- a/gpsbabel/jeeps/gpsusbread.c +++ b/gpsbabel/jeeps/gpsusbread.c @@ -28,82 +28,81 @@ * Negative on error. * 1 if read success - even if empty packet. */ -int32 GPS_Packet_Read_usb(gpsdevh *dh, GPS_PPacket *packet, int eat_bulk) +int32 GPS_Packet_Read_usb(gpsdevh* dh, GPS_PPacket* packet, int eat_bulk) { - int32 n; - int32 payload_size; + int32 n; + int32 payload_size; - garmin_usb_packet pkt; + garmin_usb_packet pkt; - memset(&pkt, 0, sizeof(pkt)); + memset(&pkt, 0, sizeof(pkt)); do_over: - n = gusb_cmd_get(&pkt, sizeof(pkt)); + n = gusb_cmd_get(&pkt, sizeof(pkt)); - if ( n < 0 ) { - /* - * We (probably) used to have a GPS and it went away - * while we were speaking with it. Perhaps batteries - * died or it was unplugged or something. - */ - gps_errno = PROTOCOL_ERROR; - return n; - } + if (n < 0) { + /* + * We (probably) used to have a GPS and it went away + * while we were speaking with it. Perhaps batteries + * died or it was unplugged or something. + */ + gps_errno = PROTOCOL_ERROR; + return n; + } - /* - * This is a horrible hack for 276/296. This family sometimes - * switches between bulk and interrupt on EVERY packet. Rather - * than bother all the callers with that bit of unpleasantness, - * silently consume zero byte "switch back to intr" packets here. - * - * The one caller that doesn't want this hidden is device discovery - * in the A000 handler. - */ - if ((n == 0) && eat_bulk) { - goto do_over; - } - - /* We sometimes get corrupted packets during a track log transfer - * where the first byte in a packet is lost, causing all remaining - * bytes in this packet to be shifted. So far, this has only been - * observed on a Forerunner 305 (both on Linux and Windows). The - * cause is unknown, but it seems to be timing dependent. - * We try to detect the corruption mainly by checking reserved bytes - * 3 and 7 which normally should be 0, the remaining comparisons are - * only sanity checks and they alone could also trigger in case of - * valid packets. Note: We can't detect corrupted packets with an ID - * or length that's a multiple of 256, but such corrupted packets - * haven't been observed so far. - */ - if (gps_save_id == 484 - && pkt.gusb_pkt.type == 0 && pkt.gusb_pkt.reserved1 == 0 - && pkt.gusb_pkt.reserved2 == 0 && pkt.gusb_pkt.reserved3 != 0 - && pkt.gusb_pkt.pkt_id[0] <= 4 && pkt.gusb_pkt.pkt_id[1] == 0 - && pkt.gusb_pkt.reserved6 == 0 && pkt.gusb_pkt.reserved7 != 0) { - memmove(&pkt.dbuf[1], &pkt.dbuf[0], sizeof(pkt) - 1); - pkt.gusb_pkt.type = 20; - } - - /* - * Populate members of serial packet from USB packet. The - * copy here seems wasteful, but teaching all the callers about - * a structure with the "data" member being in a different place - * (Since the protocol packets was badly exposed in the core - * design of jeeps) is even more painful. - */ - (*packet)->type = le_read16(&pkt.gusb_pkt.pkt_id); - payload_size = le_read32(&pkt.gusb_pkt.datasz); - if (payload_size<0 || payload_size>MAX_GPS_PACKET_SIZE) - { - /* If you get this, the packet might have been corrupted - * by the unit. Have a look at the corruption detection - * code above. - */ - GPS_Error("GPS_Packet_Read_usb: Bad payload size %d", payload_size); - gps_errno = FRAMING_ERROR; - return 0; - } - (*packet)->n = payload_size; - memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size); - - return 1; + /* + * This is a horrible hack for 276/296. This family sometimes + * switches between bulk and interrupt on EVERY packet. Rather + * than bother all the callers with that bit of unpleasantness, + * silently consume zero byte "switch back to intr" packets here. + * + * The one caller that doesn't want this hidden is device discovery + * in the A000 handler. + */ + if ((n == 0) && eat_bulk) { + goto do_over; + } + + /* We sometimes get corrupted packets during a track log transfer + * where the first byte in a packet is lost, causing all remaining + * bytes in this packet to be shifted. So far, this has only been + * observed on a Forerunner 305 (both on Linux and Windows). The + * cause is unknown, but it seems to be timing dependent. + * We try to detect the corruption mainly by checking reserved bytes + * 3 and 7 which normally should be 0, the remaining comparisons are + * only sanity checks and they alone could also trigger in case of + * valid packets. Note: We can't detect corrupted packets with an ID + * or length that's a multiple of 256, but such corrupted packets + * haven't been observed so far. + */ + if (gps_save_id == 484 + && pkt.gusb_pkt.type == 0 && pkt.gusb_pkt.reserved1 == 0 + && pkt.gusb_pkt.reserved2 == 0 && pkt.gusb_pkt.reserved3 != 0 + && pkt.gusb_pkt.pkt_id[0] <= 4 && pkt.gusb_pkt.pkt_id[1] == 0 + && pkt.gusb_pkt.reserved6 == 0 && pkt.gusb_pkt.reserved7 != 0) { + memmove(&pkt.dbuf[1], &pkt.dbuf[0], sizeof(pkt) - 1); + pkt.gusb_pkt.type = 20; + } + + /* + * Populate members of serial packet from USB packet. The + * copy here seems wasteful, but teaching all the callers about + * a structure with the "data" member being in a different place + * (Since the protocol packets was badly exposed in the core + * design of jeeps) is even more painful. + */ + (*packet)->type = le_read16(&pkt.gusb_pkt.pkt_id); + payload_size = le_read32(&pkt.gusb_pkt.datasz); + if (payload_size<0 || payload_size>MAX_GPS_PACKET_SIZE) { + /* If you get this, the packet might have been corrupted + * by the unit. Have a look at the corruption detection + * code above. + */ + GPS_Error("GPS_Packet_Read_usb: Bad payload size %d", payload_size); + gps_errno = FRAMING_ERROR; + return 0; + } + (*packet)->n = payload_size; + memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size); + + return 1; } diff --git a/gpsbabel/jeeps/gpsusbsend.c b/gpsbabel/jeeps/gpsusbsend.c index 9aee54c7e..420445f4d 100644 --- a/gpsbabel/jeeps/gpsusbsend.c +++ b/gpsbabel/jeeps/gpsusbsend.c @@ -26,20 +26,20 @@ #include "gpsusbint.h" int32 -GPS_Write_Packet_usb(gpsdevh *dh, GPS_PPacket packet) +GPS_Write_Packet_usb(gpsdevh* dh, GPS_PPacket packet) { - garmin_usb_packet gp; - memset(&gp, 0, sizeof(gp)); + garmin_usb_packet gp; + memset(&gp, 0, sizeof(gp)); - /* - * Take the "portable" GPS_Packet data and put them into - * the USB packet that we will put on the wire. - */ - gp.gusb_pkt.type = 0x14; - le_write16(&gp.gusb_pkt.pkt_id, packet->type); - le_write32(&gp.gusb_pkt.datasz, packet->n ); - memcpy(&gp.gusb_pkt.databuf, packet->data, packet->n); + /* + * Take the "portable" GPS_Packet data and put them into + * the USB packet that we will put on the wire. + */ + gp.gusb_pkt.type = 0x14; + le_write16(&gp.gusb_pkt.pkt_id, packet->type); + le_write32(&gp.gusb_pkt.datasz, packet->n); + memcpy(&gp.gusb_pkt.databuf, packet->data, packet->n); - return gusb_cmd_send(&gp, packet->n + 12); + return gusb_cmd_send(&gp, packet->n + 12); } diff --git a/gpsbabel/jeeps/gpsusbstub.c b/gpsbabel/jeeps/gpsusbstub.c index 0838c1b5a..bf4fe7cf8 100644 --- a/gpsbabel/jeeps/gpsusbstub.c +++ b/gpsbabel/jeeps/gpsusbstub.c @@ -26,15 +26,15 @@ #include "../defs.h" -#if !HAVE_LIBUSB +#if !HAVE_LIBUSB const char no_usb[] = "USB support is not available in this build.\n"; int -gusb_init(const char *portname) +gusb_init(const char* portname) { - fatal(no_usb); - return 0; + fatal(no_usb); + return 0; } #endif /* defined(HAVE_LIBUSB) */ diff --git a/gpsbabel/jeeps/gpsusbwin.c b/gpsbabel/jeeps/gpsusbwin.c index 92fbcd137..c95918b15 100644 --- a/gpsbabel/jeeps/gpsusbwin.c +++ b/gpsbabel/jeeps/gpsusbwin.c @@ -19,9 +19,9 @@ */ -#include -#include -#include +#include +#include +#include #include #include #include @@ -35,11 +35,11 @@ /* Constants from Garmin doc. */ -// {2C9C45C2-8E7D-4C08-A12D-816BBAE722C0} +// {2C9C45C2-8E7D-4C08-A12D-816BBAE722C0} DEFINE_GUID(GARMIN_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b, 0xba, 0xe7, 0x22, 0xc0); -#define GARMIN_USB_API_VERSION 1 -#define GARMIN_USB_MAX_BUFFER_SIZE 4096 +#define GARMIN_USB_API_VERSION 1 +#define GARMIN_USB_MAX_BUFFER_SIZE 4096 #define GARMIN_USB_INTERRUPT_DATA_SIZE 64 #define IOCTL_GARMIN_USB_API_VERSION CTL_CODE \ @@ -50,154 +50,154 @@ DEFINE_GUID(GARMIN_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b, 0x (FILE_DEVICE_UNKNOWN, 0x851, METHOD_BUFFERED, FILE_ANY_ACCESS) typedef struct { - int booger; + int booger; } winusb_unit_data; -static HANDLE *usb_handle = INVALID_HANDLE_VALUE; +static HANDLE* usb_handle = INVALID_HANDLE_VALUE; static int usb_tx_packet_size ; -static const gdx_info *gdx; +static const gdx_info* gdx; -static int -gusb_win_close(gpsdevh *handle) +static int +gusb_win_close(gpsdevh* handle) { - if (usb_handle != INVALID_HANDLE_VALUE) { - CloseHandle(usb_handle); - usb_handle = INVALID_HANDLE_VALUE; - } + if (usb_handle != INVALID_HANDLE_VALUE) { + CloseHandle(usb_handle); + usb_handle = INVALID_HANDLE_VALUE; + } - return 0; + return 0; } static int -gusb_win_get(garmin_usb_packet *ibuf, size_t sz) +gusb_win_get(garmin_usb_packet* ibuf, size_t sz) { - DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE; - unsigned char *buf = (unsigned char *) &ibuf->dbuf; - int tsz=0; - - while (sz) { - /* The driver wrongly (IMO) rejects reads smaller than - * GARMIN_USB_INTERRUPT_DATA_SIZE - */ - if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0, - buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) { - GPS_Serial_Error("Ioctl"); - fatal("ioctl\n"); - } - buf += rxed; - sz -= rxed; - tsz += rxed; - if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE) { - break; - } - } - return tsz; + DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE; + unsigned char* buf = (unsigned char*) &ibuf->dbuf; + int tsz=0; + + while (sz) { + /* The driver wrongly (IMO) rejects reads smaller than + * GARMIN_USB_INTERRUPT_DATA_SIZE + */ + if (!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0, + buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) { + GPS_Serial_Error("Ioctl"); + fatal("ioctl\n"); + } + buf += rxed; + sz -= rxed; + tsz += rxed; + if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE) { + break; + } + } + return tsz; } static int -gusb_win_get_bulk(garmin_usb_packet *ibuf, size_t sz) +gusb_win_get_bulk(garmin_usb_packet* ibuf, size_t sz) { - int n; - DWORD rsz; - unsigned char *buf = (unsigned char *) &ibuf->dbuf; + int n; + DWORD rsz; + unsigned char* buf = (unsigned char*) &ibuf->dbuf; - n = ReadFile(usb_handle, buf, sz, &rsz, NULL); + n = ReadFile(usb_handle, buf, sz, &rsz, NULL); - return rsz; + return rsz; } static int -gusb_win_send(const garmin_usb_packet *opkt, size_t sz) +gusb_win_send(const garmin_usb_packet* opkt, size_t sz) { - DWORD rsz; - unsigned char *obuf = (unsigned char *) &opkt->dbuf; + DWORD rsz; + unsigned char* obuf = (unsigned char*) &opkt->dbuf; - /* The spec warns us about making writes an exact multiple - * of the packet size, but isn't clear whether we can issue - * data in a single call to WriteFile if it spans buffers. - */ - WriteFile(usb_handle, obuf, sz, &rsz, NULL); + /* The spec warns us about making writes an exact multiple + * of the packet size, but isn't clear whether we can issue + * data in a single call to WriteFile if it spans buffers. + */ + WriteFile(usb_handle, obuf, sz, &rsz, NULL); - if (rsz != sz) { - fatal ("Error sending %d bytes. Successfully sent %ld\n", sz, rsz); - } + if (rsz != sz) { + fatal("Error sending %d bytes. Successfully sent %ld\n", sz, rsz); + } - return rsz; + return rsz; } static gusb_llops_t win_llops = { - gusb_win_get, - gusb_win_get_bulk, - gusb_win_send, - gusb_win_close + gusb_win_get, + gusb_win_get_bulk, + gusb_win_send, + gusb_win_close }; static -HANDLE * garmin_usb_start(HDEVINFO* hdevinfo, SP_DEVICE_INTERFACE_DATA *infodata) +HANDLE* garmin_usb_start(HDEVINFO* hdevinfo, SP_DEVICE_INTERFACE_DATA* infodata) { - DWORD size; - PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL; - SP_DEVINFO_DATA devinfo; - - SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, - NULL, 0, &size, NULL); - - pdd = xmalloc(size); - pdd->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); - - devinfo.cbSize = sizeof(SP_DEVINFO_DATA); - if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, - pdd, size, NULL, &devinfo)) { - GPS_Serial_Error("SetupDiGetDeviceInterfaceDetail"); - return NULL; - } - - /* Whew. All that just to get something we can open... */ - GPS_Diag("Windows GUID for interface is \n\t%s\n", - pdd->DevicePath); - - if (usb_handle != INVALID_HANDLE_VALUE) { - fatal("garmin_usb_start called while device already started.\n"); - } - - usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ|GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, 0, NULL ); - if (usb_handle == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_ACCESS_DENIED) { - warning( -"Exclusive access is denied. It's likely that something else such as\n" -"Nroute, Spanner, Google Earth, or GPSGate already has control of the device\n"); - } - GPS_Serial_Error("(usb) CreateFile on '%s' failed", pdd->DevicePath); - return NULL; - } - - if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE, - NULL, 0, &usb_tx_packet_size, GARMIN_USB_INTERRUPT_DATA_SIZE, - &size, NULL)) { - fatal("Couldn't get USB packet size.\n"); - } - win_llops.max_tx_size = usb_tx_packet_size; - - gusb_syncup(); - - return usb_handle; + DWORD size; + PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL; + SP_DEVINFO_DATA devinfo; + + SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, + NULL, 0, &size, NULL); + + pdd = xmalloc(size); + pdd->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); + + devinfo.cbSize = sizeof(SP_DEVINFO_DATA); + if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, + pdd, size, NULL, &devinfo)) { + GPS_Serial_Error("SetupDiGetDeviceInterfaceDetail"); + return NULL; + } + + /* Whew. All that just to get something we can open... */ + GPS_Diag("Windows GUID for interface is \n\t%s\n", + pdd->DevicePath); + + if (usb_handle != INVALID_HANDLE_VALUE) { + fatal("garmin_usb_start called while device already started.\n"); + } + + usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ|GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + if (usb_handle == INVALID_HANDLE_VALUE) { + if (GetLastError() == ERROR_ACCESS_DENIED) { + warning( + "Exclusive access is denied. It's likely that something else such as\n" + "Nroute, Spanner, Google Earth, or GPSGate already has control of the device\n"); + } + GPS_Serial_Error("(usb) CreateFile on '%s' failed", pdd->DevicePath); + return NULL; + } + + if (!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE, + NULL, 0, &usb_tx_packet_size, GARMIN_USB_INTERRUPT_DATA_SIZE, + &size, NULL)) { + fatal("Couldn't get USB packet size.\n"); + } + win_llops.max_tx_size = usb_tx_packet_size; + + gusb_syncup(); + + return usb_handle; } -static char ** get_garmin_mountpoints(void) +static char** get_garmin_mountpoints(void) { #define BUFSIZE 512 TCHAR szTemp[MAX_PATH]; - char *p = szTemp; - char **dlist = xmalloc(sizeof(*dlist)); + char* p = szTemp; + char** dlist = xmalloc(sizeof(*dlist)); int i = 0; dlist[0] = NULL; if (GetLogicalDriveStringsA(BUFSIZE-1, szTemp)) { - while(*p) { - dlist = xrealloc(dlist, sizeof (*dlist ) * (++i + 1)); + while (*p) { + dlist = xrealloc(dlist, sizeof(*dlist) * (++i + 1)); // fprintf(stderr, "Found: %d, %s\n", i, p); dlist[i-1] = xstrdup(p); dlist[i] = NULL; @@ -213,82 +213,84 @@ static char ** get_garmin_mountpoints(void) * device, and light it up. */ int -gusb_init(const char *pname, gpsdevh **dh) +gusb_init(const char* pname, gpsdevh** dh) { - int req_unit_number = 0; - int un = 0; - int match; - - HDEVINFO hdevinfo; - SP_DEVICE_INTERFACE_DATA devinterface; - - winusb_unit_data *wud = xcalloc(sizeof (winusb_unit_data), 1); - *dh = (gpsdevh*) wud; - - gusb_register_ll(&win_llops); - - if (strlen(pname) > 4) { - if (0 == strcmp(pname+4, "list")) { - req_unit_number = -1; - } else { - req_unit_number = atoi(pname+4); - } - } - - hdevinfo = SetupDiGetClassDevs( (GUID *) &GARMIN_GUID, NULL, NULL, - DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); - - if (hdevinfo == INVALID_HANDLE_VALUE) { - GPS_Serial_Error("SetupDiGetClassDevs failed"); - warning("Is the Garmin USB driver installed?"); - return 0; - } - - devinterface.cbSize = sizeof(devinterface); - - if (req_unit_number >= 0) { - if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, - (GUID *) &GARMIN_GUID, - req_unit_number, &devinterface)) { - // If there were zero matches, we may be trying to talk to a "GPX Mode" device. - - - char **dlist = get_garmin_mountpoints(); - gdx = gdx_find_file(dlist); - if (gdx) return 1; - - - // Plan C. - GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); - warning("Is the Garmin USB unit number %d powered up and connected?\nIs it really a USB unit? If it's serial, don't choose USB, choose serial.\nAre the Garmin USB drivers installed and functioning with other programs?\nIs it a storage based device like Nuvi, CO, or OR?\n If so, send GPX files to it, don't use this module.\n", un); - return 0; - } - /* We've matched. Now start the specific unit. */ - garmin_usb_start(hdevinfo, &devinterface); - return 1; - } - - /* - * Out unit nunber is less than zero, so loop over all units - * and display them. - */ - for(match = 0;;match++) { - if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, - (GUID *) &GARMIN_GUID, match, &devinterface)) { - if (GetLastError() == ERROR_NO_MORE_ITEMS) { - - break; - } else { - - GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); - warning("Is the Garmin USB unit number %d powered up and connected?", un); - return 0; - } - } - /* We've matched. Now start the specific unit. */ - garmin_usb_start(hdevinfo, &devinterface); - gusb_close(NULL); - } - gusb_list_units(); - exit (0); + int req_unit_number = 0; + int un = 0; + int match; + + HDEVINFO hdevinfo; + SP_DEVICE_INTERFACE_DATA devinterface; + + winusb_unit_data* wud = xcalloc(sizeof(winusb_unit_data), 1); + *dh = (gpsdevh*) wud; + + gusb_register_ll(&win_llops); + + if (strlen(pname) > 4) { + if (0 == strcmp(pname+4, "list")) { + req_unit_number = -1; + } else { + req_unit_number = atoi(pname+4); + } + } + + hdevinfo = SetupDiGetClassDevs((GUID*) &GARMIN_GUID, NULL, NULL, + DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); + + if (hdevinfo == INVALID_HANDLE_VALUE) { + GPS_Serial_Error("SetupDiGetClassDevs failed"); + warning("Is the Garmin USB driver installed?"); + return 0; + } + + devinterface.cbSize = sizeof(devinterface); + + if (req_unit_number >= 0) { + if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, + (GUID*) &GARMIN_GUID, + req_unit_number, &devinterface)) { + // If there were zero matches, we may be trying to talk to a "GPX Mode" device. + + + char** dlist = get_garmin_mountpoints(); + gdx = gdx_find_file(dlist); + if (gdx) { + return 1; + } + + + // Plan C. + GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); + warning("Is the Garmin USB unit number %d powered up and connected?\nIs it really a USB unit? If it's serial, don't choose USB, choose serial.\nAre the Garmin USB drivers installed and functioning with other programs?\nIs it a storage based device like Nuvi, CO, or OR?\n If so, send GPX files to it, don't use this module.\n", un); + return 0; + } + /* We've matched. Now start the specific unit. */ + garmin_usb_start(hdevinfo, &devinterface); + return 1; + } + + /* + * Out unit nunber is less than zero, so loop over all units + * and display them. + */ + for (match = 0;; match++) { + if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, + (GUID*) &GARMIN_GUID, match, &devinterface)) { + if (GetLastError() == ERROR_NO_MORE_ITEMS) { + + break; + } else { + + GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); + warning("Is the Garmin USB unit number %d powered up and connected?", un); + return 0; + } + } + /* We've matched. Now start the specific unit. */ + garmin_usb_start(hdevinfo, &devinterface); + gusb_close(NULL); + } + gusb_list_units(); + exit(0); } diff --git a/gpsbabel/jeeps/gpsutil.c b/gpsbabel/jeeps/gpsutil.c index 4078e2e5e..8a6201b7e 100644 --- a/gpsbabel/jeeps/gpsutil.c +++ b/gpsbabel/jeeps/gpsutil.c @@ -2,20 +2,20 @@ ** @source JEEPS utility functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -44,28 +44,27 @@ int32 gps_errno = 0; int32 GPS_Util_Little(void) { - static union lb - { - char chars[sizeof(int32)]; - int32 i; - } - data; - - if(!gps_endian_called) - { - gps_endian_called = 1; - data.i = 0; - *data.chars = '\1'; - if(data.i == 1) - GPS_Little = 1; - else - GPS_Little = 0; + static union lb { + char chars[sizeof(int32)]; + int32 i; + } + data; + + if (!gps_endian_called) { + gps_endian_called = 1; + data.i = 0; + *data.chars = '\1'; + if (data.i == 1) { + GPS_Little = 1; + } else { + GPS_Little = 0; } + } - return GPS_Little; + return GPS_Little; } - + /* @func GPS_Util_Get_Short ******************************************** ** ** Get a short from a string @@ -73,25 +72,22 @@ int32 GPS_Util_Little(void) ** @return [US] value ************************************************************************/ -US GPS_Util_Get_Short(const UC *s) +US GPS_Util_Get_Short(const UC* s) { - static US ret; - UC *p; - - p = (UC *)&ret; - - if(!GPS_Little) - { - *p++ = *(s+1); - *p = *s; - } - else - { - *p++ = *s; - *p = *(s+1); - } + static US ret; + UC* p; + + p = (UC*)&ret; - return ret; + if (!GPS_Little) { + *p++ = *(s+1); + *p = *s; + } else { + *p++ = *s; + *p = *(s+1); + } + + return ret; } @@ -106,24 +102,21 @@ US GPS_Util_Get_Short(const UC *s) ** @return [void] ************************************************************************/ -void GPS_Util_Put_Short(UC *s, const US v) +void GPS_Util_Put_Short(UC* s, const US v) { - UC *p; - - p = (UC *)&v; - - if(!GPS_Little) - { - *s++ = *(p+1); - *s = *p; - } - else - { - *s++ = *p; - *s = *(p+1); - } + UC* p; - return; + p = (UC*)&v; + + if (!GPS_Little) { + *s++ = *(p+1); + *s = *p; + } else { + *s++ = *p; + *s = *(p+1); + } + + return; } @@ -135,23 +128,25 @@ void GPS_Util_Put_Short(UC *s, const US v) ** @return [double] value ************************************************************************/ -double GPS_Util_Get_Double(const UC *s) +double GPS_Util_Get_Double(const UC* s) { - double ret; - UC *p; - int32 i; + double ret; + UC* p; + int32 i; - p = (UC *)&ret; + p = (UC*)&ret; - - if(!GPS_Little) - for(i=sizeof(double)-1;i>-1;--i) - *p++ = s[i]; - else - for(i=0;i<(int32)sizeof(double);++i) - *p++ = s[i]; - return ret; + if (!GPS_Little) + for (i=sizeof(double)-1; i>-1; --i) { + *p++ = s[i]; + } + else + for (i=0; i<(int32)sizeof(double); ++i) { + *p++ = s[i]; + } + + return ret; } @@ -166,21 +161,23 @@ double GPS_Util_Get_Double(const UC *s) ** @return [void] ************************************************************************/ -void GPS_Util_Put_Double(UC *s, const double v) +void GPS_Util_Put_Double(UC* s, const double v) { - UC *p; - int32 i; - - p = (UC *)&v; - - if(!GPS_Little) - for(i=sizeof(double)-1;i>-1;--i) - s[i] = *p++; - else - for(i=0;i<(int32)sizeof(double);++i) - s[i] = *p++; + UC* p; + int32 i; - return; + p = (UC*)&v; + + if (!GPS_Little) + for (i=sizeof(double)-1; i>-1; --i) { + s[i] = *p++; + } + else + for (i=0; i<(int32)sizeof(double); ++i) { + s[i] = *p++; + } + + return; } @@ -193,23 +190,25 @@ void GPS_Util_Put_Double(UC *s, const double v) ** @return [int32] value ************************************************************************/ -int32 GPS_Util_Get_Int(const UC *s) +int32 GPS_Util_Get_Int(const UC* s) { - int32 ret; - UC *p; - int32 i; - - p = (UC *)&ret; - - - if(!GPS_Little) - for(i=sizeof(int32)-1;i>-1;--i) - *p++ = s[i]; - else - for(i=0;i<(int32)sizeof(int32);++i) - *p++ = s[i]; - - return ret; + int32 ret; + UC* p; + int32 i; + + p = (UC*)&ret; + + + if (!GPS_Little) + for (i=sizeof(int32)-1; i>-1; --i) { + *p++ = s[i]; + } + else + for (i=0; i<(int32)sizeof(int32); ++i) { + *p++ = s[i]; + } + + return ret; } @@ -224,21 +223,23 @@ int32 GPS_Util_Get_Int(const UC *s) ** @return [void] ************************************************************************/ -void GPS_Util_Put_Int(UC *s, const int32 v) +void GPS_Util_Put_Int(UC* s, const int32 v) { - UC *p; - int32 i; - - p = (UC *)&v; - - if(!GPS_Little) - for(i=sizeof(int32)-1;i>-1;--i) - s[i] = *p++; - else - for(i=0;i<(int32)sizeof(int32);++i) - s[i] = *p++; + UC* p; + int32 i; - return; + p = (UC*)&v; + + if (!GPS_Little) + for (i=sizeof(int32)-1; i>-1; --i) { + s[i] = *p++; + } + else + for (i=0; i<(int32)sizeof(int32); ++i) { + s[i] = *p++; + } + + return; } @@ -250,23 +251,25 @@ void GPS_Util_Put_Int(UC *s, const int32 v) ** @return [uint32] value ************************************************************************/ -uint32 GPS_Util_Get_Uint(const UC *s) +uint32 GPS_Util_Get_Uint(const UC* s) { - uint32 ret; - UC *p; - int32 i; - - p = (UC *)&ret; - - - if(!GPS_Little) - for(i=sizeof(uint32)-1;i>-1;--i) - *p++ = s[i]; - else - for(i=0;i<(int32)sizeof(uint32);++i) - *p++ = s[i]; - - return ret; + uint32 ret; + UC* p; + int32 i; + + p = (UC*)&ret; + + + if (!GPS_Little) + for (i=sizeof(uint32)-1; i>-1; --i) { + *p++ = s[i]; + } + else + for (i=0; i<(int32)sizeof(uint32); ++i) { + *p++ = s[i]; + } + + return ret; } @@ -281,21 +284,23 @@ uint32 GPS_Util_Get_Uint(const UC *s) ** @return [void] ************************************************************************/ -void GPS_Util_Put_Uint(UC *s, const uint32 v) +void GPS_Util_Put_Uint(UC* s, const uint32 v) { - UC *p; - int32 i; - - p = (UC *)&v; - - if(!GPS_Little) - for(i=sizeof(uint32)-1;i>-1;--i) - s[i] = *p++; - else - for(i=0;i<(int32)sizeof(uint32);++i) - s[i] = *p++; + UC* p; + int32 i; - return; + p = (UC*)&v; + + if (!GPS_Little) + for (i=sizeof(uint32)-1; i>-1; --i) { + s[i] = *p++; + } + else + for (i=0; i<(int32)sizeof(uint32); ++i) { + s[i] = *p++; + } + + return; } @@ -307,23 +312,25 @@ void GPS_Util_Put_Uint(UC *s, const uint32 v) ** @return [float] value ************************************************************************/ -float GPS_Util_Get_Float(const UC *s) +float GPS_Util_Get_Float(const UC* s) { - float ret; - UC *p; - int32 i; + float ret; + UC* p; + int32 i; - p = (UC *)&ret; + p = (UC*)&ret; - - if(!GPS_Little) - for(i=sizeof(float)-1;i>-1;--i) - *p++ = s[i]; - else - for(i=0;i<(int32)sizeof(float);++i) - *p++ = s[i]; - return ret; + if (!GPS_Little) + for (i=sizeof(float)-1; i>-1; --i) { + *p++ = s[i]; + } + else + for (i=0; i<(int32)sizeof(float); ++i) { + *p++ = s[i]; + } + + return ret; } @@ -338,21 +345,23 @@ float GPS_Util_Get_Float(const UC *s) ** @return [void] ************************************************************************/ -void GPS_Util_Put_Float(UC *s, const float v) +void GPS_Util_Put_Float(UC* s, const float v) { - UC *p; - int32 i; - - p = (UC *)&v; - - if(!GPS_Little) - for(i=sizeof(float)-1;i>-1;--i) - s[i] = *p++; - else - for(i=0;i<(int32)sizeof(float);++i) - s[i] = *p++; + UC* p; + int32 i; - return; + p = (UC*)&v; + + if (!GPS_Little) + for (i=sizeof(float)-1; i>-1; --i) { + s[i] = *p++; + } + else + for (i=0; i<(int32)sizeof(float); ++i) { + s[i] = *p++; + } + + return; } #if 0 @@ -369,24 +378,23 @@ void GPS_Util_Put_Float(UC *s, const float v) void GPS_Util_Canon(int32 state) { - static struct termios tty; - static struct termios sv; - - - if(state) - { - tcgetattr(1,&sv); - tcgetattr(1, &tty); - tty.c_cc[VMIN]='\1'; - tty.c_cc[VTIME]='\0'; - tcsetattr(1,TCSANOW,&tty); - tty.c_lflag &= ~(ICANON | ECHO); - tcsetattr(1, TCSANOW, &tty); - } - else - tcsetattr(1, TCSANOW, &sv); - - return; + static struct termios tty; + static struct termios sv; + + + if (state) { + tcgetattr(1,&sv); + tcgetattr(1, &tty); + tty.c_cc[VMIN]='\1'; + tty.c_cc[VTIME]='\0'; + tcsetattr(1,TCSANOW,&tty); + tty.c_lflag &= ~(ICANON | ECHO); + tcsetattr(1, TCSANOW, &tty); + } else { + tcsetattr(1, TCSANOW, &sv); + } + + return; } #endif @@ -398,50 +406,43 @@ void GPS_Util_Canon(int32 state) ** ** @param [r] fd [int32] file descriptor ** @param [r] state [int32] state=true->block state=false->non-block -** +** ** @return [int32] success ** @@ ****************************************************************************/ int32 GPS_Util_Block(int32 fd, int32 state) { - static int32 notcalled=1; - static int32 block; - static int32 noblock; - int32 f; - - gps_errno = HARDWARE_ERROR; - - if(notcalled) - { - notcalled = 0; - if((f=fcntl(fd,F_GETFL,0))==-1) - { - GPS_Error("Util_Block: FCNTL error"); - return 0; - } - block = f & ~O_NDELAY; - noblock = f | O_NDELAY; + static int32 notcalled=1; + static int32 block; + static int32 noblock; + int32 f; + + gps_errno = HARDWARE_ERROR; + + if (notcalled) { + notcalled = 0; + if ((f=fcntl(fd,F_GETFL,0))==-1) { + GPS_Error("Util_Block: FCNTL error"); + return 0; } - - if(state) - { - if(fcntl(fd,F_SETFL,block)==-1) - { - GPS_Error("Util_Block: Error blocking"); - return 0; - } + block = f & ~O_NDELAY; + noblock = f | O_NDELAY; + } + + if (state) { + if (fcntl(fd,F_SETFL,block)==-1) { + GPS_Error("Util_Block: Error blocking"); + return 0; } - else - { - if(fcntl(fd,F_SETFL,noblock)==-1) - { - GPS_Error("Util_Block: Error unblocking"); - return 0; - } + } else { + if (fcntl(fd,F_SETFL,noblock)==-1) { + GPS_Error("Util_Block: Error unblocking"); + return 0; } + } - return 1; + return 1; } #endif @@ -456,15 +457,16 @@ int32 GPS_Util_Block(int32 fd, int32 state) ** @@ ****************************************************************************/ -void GPS_Warning(char *s) +void GPS_Warning(char* s) { - if(!gps_warning) - return; - - fprintf(stderr,"[WARNING] %s\n",s); - fflush(stderr); - + if (!gps_warning) { return; + } + + fprintf(stderr,"[WARNING] %s\n",s); + fflush(stderr); + + return; } @@ -479,12 +481,12 @@ void GPS_Warning(char *s) ** @@ ****************************************************************************/ -void GPS_Fatal(char *s) +void GPS_Fatal(char* s) { - fprintf(stderr,"[FATAL] %s\n",s); - exit(0); - return; + fprintf(stderr,"[FATAL] %s\n",s); + exit(0); + return; } @@ -499,21 +501,22 @@ void GPS_Fatal(char *s) ** @@ ****************************************************************************/ -void GPS_Error(char *fmt, ...) +void GPS_Error(char* fmt, ...) { - va_list argp; - va_start(argp, fmt); + va_list argp; + va_start(argp, fmt); - if(!gps_error) - return; + if (!gps_error) { + return; + } - fprintf(stderr, "[ERROR] "); - vfprintf(stderr, fmt, argp); - fprintf(stderr, "\n"); + fprintf(stderr, "[ERROR] "); + vfprintf(stderr, fmt, argp); + fprintf(stderr, "\n"); - va_end(argp); - return; + va_end(argp); + return; } @@ -527,8 +530,8 @@ void GPS_Error(char *fmt, ...) void GPS_Enable_Error(void) { - gps_error = 1; - return; + gps_error = 1; + return; } @@ -543,8 +546,8 @@ void GPS_Enable_Error(void) void GPS_Enable_Warning(void) { - gps_warning = 1; - return; + gps_warning = 1; + return; } @@ -559,8 +562,8 @@ void GPS_Enable_Warning(void) void GPS_Disable_Error(void) { - gps_error = 0; - return; + gps_error = 0; + return; } @@ -575,8 +578,8 @@ void GPS_Disable_Error(void) void GPS_Disable_Warning(void) { - gps_warning = 0; - return; + gps_warning = 0; + return; } @@ -591,17 +594,17 @@ void GPS_Disable_Warning(void) ** @@ ****************************************************************************/ -void GPS_User(const char *fmt, ...) +void GPS_User(const char* fmt, ...) { - va_list argp; - va_start (argp, fmt); + va_list argp; + va_start(argp, fmt); - if (gps_user) { - vfprintf(stdout, fmt, argp); - fflush(stdout); - } - - va_end(argp); + if (gps_user) { + vfprintf(stdout, fmt, argp); + fflush(stdout); + } + + va_end(argp); } /* @func GPS_Disable_User *********************************************** @@ -614,8 +617,8 @@ void GPS_User(const char *fmt, ...) void GPS_Disable_User(void) { - gps_user = 0; - return; + gps_user = 0; + return; } @@ -629,8 +632,8 @@ void GPS_Disable_User(void) void GPS_Enable_User(void) { - gps_user = 1; - return; + gps_user = 1; + return; } @@ -646,25 +649,26 @@ void GPS_Enable_User(void) void GPS_Diagnose(int32 c) { - if(!gps_show_bytes) - return; - - fprintf(stdout,"%d\n",(int)c); - fflush(stdout); - + if (!gps_show_bytes) { return; + } + + fprintf(stdout,"%d\n",(int)c); + fflush(stdout); + + return; } -void GPS_Diag(const char *fmt, ...) +void GPS_Diag(const char* fmt, ...) { - va_list argp; - va_start(argp, fmt); + va_list argp; + va_start(argp, fmt); - if(gps_show_bytes) { - vfprintf(stdout, fmt, argp); - } - va_end(argp); - return; + if (gps_show_bytes) { + vfprintf(stdout, fmt, argp); + } + va_end(argp); + return; } @@ -678,8 +682,8 @@ void GPS_Diag(const char *fmt, ...) void GPS_Enable_Diagnose(void) { - gps_show_bytes = 1; - return; + gps_show_bytes = 1; + return; } @@ -694,6 +698,6 @@ void GPS_Enable_Diagnose(void) void GPS_Disable_Diagnose(void) { - gps_show_bytes = 0; - return; + gps_show_bytes = 0; + return; } diff --git a/gpsbabel/jeeps/gpsutil.h b/gpsbabel/jeeps/gpsutil.h index faf1e0f06..625176659 100644 --- a/gpsbabel/jeeps/gpsutil.h +++ b/gpsbabel/jeeps/gpsutil.h @@ -9,37 +9,37 @@ extern "C" #include "gps.h" -int32 GPS_Util_Little(void); - -US GPS_Util_Get_Short(const UC *s); -void GPS_Util_Put_Short(UC *s, const US v); -int32 GPS_Util_Get_Int(const UC *s); -void GPS_Util_Put_Int(UC *s, const int32 v); -double GPS_Util_Get_Double(const UC *s); -void GPS_Util_Put_Double(UC *s, const double v); -float GPS_Util_Get_Float(const UC *s); -void GPS_Util_Put_Float(UC *s, const float v); -void GPS_Util_Canon(int32 state); -int32 GPS_Util_Block(int32 fd, int32 state); -void GPS_Util_Put_Uint(UC *s, const uint32 v); -uint32 GPS_Util_Get_Uint(const UC *s); - -void GPS_Warning(char *s); -void GPS_Error(char *fmt, ...); -void GPS_Serial_Error(const char *hdr, ...); -void GPS_Fatal(char *s); -void GPS_Enable_Error(void); -void GPS_Enable_Warning(void); -void GPS_Disable_Error(void); -void GPS_Disable_Warning(void); -void GPS_User(const char *fmt, ...); -void GPS_Disable_User(void); -void GPS_Enable_User(void); -void GPS_Diagnose(int32 c); -void GPS_Diag(const char *fmt, ...); - -void GPS_Enable_Diagnose(void); -void GPS_Disable_Diagnose(void); + int32 GPS_Util_Little(void); + + US GPS_Util_Get_Short(const UC* s); + void GPS_Util_Put_Short(UC* s, const US v); + int32 GPS_Util_Get_Int(const UC* s); + void GPS_Util_Put_Int(UC* s, const int32 v); + double GPS_Util_Get_Double(const UC* s); + void GPS_Util_Put_Double(UC* s, const double v); + float GPS_Util_Get_Float(const UC* s); + void GPS_Util_Put_Float(UC* s, const float v); + void GPS_Util_Canon(int32 state); + int32 GPS_Util_Block(int32 fd, int32 state); + void GPS_Util_Put_Uint(UC* s, const uint32 v); + uint32 GPS_Util_Get_Uint(const UC* s); + + void GPS_Warning(char* s); + void GPS_Error(char* fmt, ...); + void GPS_Serial_Error(const char* hdr, ...); + void GPS_Fatal(char* s); + void GPS_Enable_Error(void); + void GPS_Enable_Warning(void); + void GPS_Disable_Error(void); + void GPS_Disable_Warning(void); + void GPS_User(const char* fmt, ...); + void GPS_Disable_User(void); + void GPS_Enable_User(void); + void GPS_Diagnose(int32 c); + void GPS_Diag(const char* fmt, ...); + + void GPS_Enable_Diagnose(void); + void GPS_Disable_Diagnose(void); #endif diff --git a/gpsbabel/jeeps/main.c b/gpsbabel/jeeps/main.c index a8488248b..128cbd2b7 100644 --- a/gpsbabel/jeeps/main.c +++ b/gpsbabel/jeeps/main.c @@ -3,29 +3,29 @@ main() { - int n; - GPS_PWay *way; - GPS_PWay *array; + int n; + GPS_PWay* way; + GPS_PWay* array; - if (GPS_Init("/dev/ttyS0") < 0) { - fprintf(stderr, "Can't init\n"); - } - - if((n=GPS_Command_Get_Waypoint("/dev/ttyS0", &way))<0) { - fprintf(stderr, "can't get\n"); - return; - } + if (GPS_Init("/dev/ttyS0") < 0) { + fprintf(stderr, "Can't init\n"); + } + + if ((n=GPS_Command_Get_Waypoint("/dev/ttyS0", &way))<0) { + fprintf(stderr, "can't get\n"); + return; + } // fprintf(stdout," Done\n"); - GPS_Fmt_Print_Waypoint(way, n, stdout); + GPS_Fmt_Print_Waypoint(way, n, stdout); - array = (GPS_PWay *) calloc(1, sizeof(GPS_PWay)); - array[0] = GPS_Way_New(); - strcpy(array[0]->ident,"lower @#$%^&* rocks"); - strcpy(array[0]->cmnt,"COMMENTCOMMENTCOMMENTCOMMENTCOMMENT"); - array[0]->wpt_class = 0; - array[0]->lat = 1.234; - array[0]->lon = 1.234; -GPS_Command_Send_Waypoint("/dev/ttyS0", array, 1); + array = (GPS_PWay*) calloc(1, sizeof(GPS_PWay)); + array[0] = GPS_Way_New(); + strcpy(array[0]->ident,"lower @#$%^&* rocks"); + strcpy(array[0]->cmnt,"COMMENTCOMMENTCOMMENTCOMMENTCOMMENT"); + array[0]->wpt_class = 0; + array[0]->lat = 1.234; + array[0]->lon = 1.234; + GPS_Command_Send_Waypoint("/dev/ttyS0", array, 1); } diff --git a/gpsbabel/jogmap.c b/gpsbabel/jogmap.c index 9273f5249..62c65085e 100644 --- a/gpsbabel/jogmap.c +++ b/gpsbabel/jogmap.c @@ -1,4 +1,4 @@ -/* +/* Support for XML files from jogmap.de @@ -25,20 +25,19 @@ #include "jeeps/gpsmath.h" #include "garmin_tables.h" -static route_head *trk; +static route_head* trk; -static arglist_t jogmap_args[] = -{ - ARG_TERMINATOR +static arglist_t jogmap_args[] = { + ARG_TERMINATOR }; #define MYNAME "xol" #if ! HAVE_LIBEXPAT void -jogmap_rd_init(const char *fname) +jogmap_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); } void @@ -56,74 +55,77 @@ jogmap_read(void) static void -jogmap_markers(const char *args, const char **attrv) +jogmap_markers(const char* args, const char** attrv) { - trk = route_head_alloc(); - track_add_head(trk); + trk = route_head_alloc(); + track_add_head(trk); } static void -jogmap_marker(const char *args, const char **attrv) +jogmap_marker(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - waypoint *wpt = waypt_new(); - - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &wpt->latitude); - } else - if (strcmp(avp[0], "lng") == 0) { - sscanf(avp[1], "%lf", - &wpt->longitude); - } - - avp+=2; - } - - if (trk) track_add_wpt(trk, wpt); + const char** avp = &attrv[0]; + waypoint* wpt = waypt_new(); + + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt->latitude); + } else if (strcmp(avp[0], "lng") == 0) { + sscanf(avp[1], "%lf", + &wpt->longitude); + } + + avp+=2; + } + + if (trk) { + track_add_wpt(trk, wpt); + } } static xg_tag_mapping jogmap_map[] = { - { jogmap_markers, cb_start, "/markers" }, - { jogmap_marker, cb_start, "/markers/marker" }, - { NULL, 0, NULL } + { jogmap_markers, cb_start, "/markers" }, + { jogmap_marker, cb_start, "/markers/marker" }, + { NULL, (xg_cb_type)0, NULL } }; -static void -jogmap_rd_init(const char *fname) +static void +jogmap_rd_init(const char* fname) { - trk = NULL; - xml_init(fname, jogmap_map, NULL); + trk = NULL; + xml_init(fname, jogmap_map, NULL); } -static void +static void jogmap_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void jogmap_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } ff_vecs_t jogmap_vecs = { - ff_type_file, - { ff_cap_none, /* waypoints */ - ff_cap_read, /* tracks */ - ff_cap_none }, /* routes */ - jogmap_rd_init, - NULL, - jogmap_rd_deinit, - NULL, - jogmap_read, - NULL, - NULL, - jogmap_args, - CET_CHARSET_UTF8, 0 + ff_type_file, + { + ff_cap_none, /* waypoints */ + ff_cap_read, /* tracks */ + ff_cap_none + }, /* routes */ + jogmap_rd_init, + NULL, + jogmap_rd_deinit, + NULL, + jogmap_read, + NULL, + NULL, + jogmap_args, + CET_CHARSET_UTF8, 0 }; diff --git a/gpsbabel/jtr.c b/gpsbabel/jtr.c index 2fe5425b3..861928a21 100644 --- a/gpsbabel/jtr.c +++ b/gpsbabel/jtr.c @@ -32,47 +32,51 @@ static arglist_t jtr_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; -static gbfile *fin, *fout; -static avltree_t *trkpts; +static gbfile* fin, *fout; +static avltree_t* trkpts; static time_t -jtr_parse_time(const char *str, struct tm *tm, int *micro) +jtr_parse_time(const char* str, struct tm* tm, int* micro) { - long int hms; - char *dot; - - hms = strtol(str, &dot, 10); - if (hms > 0) { - tm->tm_sec = hms % 100; - hms = hms / 100; - tm->tm_min = hms % 100; - hms = hms / 100; - tm->tm_hour = hms % 100; - - if ((*dot == '.') && (micro != NULL)) *micro = atoi(dot + 1) * 10000; - - return mkgmtime(tm); - } - else return 0; + long int hms; + char* dot; + + hms = strtol(str, &dot, 10); + if (hms > 0) { + tm->tm_sec = hms % 100; + hms = hms / 100; + tm->tm_min = hms % 100; + hms = hms / 100; + tm->tm_hour = hms % 100; + + if ((*dot == '.') && (micro != NULL)) { + *micro = atoi(dot + 1) * 10000; + } + + return mkgmtime(tm); + } else { + return 0; + } } static time_t -jtr_parse_date(const char *str, struct tm *tm) +jtr_parse_date(const char* str, struct tm* tm) { - int dmy = atoi(str); - - if (dmy > 0) { - tm->tm_year = dmy % 100 + 100; - dmy = dmy / 100; - tm->tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm->tm_mday = dmy; - return mkgmtime(tm); - } - else return 0; + int dmy = atoi(str); + + if (dmy > 0) { + tm->tm_year = dmy % 100 + 100; + dmy = dmy / 100; + tm->tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm->tm_mday = dmy; + return mkgmtime(tm); + } else { + return 0; + } } /******************************************************************************* @@ -80,206 +84,266 @@ jtr_parse_date(const char *str, struct tm *tm) *******************************************************************************/ static void -jtr_rd_init(const char *fname) +jtr_rd_init(const char* fname) { - fin = gbfopen(fname, "r", MYNAME); - trkpts = avltree_init(0, MYNAME); + fin = gbfopen(fname, "r", MYNAME); + trkpts = avltree_init(0, MYNAME); } static void jtr_rd_deinit(void) { - avltree_done(trkpts); - gbfclose(fin); + avltree_done(trkpts); + gbfclose(fin); } static void jtr_read(void) { - char *str; - int line = 0; - route_head *trk = NULL; - - while ((str = gbfgetstr(fin))) { - waypoint *wpt; - struct tm tm; - char *tmp; - int column = -1; - char valid = 'V'; - double lat, lon; - float speed, course, mcourse, mvar, mdev; - time_t time = 0; - int micros = 0; - char buf[32]; - char mvardir, mdevdir; - - line++; - - str = lrtrim(str); - if (*str == '\0') continue; - - if (strncmp(str, "GEOTAG2,", 8) != 0) - fatal(MYNAME ": Unknown or unsupported file (missing \"GEOTAG2\")!\n"); - - memset(&tm, 0, sizeof(tm)); - lat = lon = 999; - speed = course = mcourse = mvar = mdev = -1; - mvardir = mdevdir = 0; - - column = -1; - tmp = str; - while ((str = csv_lineparse(tmp, ",", "", column++))) { - tmp = NULL; - - if (*str == '\0') continue; - - switch(column) { - case 0: break; /* GEOTAG2 */ - case 1: jtr_parse_time(str, &tm, µs); break; - case 2: valid = *str; break; - case 3: lat = ddmm2degrees(atof(str)); break; - case 4: if (*str == 'S') lat *= -1; break; - case 5: lon = ddmm2degrees(atof(str)); break; - case 6: if (*str == 'W') lon *= -1; break; - case 7: speed = KNOTS_TO_MPS(atof(str)); break; - case 8: course = atof(str); break; - case 9: jtr_parse_date(str, &tm); break; - case 13: mcourse = atof(str); break; - case 14: mdev = atof(str); break; - case 15: mdevdir = *str; break; - case 16: mvar = atof(str); break; - case 17: mvardir = *str; break; - default: - break; - } - } - - if ((lat == 999) || (lon == 999) || (valid != 'A')) continue; - - if (tm.tm_year > 0) time = mkgmtime(&tm); - else time = 0; - - /* check for duplicates as suggested in format description */ - - snprintf(buf, sizeof(buf), "%.6f\01%.6f\01%ld", lat, lon, (long)time); - if (avltree_find(trkpts, buf, NULL)) continue; - - wpt = waypt_new(); - - wpt->latitude = lat; - wpt->longitude = lon; - wpt->creation_time = time; - wpt->microseconds = micros; - if (speed >= 0) WAYPT_SET(wpt, speed, speed); - if (mcourse >= 0) { - course = mcourse; - if (mvar >= 0) { - if (mvardir == 'W') course += mvar; - else if (mvardir == 'E') course -= mvar; - } - if (mdev >= 0) { - if (mdevdir == 'W') course += mdev; - else if (mdevdir == 'E') course -= mdev; - } - } - if (course >= 0) WAYPT_SET(wpt, course, course); - - if (trk == NULL) { - trk = route_head_alloc(); - track_add_head(trk); - } - - avltree_insert(trkpts, buf, wpt); - track_add_wpt(trk, wpt); - } + char* str; + int line = 0; + route_head* trk = NULL; + + while ((str = gbfgetstr(fin))) { + waypoint* wpt; + struct tm tm; + char* tmp; + int column = -1; + char valid = 'V'; + double lat, lon; + float speed, course, mcourse, mvar, mdev; + time_t time = 0; + int micros = 0; + char buf[32]; + char mvardir, mdevdir; + + line++; + + str = lrtrim(str); + if (*str == '\0') { + continue; + } + + if (strncmp(str, "GEOTAG2,", 8) != 0) { + fatal(MYNAME ": Unknown or unsupported file (missing \"GEOTAG2\")!\n"); + } + + memset(&tm, 0, sizeof(tm)); + lat = lon = 999; + speed = course = mcourse = mvar = mdev = -1; + mvardir = mdevdir = 0; + + column = -1; + tmp = str; + while ((str = csv_lineparse(tmp, ",", "", column++))) { + tmp = NULL; + + if (*str == '\0') { + continue; + } + + switch (column) { + case 0: + break; /* GEOTAG2 */ + case 1: + jtr_parse_time(str, &tm, µs); + break; + case 2: + valid = *str; + break; + case 3: + lat = ddmm2degrees(atof(str)); + break; + case 4: + if (*str == 'S') { + lat *= -1; + } + break; + case 5: + lon = ddmm2degrees(atof(str)); + break; + case 6: + if (*str == 'W') { + lon *= -1; + } + break; + case 7: + speed = KNOTS_TO_MPS(atof(str)); + break; + case 8: + course = atof(str); + break; + case 9: + jtr_parse_date(str, &tm); + break; + case 13: + mcourse = atof(str); + break; + case 14: + mdev = atof(str); + break; + case 15: + mdevdir = *str; + break; + case 16: + mvar = atof(str); + break; + case 17: + mvardir = *str; + break; + default: + break; + } + } + + if ((lat == 999) || (lon == 999) || (valid != 'A')) { + continue; + } + + if (tm.tm_year > 0) { + time = mkgmtime(&tm); + } else { + time = 0; + } + + /* check for duplicates as suggested in format description */ + + snprintf(buf, sizeof(buf), "%.6f\01%.6f\01%ld", lat, lon, (long)time); + if (avltree_find(trkpts, buf, NULL)) { + continue; + } + + wpt = waypt_new(); + + wpt->latitude = lat; + wpt->longitude = lon; + wpt->creation_time = time; + wpt->microseconds = micros; + if (speed >= 0) { + WAYPT_SET(wpt, speed, speed); + } + if (mcourse >= 0) { + course = mcourse; + if (mvar >= 0) { + if (mvardir == 'W') { + course += mvar; + } else if (mvardir == 'E') { + course -= mvar; + } + } + if (mdev >= 0) { + if (mdevdir == 'W') { + course += mdev; + } else if (mdevdir == 'E') { + course -= mdev; + } + } + } + if (course >= 0) { + WAYPT_SET(wpt, course, course); + } + + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + + avltree_insert(trkpts, buf, wpt); + track_add_wpt(trk, wpt); + } } static void -jtr_wr_init(const char *fname) +jtr_wr_init(const char* fname) { - fout = gbfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); } static void jtr_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void -jtr_trkpt_disp_cb(const waypoint *wpt) +jtr_trkpt_disp_cb(const waypoint* wpt) { - char *str, *tmp; - char stime[10], sdate[7], scourse[6], sspeed[8]; - struct tm tm; - - if (wpt->creation_time > 0) { - tm = *gmtime(&wpt->creation_time); - tm.tm_year += 1900; - tm.tm_mon += 1; - snprintf(sdate, sizeof(sdate), "%02d%02d%02d", tm.tm_mday, tm.tm_mon, tm.tm_year % 100); - snprintf(stime, sizeof(stime), "%02d%02d%02d.%02d", tm.tm_hour, tm.tm_min, tm.tm_sec, wpt->microseconds / 10000); - if (wpt->microseconds / 10000 == 0) stime[6] = 0; - } - else { - stime[0] = 0; - sdate[0] = 0; - } - if (WAYPT_HAS(wpt, speed) && (wpt->speed >= 0)) - snprintf(sspeed, sizeof(sspeed), "%.1f", MPS_TO_KNOTS(wpt->speed)); - else sspeed[0] = 0; - if (WAYPT_HAS(wpt, course) && (wpt->course >= 0)) - snprintf(scourse, sizeof(scourse), "%.1f", wpt->course); - else scourse[0] = 0; - - xasprintf(&str, "GEOTAG2,%s,%c,%09.4f,%c,%010.4f,%c,%s,%s,%s,,E,A", - stime, - time > 0 ? 'A' : 'V', - fabs(degrees2ddmm(wpt->latitude)), - wpt->latitude < 0 ? 'S' : 'N', - fabs(degrees2ddmm(wpt->longitude)), - wpt->longitude < 0 ? 'W' : 'E', - sspeed, - scourse, - sdate); - - xasprintf(&tmp, "%s*%02X", str, nmea_cksum(str)); - xfree(str); - str = tmp; - - xasprintf(&tmp, "%s,,,E,,E*%02X\r", str, nmea_cksum(str)); - xfree(str); - str = tmp; - - gbfputs(str, fout); - xfree(str); + char* str, *tmp; + char stime[10], sdate[7], scourse[6], sspeed[8]; + struct tm tm; + + if (wpt->creation_time > 0) { + tm = *gmtime(&wpt->creation_time); + tm.tm_year += 1900; + tm.tm_mon += 1; + snprintf(sdate, sizeof(sdate), "%02d%02d%02d", tm.tm_mday, tm.tm_mon, tm.tm_year % 100); + snprintf(stime, sizeof(stime), "%02d%02d%02d.%02d", tm.tm_hour, tm.tm_min, tm.tm_sec, wpt->microseconds / 10000); + if (wpt->microseconds / 10000 == 0) { + stime[6] = 0; + } + } else { + stime[0] = 0; + sdate[0] = 0; + } + if (WAYPT_HAS(wpt, speed) && (wpt->speed >= 0)) { + snprintf(sspeed, sizeof(sspeed), "%.1f", MPS_TO_KNOTS(wpt->speed)); + } else { + sspeed[0] = 0; + } + if (WAYPT_HAS(wpt, course) && (wpt->course >= 0)) { + snprintf(scourse, sizeof(scourse), "%.1f", wpt->course); + } else { + scourse[0] = 0; + } + + xasprintf(&str, "GEOTAG2,%s,%c,%09.4f,%c,%010.4f,%c,%s,%s,%s,,E,A", + stime, + time > 0 ? 'A' : 'V', + fabs(degrees2ddmm(wpt->latitude)), + wpt->latitude < 0 ? 'S' : 'N', + fabs(degrees2ddmm(wpt->longitude)), + wpt->longitude < 0 ? 'W' : 'E', + sspeed, + scourse, + sdate); + + xasprintf(&tmp, "%s*%02X", str, nmea_cksum(str)); + xfree(str); + str = tmp; + + xasprintf(&tmp, "%s,,,E,,E*%02X\r", str, nmea_cksum(str)); + xfree(str); + str = tmp; + + gbfputs(str, fout); + xfree(str); } static void jtr_write(void) { - track_disp_all(NULL, NULL, jtr_trkpt_disp_cb); + track_disp_all(NULL, NULL, jtr_trkpt_disp_cb); } /**************************************************************************/ ff_vecs_t jtr_vecs = { - ff_type_file, - { - ff_cap_none, /* waypoints */ - ff_cap_read | ff_cap_write, /* tracks */ - ff_cap_none /* routes */ - }, - jtr_rd_init, - jtr_wr_init, - jtr_rd_deinit, - jtr_wr_deinit, - jtr_read, - jtr_write, - NULL, - jtr_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_none, /* waypoints */ + (ff_cap)(ff_cap_read | ff_cap_write), /* tracks */ + ff_cap_none /* routes */ + }, + jtr_rd_init, + jtr_wr_init, + jtr_rd_deinit, + jtr_wr_deinit, + jtr_read, + jtr_write, + NULL, + jtr_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/kml.c b/gpsbabel/kml.c index e7285c721..ccd023c09 100644 --- a/gpsbabel/kml.c +++ b/gpsbabel/kml.c @@ -29,19 +29,19 @@ #endif // options -static char *opt_deficon = NULL; -static char *opt_export_lines = NULL; -static char *opt_export_points = NULL; -static char *opt_export_track = NULL; -static char *opt_line_width = NULL; -static char *opt_line_color = NULL; -static char *opt_floating = NULL; -static char *opt_extrude = NULL; -static char *opt_trackdata = NULL; -static char *opt_trackdirection = NULL; -static char *opt_units = NULL; -static char *opt_labels = NULL; -static char *opt_max_position_points = NULL; +static char* opt_deficon = NULL; +static char* opt_export_lines = NULL; +static char* opt_export_points = NULL; +static char* opt_export_track = NULL; +static char* opt_line_width = NULL; +static char* opt_line_color = NULL; +static char* opt_floating = NULL; +static char* opt_extrude = NULL; +static char* opt_trackdata = NULL; +static char* opt_trackdirection = NULL; +static char* opt_units = NULL; +static char* opt_labels = NULL; +static char* opt_max_position_points = NULL; static int export_lines; static int export_points; @@ -51,17 +51,17 @@ static int extrude; static int trackdata; static int trackdirection; static int max_position_points; -static int export_track; static int line_width; +static int html_encrypt; static int indent_level; -static waypoint *wpt_tmp; +static waypoint* wpt_tmp; static int wpt_tmp_queued; -static const char *posnfilename; -static char *posnfilenametmp; +static const char* posnfilename; +static char* posnfilenametmp; -static gbfile *ofd; +static gbfile* ofd; #define COORD_FORMAT "%.6f" #define ALT_FORMAT "%.2f" // Beyond a centimeter is fantasy. @@ -101,54 +101,78 @@ static const char kmt_power[] = "power"; static arglist_t kml_args[] = { - {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"lines", &opt_export_lines, - "Export linestrings for tracks and routes", - "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"points", &opt_export_points, - "Export placemarks for tracks and routes", - "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"line_width", &opt_line_width, - "Width of lines, in pixels", - "6", ARGTYPE_INT, ARG_NOMINMAX }, - {"line_color", &opt_line_color, - "Line color, specified in hex AABBGGRR", - "99ffac59", ARGTYPE_STRING, ARG_NOMINMAX }, - {"floating", &opt_floating, - "Altitudes are absolute and not clamped to ground", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"extrude", &opt_extrude, - "Draw extrusion line from trackpoint to ground", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"track", &opt_export_track, - "Write KML track (default = 0)", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"trackdata", &opt_trackdata, - "Include extended data for trackpoints (default = 1)", - "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"trackdirection", &opt_trackdirection, - "Indicate direction of travel in track icons (default = 0)", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"units", &opt_units, - "Units used when writing comments ('s'tatute, 'm'etric,' 'n'autical)", - "s", ARGTYPE_STRING, ARG_NOMINMAX }, - {"labels", &opt_labels, - "Display labels on track and routepoints (default = 1)", - "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"max_position_points", &opt_max_position_points, - "Retain at most this number of position points (0 = unlimited)", - "0", ARGTYPE_INT, ARG_NOMINMAX }, - ARG_TERMINATOR + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { + "lines", &opt_export_lines, + "Export linestrings for tracks and routes", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "points", &opt_export_points, + "Export placemarks for tracks and routes", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "line_width", &opt_line_width, + "Width of lines, in pixels", + "6", ARGTYPE_INT, ARG_NOMINMAX + }, + { + "line_color", &opt_line_color, + "Line color, specified in hex AABBGGRR", + "99ffac59", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "floating", &opt_floating, + "Altitudes are absolute and not clamped to ground", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "extrude", &opt_extrude, + "Draw extrusion line from trackpoint to ground", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "track", &opt_export_track, + "Write KML track (default = 0)", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "trackdata", &opt_trackdata, + "Include extended data for trackpoints (default = 1)", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "trackdirection", &opt_trackdirection, + "Indicate direction of travel in track icons (default = 0)", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "units", &opt_units, + "Units used when writing comments ('s'tatute, 'm'etric,' 'n'autical, 'a'viation)", + "s", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "labels", &opt_labels, + "Display labels on track and routepoints (default = 1)", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "max_position_points", &opt_max_position_points, + "Retain at most this number of position points (0 = unlimited)", + "0", ARGTYPE_INT, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static struct { - int freshness; - const char *icon; + int freshness; + const char* icon; } kml_tracking_icons[] = { - { 60, ICON_BASE "youarehere-60.png" }, // Red - { 30, ICON_BASE "youarehere-30.png" }, // Yellow - { 0, ICON_BASE "youarehere-0.png" }, // Green + { 60, ICON_BASE "youarehere-60.png" }, // Red + { 30, ICON_BASE "youarehere-30.png" }, // Yellow + { 0, ICON_BASE "youarehere-0.png" }, // Green }; #define ICON_NOSAT ICON_BASE "youarehere-warning.png"; @@ -162,9 +186,9 @@ struct { #if ! HAVE_LIBEXPAT static void -kml_rd_init(const char *fname) +kml_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded KML support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded KML support because expat was not installed.\n"); } static void @@ -178,170 +202,183 @@ static xg_callback wpt_name, wpt_desc, wpt_coord, wpt_icon, trk_coord, wpt_time; static xg_tag_mapping kml_map[] = { - { wpt_s, cb_start, "/Placemark" }, - { wpt_e, cb_end, "/Placemark" }, - { wpt_name, cb_cdata, "/Placemark/name" }, - { wpt_desc, cb_cdata, "/Placemark/description" }, - { wpt_time, cb_cdata, "/Placemark/TimeStamp/when" }, - // Alias for above used in KML 2.0 - { wpt_time, cb_cdata, "/Placemark/TimeInstant/timePosition" }, - { wpt_coord, cb_cdata, "/Placemark/Point/coordinates" }, - { wpt_icon, cb_cdata, "/Placemark/Style/Icon/href" }, - { trk_coord, cb_cdata, "/Placemark/MultiGeometry/LineString/coordinates" }, - { trk_coord, cb_cdata, "/Placemark/GeometryCollection/LineString/coordinates" }, - { trk_coord, cb_cdata, "/Placemark/Polygon/outerBoundaryIs/LinearRing/coordinates" }, - { trk_coord, cb_cdata, "/Placemark/LineString/coordinates" }, - { NULL, 0, NULL } + { wpt_s, cb_start, "/Placemark" }, + { wpt_e, cb_end, "/Placemark" }, + { wpt_name, cb_cdata, "/Placemark/name" }, + { wpt_desc, cb_cdata, "/Placemark/description" }, + { wpt_time, cb_cdata, "/Placemark/TimeStamp/when" }, + // Alias for above used in KML 2.0 + { wpt_time, cb_cdata, "/Placemark/TimeInstant/timePosition" }, + { wpt_coord, cb_cdata, "/Placemark/Point/coordinates" }, + { wpt_icon, cb_cdata, "/Placemark/Style/Icon/href" }, + { trk_coord, cb_cdata, "/Placemark/MultiGeometry/LineString/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/GeometryCollection/LineString/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/Polygon/outerBoundaryIs/LinearRing/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/LineString/coordinates" }, + { NULL, (xg_cb_type) 0, NULL } }; static -const char * kml_tags_to_ignore[] = { - "kml", - "Document", - "Folder", - NULL, +const char* kml_tags_to_ignore[] = { + "kml", + "Document", + "Folder", + NULL, }; -void wpt_s(const char *args, const char **unused) +void wpt_s(const char* args, const char** unused) { - wpt_tmp = waypt_new(); - wpt_tmp_queued = 0; + wpt_tmp = waypt_new(); + wpt_tmp_queued = 0; } -void wpt_e(const char *args, const char **unused) +void wpt_e(const char* args, const char** unused) { - if (wpt_tmp_queued) { - waypt_add(wpt_tmp); - } - wpt_tmp_queued = 0; + if (wpt_tmp_queued) { + waypt_add(wpt_tmp); + } + wpt_tmp_queued = 0; } -void wpt_name(const char *args, const char **unused) +void wpt_name(const char* args, const char** unused) { - if (args) wpt_tmp->shortname = xstrdup(args); + if (args) { + wpt_tmp->shortname = xstrdup(args); + } } -void wpt_desc(const char *args, const char **unused) +void wpt_desc(const char* args, const char** unused) { - if (args) { - char *tmp, *c; - - tmp = xstrdup((char *)args); - c = lrtrim(tmp); - if (*c) { - wpt_tmp->description = xstrappend(wpt_tmp->description, c); - } - xfree(tmp); - } + if (args) { + char* tmp, *c; + + tmp = xstrdup((char*)args); + c = lrtrim(tmp); + if (*c) { + wpt_tmp->description = xstrappend(wpt_tmp->description, c); + } + xfree(tmp); + } } -void wpt_time(const char *args, const char **unused) +void wpt_time(const char* args, const char** unused) { - wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); + wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); } -void wpt_coord(const char *args, const char **attrv) +void wpt_coord(const char* args, const char** attrv) { - int n = 0; - double lat, lon, alt; - // Alt is actually optional. - n = sscanf(args, "%lf,%lf,%lf", &lon, &lat, &alt); - if (n >= 2) { - wpt_tmp->latitude = lat; - wpt_tmp->longitude = lon; - } - if (n == 3) { - wpt_tmp->altitude = alt; - } - wpt_tmp_queued = 1; + int n = 0; + double lat, lon, alt; + // Alt is actually optional. + n = sscanf(args, "%lf,%lf,%lf", &lon, &lat, &alt); + if (n >= 2) { + wpt_tmp->latitude = lat; + wpt_tmp->longitude = lon; + } + if (n == 3) { + wpt_tmp->altitude = alt; + } + wpt_tmp_queued = 1; } -void wpt_icon(const char *args, const char **unused) +void wpt_icon(const char* args, const char** unused) { - if (wpt_tmp) { - wpt_tmp->icon_descr = xstrdup(args); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - } + if (wpt_tmp) { + wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + } } -void trk_coord(const char *args, const char **attrv) +void trk_coord(const char* args, const char** attrv) { - int consumed = 0; - double lat, lon, alt; - waypoint *trkpt; - int n = 0; - - route_head *trk_head = route_head_alloc(); - if (wpt_tmp->shortname) { - trk_head->rte_name = xstrdup(wpt_tmp->shortname); - } - track_add_head(trk_head); + int consumed = 0; + double lat, lon, alt; + waypoint* trkpt; + int n = 0; + + route_head* trk_head = route_head_alloc(); + if (wpt_tmp->shortname) { + trk_head->rte_name = xstrdup(wpt_tmp->shortname); + } + track_add_head(trk_head); - while ((n = sscanf(args, "%lf,%lf,%lf %n", &lon, &lat, &alt, &consumed)) > 0) { + while ((n = sscanf(args, "%lf,%lf,%lf%n", &lon, &lat, &alt, &consumed)) > 0) { - trkpt = waypt_new(); - trkpt->latitude = lat; - trkpt->longitude = lon; + trkpt = waypt_new(); + trkpt->latitude = lat; + trkpt->longitude = lon; - // Line malformed or two-arg format without alt . Rescan. - if (2 == n) { - sscanf(args, "%lf,%lf %n", &lon, &lat, &consumed); - } + // Line malformed or two-arg format without alt . Rescan. + if (2 == n) { + sscanf(args, "%lf,%lf%n", &lon, &lat, &consumed); + } - if (3 == n) { - trkpt->altitude = alt; - } + if (3 == n) { + trkpt->altitude = alt; + } - track_add_wpt(trk_head, trkpt); + track_add_wpt(trk_head, trkpt); - args += consumed; - } + args += consumed; + } } static void -kml_rd_init(const char *fname) +kml_rd_init(const char* fname) { - xml_init(fname, kml_map, NULL); - xml_ignore_tags(kml_tags_to_ignore); + xml_init(fname, kml_map, NULL); + xml_ignore_tags(kml_tags_to_ignore); } static void kml_read(void) { - xml_read(); + xml_read(); } #endif static void kml_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void -kml_wr_init(const char *fname) +kml_wr_init(const char* fname) { - char u = 's'; - waypt_init_bounds(&kml_bounds); - kml_time_min = 0; - kml_time_max = 0; - - if (opt_units) { - u = tolower(opt_units[0]); - } - - switch(u) { - case 's': fmt_setunits(units_statute); break; - case 'm': fmt_setunits(units_metric); break; - case 'n': fmt_setunits(units_nautical); break; - default: fatal("Units argument '%s' should be 's' for statute units or 'm' for metric.", opt_units); break; - } - /* - * Reduce race conditions with network read link. - */ - ofd = gbfopen(fname, "w", MYNAME); + char u = 's'; + waypt_init_bounds(&kml_bounds); + kml_time_min = 0; + kml_time_max = 0; + + if (opt_units) { + u = tolower(opt_units[0]); + } + + switch (u) { + case 's': + fmt_setunits(units_statute); + break; + case 'm': + fmt_setunits(units_metric); + break; + case 'n': + fmt_setunits(units_nautical); + break; + case 'a': + fmt_setunits(units_aviation); + break; + default: + fatal("Units argument '%s' should be 's' for statute units, 'm' for metric, 'n' for nautical or 'a' for aviation.\n", opt_units); + break; + } + /* + * Reduce race conditions with network read link. + */ + ofd = gbfopen(fname, "w", MYNAME); } /* @@ -349,44 +386,44 @@ kml_wr_init(const char *fname) * updated. */ static void -kml_wr_position_init(const char *fname) +kml_wr_position_init(const char* fname) { - posnfilename = fname; - posnfilenametmp = xstrappend(xstrdup(fname), "-"); - realtime_positioning = 1; + posnfilename = fname; + posnfilenametmp = xstrappend(xstrdup(fname), "-"); + realtime_positioning = 1; - /* - * 30% of our output file is whitespace. Since parse time - * matters in this mode, turn the pretty formatting off. - */ - do_indentation = 0; + /* + * 30% of our output file is whitespace. Since parse time + * matters in this mode, turn the pretty formatting off. + */ + do_indentation = 0; - max_position_points = atoi(opt_max_position_points); + max_position_points = atoi(opt_max_position_points); } static void kml_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); - if (posnfilenametmp) { + if (posnfilenametmp) { #if __WIN32__ - MoveFileExA(posnfilenametmp, posnfilename, - MOVEFILE_REPLACE_EXISTING); + MoveFileExA(posnfilenametmp, posnfilename, + MOVEFILE_REPLACE_EXISTING); #endif - rename(posnfilenametmp, posnfilename); - } - ofd = NULL; + rename(posnfilenametmp, posnfilename); + } + ofd = NULL; } static void kml_wr_position_deinit(void) { // kml_wr_deinit(); - if (posnfilenametmp) { - xfree(posnfilenametmp); - posnfilenametmp = NULL; - } + if (posnfilenametmp) { + xfree(posnfilenametmp); + posnfilenametmp = NULL; + } } /* @@ -396,25 +433,33 @@ kml_wr_position_deinit(void) * If negative, descrease the indent level. */ static void -kml_write_xml(int indent, const char *fmt, ...) +kml_write_xml(int indent, const char* fmt, ...) { - va_list args; - int i; - va_start(args, fmt); + va_list args; + int i; + va_start(args, fmt); - if (indent < 0) indent_level--; + if (indent < 0) { + indent_level--; + } + + if (indent_level < 0) { + fatal("Indention nesting problem in KML writer."); + } - if (fmt[1] != '!' && do_indentation) { - for (i = 0; i < indent_level; i++) { - gbfputs(" ", ofd); - } - } + if (fmt[1] != '!' && do_indentation) { + for (i = 0; i < indent_level; i++) { + gbfputs(" ", ofd); + } + } - gbvfprintf(ofd, fmt, args); + gbvfprintf(ofd, fmt, args); - if (indent > 0) indent_level++; + if (indent > 0) { + indent_level++; + } - va_end(args); + va_end(args); } /* @@ -422,31 +467,37 @@ kml_write_xml(int indent, const char *fmt, ...) * Never changes indention leve, but does honour it. */ static void -kml_write_xmle(const char *tag, const char *fmt, ...) +kml_write_xmle(const char* tag, const char* fmt, ...) { - va_list args; - int i; - va_start(args, fmt); - - if (fmt && *fmt) { - char *tmp_ent = xml_entitize(fmt); - int needs_escaping = 0; - for (i = 0; i < indent_level; i++) { - gbfputs(" ", ofd); - } - if (strspn(tmp_ent, "&'<>\"")) - needs_escaping = 1; - gbfprintf(ofd, "<%s>", tag); - if (needs_escaping) gbfprintf(ofd, ""); - gbfprintf(ofd, "\n", tag); - xfree(tmp_ent); - } + va_list args; + int i; + va_start(args, fmt); + + if (fmt && *fmt) { + char* tmp_ent = xml_entitize(fmt); + int needs_escaping = 0; + for (i = 0; i < indent_level; i++) { + gbfputs(" ", ofd); + } + if (strspn(tmp_ent, "&'<>\"")) { + needs_escaping = 1; + } + gbfprintf(ofd, "<%s>", tag); + if (needs_escaping) { + gbfprintf(ofd, ""); + } + gbfprintf(ofd, "\n", tag); + xfree(tmp_ent); + } } void -kml_output_linestyle(char *color, int width) { +kml_output_linestyle(char* color, int width) +{ // Style settings for line strings kml_write_xml(1, "\n"); kml_write_xml(0, "%s\n", opt_line_color); @@ -456,309 +507,334 @@ kml_output_linestyle(char *color, int width) { #define hovertag(h) h ? 'h' : 'n' -static void kml_write_bitmap_style_(const char *style, const char * bitmap, - int highlighted, int force_heading) +static void kml_write_bitmap_style_(const char* style, const char* bitmap, + int highlighted, int force_heading) { - int is_track = !strncmp(style, "track", 5); - int is_multitrack = !strncmp(style, "multiTrack", 5); - - kml_write_xml(0, "\n", - highlighted ? "Highlighted" : "Normal", style); - kml_write_xml(1, "\n"); + kml_write_xml(-1, "\n"); } /* A wrapper for the above function to emit both a highlighted * and non-highlighted version of the style to allow the icons * to magnify slightly on a rollover. */ -static void kml_write_bitmap_style(kml_point_type pt_type, const char *bitmap, - const char *customstyle) +static void kml_write_bitmap_style(kml_point_type pt_type, const char* bitmap, + const char* customstyle) { - int force_heading = 0; - const char *style; - switch (pt_type) { - case kmlpt_track: style = "track"; break; - case kmlpt_route: style = "route"; break; - case kmlpt_waypoint: style = "waypoint"; break; - case kmlpt_multitrack: style = "multiTrack"; break; - case kmlpt_other: style = customstyle; force_heading = 1; break; - default: fatal("kml_output_point: unknown point type"); break; - } - - kml_write_bitmap_style_(style, bitmap, 0, force_heading); - kml_write_bitmap_style_(style, bitmap, 1, force_heading); - - kml_write_xml(1, "\n", style); - kml_write_xml(1, "\n"); - kml_write_xml(0, "normal\n"); - kml_write_xml(0, "#%s_%c\n",style, hovertag(0)); - kml_write_xml(-1, "\n"); - kml_write_xml(1, "\n"); - kml_write_xml(0, "highlight\n"); - kml_write_xml(0, "#%s_%c\n",style, hovertag(1)); - kml_write_xml(-1, "\n"); - kml_write_xml(-1, "\n"); + int force_heading = 0; + const char* style; + switch (pt_type) { + case kmlpt_track: + style = "track"; + break; + case kmlpt_route: + style = "route"; + break; + case kmlpt_waypoint: + style = "waypoint"; + break; + case kmlpt_multitrack: + style = "multiTrack"; + break; + case kmlpt_other: + style = customstyle; + force_heading = 1; + break; + default: + fatal("kml_output_point: unknown point type"); + break; + } + + kml_write_bitmap_style_(style, bitmap, 0, force_heading); + kml_write_bitmap_style_(style, bitmap, 1, force_heading); + + kml_write_xml(1, "\n", style); + kml_write_xml(1, "\n"); + kml_write_xml(0, "normal\n"); + kml_write_xml(0, "#%s_%c\n",style, hovertag(0)); + kml_write_xml(-1, "\n"); + kml_write_xml(1, "\n"); + kml_write_xml(0, "highlight\n"); + kml_write_xml(0, "#%s_%c\n",style, hovertag(1)); + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); } -static void kml_output_timestamp(const waypoint *waypointp) +static void kml_output_timestamp(const waypoint* waypointp) { - char time_string[64]; - if (waypointp->creation_time) { - xml_fill_in_time(time_string, waypointp->creation_time, waypointp->microseconds, XML_LONG_TIME); - if (time_string[0]) { - kml_write_xml(0, "%s\n", - time_string); - } - } + char time_string[64]; + if (waypointp->creation_time) { + xml_fill_in_time(time_string, waypointp->creation_time, waypointp->microseconds, XML_LONG_TIME); + if (time_string[0]) { + kml_write_xml(0, "%s\n", + time_string); + } + } } /* * Output the track summary. */ static -void kml_output_trkdescription(const route_head *header, computed_trkdata *td) +void kml_output_trkdescription(const route_head* header, computed_trkdata* td) { - char *max_alt_units; - double max_alt; - char *min_alt_units; - double min_alt; - char *distance_units; - double distance; - - if (!td || !trackdata) { - return; - } - - max_alt = fmt_distance(td->max_alt, &max_alt_units); - min_alt = fmt_distance(td->min_alt, &min_alt_units); - distance = fmt_distance(td->distance_meters, &distance_units); - - kml_write_xml(0, "\n"); - - kml_write_xml(1, "\n"); - kml_write_xml(1, "\n"); - - if (header->rte_desc) { - TD("Description %s", header->rte_desc); - } - TD2("Distance %.1f %s", distance, distance_units); - if (min_alt != unknown_alt) { - TD2("Min Alt %.3f %s", min_alt, min_alt_units); - } - if (max_alt != unknown_alt) { - TD2("Max Alt %.3f %s", max_alt, max_alt_units); - } - if (td->min_spd) { - char *spd_units; - double spd = fmt_speed(td->min_spd, &spd_units); - TD2("Min Speed %.1f %s", spd, spd_units); - } - if (td->max_spd) { - char *spd_units; - double spd = fmt_speed(td->max_spd, &spd_units); - TD2("Max Speed %.1f %s", spd, spd_units); - } - if (td->max_spd && td->start && td->end) { - char *spd_units; - time_t elapsed = td->end - td->start; - double spd = fmt_speed(td->distance_meters / elapsed, &spd_units); - if (spd > 1.0) { - TD2("Avg Speed %.1f %s", spd, spd_units); - } - } - if (td->avg_hrt) { - TD("Avg Heart Rate %.1f bpm", td->avg_hrt); - } - if (td->min_hrt < td->max_hrt) { - TD("Min Heart Rate %d bpm", td->min_hrt); - } - if (td->max_hrt) { - TD("Max Heart Rate %d bpm", td->max_hrt); - } - if (td->avg_cad) { - TD("Avg Cadence %.1f rpm", td->avg_cad); - } - if (td->max_cad) { - TD("Max Cadence %d rpm", td->max_cad); - } - if (td->start && td->end) { - char time_string[64]; - - xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); - TD("Start Time %s ", time_string); - xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); - TD("End Time %s ", time_string); - } - - kml_write_xml(-1, "]]>\n"); - kml_write_xml(-1, "\n"); - - /* We won't always have times. Garmin saved tracks, for example... */ - if (td->start && td->end) { - char time_string[64]; - kml_write_xml(1, "\n"); - xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); - kml_write_xml(0, "%s\n", time_string); - xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); - kml_write_xml(0, "%s\n", time_string); - kml_write_xml(-1, "\n"); - } + char* max_alt_units; + double max_alt; + char* min_alt_units; + double min_alt; + char* distance_units; + double distance; + + if (!td || !trackdata) { + return; + } + + max_alt = fmt_altitude(td->max_alt, &max_alt_units); + min_alt = fmt_altitude(td->min_alt, &min_alt_units); + distance = fmt_distance(td->distance_meters, &distance_units); + + kml_write_xml(0, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(1, "\n"); + + if (header->rte_desc) { + TD("Description %s", header->rte_desc); + } + TD2("Distance %.1f %s", distance, distance_units); + if (td->min_alt != -unknown_alt) { + TD2("Min Alt %.3f %s", min_alt, min_alt_units); + } + if (td->max_alt != unknown_alt) { + TD2("Max Alt %.3f %s", max_alt, max_alt_units); + } + if (td->min_spd) { + char* spd_units; + double spd = fmt_speed(td->min_spd, &spd_units); + TD2("Min Speed %.1f %s", spd, spd_units); + } + if (td->max_spd) { + char* spd_units; + double spd = fmt_speed(td->max_spd, &spd_units); + TD2("Max Speed %.1f %s", spd, spd_units); + } + if (td->max_spd && td->start && td->end) { + char* spd_units; + time_t elapsed = td->end - td->start; + double spd = fmt_speed(td->distance_meters / elapsed, &spd_units); + if (spd > 1.0) { + TD2("Avg Speed %.1f %s", spd, spd_units); + } + } + if (td->avg_hrt) { + TD("Avg Heart Rate %.1f bpm", td->avg_hrt); + } + if (td->min_hrt < td->max_hrt) { + TD("Min Heart Rate %d bpm", td->min_hrt); + } + if (td->max_hrt) { + TD("Max Heart Rate %d bpm", td->max_hrt); + } + if (td->avg_cad) { + TD("Avg Cadence %.1f rpm", td->avg_cad); + } + if (td->max_cad) { + TD("Max Cadence %d rpm", td->max_cad); + } + if (td->start && td->end) { + char time_string[64]; + + xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); + TD("Start Time %s ", time_string); + xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); + TD("End Time %s ", time_string); + } + + kml_write_xml(-1, "]]>\n"); + kml_write_xml(-1, "\n"); + + /* We won't always have times. Garmin saved tracks, for example... */ + if (td->start && td->end) { + char time_string[64]; + kml_write_xml(1, "\n"); + xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); + kml_write_xml(0, "%s\n", time_string); + xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); + kml_write_xml(0, "%s\n", time_string); + kml_write_xml(-1, "\n"); + } } static -void kml_output_header(const route_head *header, computed_trkdata*td) +void kml_output_header(const route_head* header, computed_trkdata* td) { - if (!realtime_positioning) { - kml_write_xml(1, "\n"); - } - kml_write_xmle("name", header->rte_name); - kml_output_trkdescription(header, td); - - if (export_points && header->rte_waypt_ct > 0) { - // Put the points in a subfolder - kml_write_xml(1, "\n"); - kml_write_xml(0, "Points\n"); - } + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + } + kml_write_xmle("name", header->rte_name); + kml_output_trkdescription(header, td); + + if (export_points && header->rte_waypt_ct > 0) { + // Put the points in a subfolder + kml_write_xml(1, "\n"); + kml_write_xml(0, "Points\n"); + } } static -int kml_altitude_known(const waypoint *waypoint) +int kml_altitude_known(const waypoint* waypoint) { - if (waypoint->altitude == unknown_alt) { - return 0; - } - // We see way more data that's sourceed at 'zero' than is actually - // precisely at 0 MSL. - if (fabs(waypoint->altitude) < .01) { - return 0; - } - return 1; + if (waypoint->altitude == unknown_alt) { + return 0; + } + // We see way more data that's sourceed at 'zero' than is actually + // precisely at 0 MSL. + if (fabs(waypoint->altitude) < .01) { + return 0; + } + return 1; } static -void kml_write_coordinates(const waypoint *waypointp) +void kml_write_coordinates(const waypoint* waypointp) { - if (kml_altitude_known(waypointp)) { - kml_write_xml(0, "" - COORD_FORMAT "," COORD_FORMAT "," ALT_FORMAT - "\n", - waypointp->longitude, - waypointp->latitude, - waypointp->altitude); - } else { - kml_write_xml(0, "" - COORD_FORMAT "," COORD_FORMAT - "\n", - waypointp->longitude, - waypointp->latitude); - } + if (kml_altitude_known(waypointp)) { + kml_write_xml(0, "" + COORD_FORMAT "," COORD_FORMAT "," ALT_FORMAT + "\n", + waypointp->longitude, + waypointp->latitude, + waypointp->altitude); + } else { + kml_write_xml(0, "" + COORD_FORMAT "," COORD_FORMAT + "\n", + waypointp->longitude, + waypointp->latitude); + } } /* Rather than a default "top down" view, view from the side to highlight * topo features. */ -static void kml_output_lookat(const waypoint *waypointp) +static void kml_output_lookat(const waypoint* waypointp) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "%f\n", waypointp->longitude); - kml_write_xml(0, "%f\n", waypointp->latitude); - kml_write_xml(0, "66\n"); - kml_write_xml(-1, "\n"); + kml_write_xml(1, "\n"); + kml_write_xml(0, "%f\n", waypointp->longitude); + kml_write_xml(0, "%f\n", waypointp->latitude); + kml_write_xml(0, "66\n"); + kml_write_xml(-1, "\n"); } static void kml_output_positioning(void) { - if (floating) { - kml_write_xml(0, "absolute\n"); - } + if (floating) { + kml_write_xml(0, "absolute\n"); + } - if (extrude) { - kml_write_xml(0, "1\n"); - } + if (extrude) { + kml_write_xml(0, "1\n"); + } } /* Output something interesing when we can for route and trackpoints */ -static void kml_output_description(const waypoint *pt) +static void kml_output_description(const waypoint* pt) { - char *alt_units; - double alt; - - if (!trackdata) { - return; - } - - alt = fmt_distance(pt->altitude, &alt_units); - - kml_write_xml(1, "\n"); - - TD("Longitude: %f", pt->longitude); - TD("Latitude: %f", pt->latitude); - if (kml_altitude_known(pt)) TD2("Altitude: %.3f %s", alt, alt_units); - if (pt->heartrate) TD("Heart rate: %d", pt->heartrate); - if (pt->cadence) TD("Cadence: %d", pt->cadence); - /* Which unit is this temp in? C? F? K? */ - if WAYPT_HAS(pt, temperature) TD("Temperature: %.1f", pt->temperature); - if WAYPT_HAS(pt, depth) { - char *depth_units; - double depth = fmt_distance(pt->depth, &depth_units); - TD2("Depth: %.1f %s", depth, depth_units); - } - if WAYPT_HAS(pt, speed) { - char *spd_units; - double spd = fmt_speed(pt->speed, &spd_units); - TD2("Speed: %.1f %s", spd, spd_units); - } - if WAYPT_HAS(pt, course) TD("Heading: %.1f", pt->course); - /* This really shouldn't be here, but as of this writing, - * Earth can't edit/display the TimeStamp. - */ - if (pt->creation_time) { - char time_string[64]; - - xml_fill_in_time(time_string, pt->creation_time, - pt->microseconds, XML_LONG_TIME); - if (time_string[0]) { - TD("Time: %s", time_string); - } - } - - kml_write_xml(-1, "\n"); - kml_write_xml(-1, "]]>\n"); + char* alt_units; + double alt; + + if (!trackdata) { + return; + } + + alt = fmt_altitude(pt->altitude, &alt_units); + + kml_write_xml(1, "\n"); + + TD("Longitude: %f", pt->longitude); + TD("Latitude: %f", pt->latitude); + if (kml_altitude_known(pt)) { + TD2("Altitude: %.3f %s", alt, alt_units); + } + if (pt->heartrate) { + TD("Heart rate: %d", pt->heartrate); + } + if (pt->cadence) { + TD("Cadence: %d", pt->cadence); + } + /* Which unit is this temp in? C? F? K? */ + if WAYPT_HAS(pt, temperature) { + TD("Temperature: %.1f", pt->temperature); + } + if WAYPT_HAS(pt, depth) { + char* depth_units; + double depth = fmt_distance(pt->depth, &depth_units); + TD2("Depth: %.1f %s", depth, depth_units); + } + if WAYPT_HAS(pt, speed) { + char* spd_units; + double spd = fmt_speed(pt->speed, &spd_units); + TD2("Speed: %.1f %s", spd, spd_units); + } + if WAYPT_HAS(pt, course) { + TD("Heading: %.1f", pt->course); + } + /* This really shouldn't be here, but as of this writing, + * Earth can't edit/display the TimeStamp. + */ + if (pt->creation_time) { + char time_string[64]; + + xml_fill_in_time(time_string, pt->creation_time, + pt->microseconds, XML_LONG_TIME); + if (time_string[0]) { + TD("Time: %s", time_string); + } + } + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "]]>\n"); } -static void kml_recompute_time_bounds(const waypoint *waypointp) { +static void kml_recompute_time_bounds(const waypoint* waypointp) +{ if (waypointp->creation_time && (waypointp->creation_time < kml_time_min)) { kml_time_min = waypointp->creation_time; } @@ -770,73 +846,89 @@ static void kml_recompute_time_bounds(const waypoint *waypointp) { } } -static void kml_output_point(const waypoint *waypointp, kml_point_type pt_type) { - const char *style; - +static void kml_add_to_bounds(const waypoint* waypointp) +{ waypt_add_to_bounds(&kml_bounds, waypointp); kml_recompute_time_bounds(waypointp); +} + +static void kml_output_point(const waypoint* waypointp, kml_point_type pt_type) +{ + const char* style; switch (pt_type) { - case kmlpt_track: style = "#track"; break; - case kmlpt_route: style = "#route"; break; - default: fatal("kml_output_point: unknown point type"); break; + case kmlpt_track: + style = "#track"; + break; + case kmlpt_route: + style = "#route"; + break; + default: + fatal("kml_output_point: unknown point type"); + break; } switch (pt_type) { - case kmlpt_track: style = "#track"; break; - case kmlpt_route: style = "#route"; break; - default: fatal("kml_output_point: unknown point type"); break; + case kmlpt_track: + style = "#track"; + break; + case kmlpt_route: + style = "#route"; + break; + default: + fatal("kml_output_point: unknown point type"); + break; } if (export_points) { - kml_write_xml(1, "\n"); - if (atoi(opt_labels)) { - kml_write_xmle("name", waypointp->shortname); - } - kml_write_xml(0, "\n"); - kml_output_description(waypointp); - kml_output_lookat(waypointp); - kml_output_timestamp(waypointp); - - - if (opt_deficon) { - kml_write_xml(1, "\n"); - } else { - if (trackdirection && (pt_type == kmlpt_track)) { - char buf[100]; - if (waypointp->speed < 1) - snprintf(buf, sizeof(buf), "%s-none", style); - else - snprintf(buf, sizeof(buf), "%s-%d", style, - (int) (waypointp->course / 22.5 + .5) % 16); - kml_write_xml(0, "%s\n", buf); - } else { - kml_write_xml(0, "%s\n", style); - } - } + kml_write_xml(1, "\n"); + if (atoi(opt_labels)) { + kml_write_xmle("name", waypointp->shortname); + } + kml_write_xml(0, "\n"); + kml_output_description(waypointp); + kml_output_lookat(waypointp); + kml_output_timestamp(waypointp); - kml_write_xml(1, "\n"); - kml_output_positioning(); - if (extrude) { - kml_write_xml(0, "1\n"); - } - kml_write_coordinates(waypointp); - kml_write_xml(-1, "\n"); + if (opt_deficon) { + kml_write_xml(1, "\n"); + } else { + if (trackdirection && (pt_type == kmlpt_track)) { + char buf[100]; + if (waypointp->speed < 1) { + snprintf(buf, sizeof(buf), "%s-none", style); + } else + snprintf(buf, sizeof(buf), "%s-%d", style, + (int)(waypointp->course / 22.5 + .5) % 16); + kml_write_xml(0, "%s\n", buf); + } else { + kml_write_xml(0, "%s\n", style); + } + } + + kml_write_xml(1, "\n"); + kml_output_positioning(); - kml_write_xml(-1, "\n"); + if (extrude) { + kml_write_xml(0, "1\n"); + } + kml_write_coordinates(waypointp); + kml_write_xml(-1, "\n"); + + kml_write_xml(-1, "\n"); } } -static void kml_output_tailer(const route_head *header) +static void kml_output_tailer(const route_head* header) { - queue *elem, *tmp; + queue* elem, *tmp; if (export_points && header->rte_waypt_ct > 0) { kml_write_xml(-1, "\n"); @@ -846,12 +938,12 @@ static void kml_output_tailer(const route_head *header) if (export_lines && header->rte_waypt_ct > 0) { int needs_multigeometry = 0; QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) { - waypoint *tpt = (waypoint *) elem; + waypoint* tpt = (waypoint*) elem; int first_in_trk = tpt->Q.prev == &header->waypoint_list; if (!first_in_trk && tpt->wpt_flags.new_trkseg) { needs_multigeometry = 1; break; - } + } } kml_write_xml(1, "\n"); kml_write_xml(0, "Path\n"); @@ -862,19 +954,21 @@ static void kml_output_tailer(const route_head *header) if (header->line_color.bbggrr >= 0) kml_write_xml(0, "%02x%06x\n", header->line_color.opacity, header->line_color.bbggrr); - if (header->line_width >= 0) + if (header->line_width >= 0) { kml_write_xml(0, "%d\n",header->line_width); + } kml_write_xml(-1, "\n"); kml_write_xml(-1, "\n"); } - if (needs_multigeometry) + if (needs_multigeometry) { kml_write_xml(1, "\n"); + } QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) { - waypoint *tpt = (waypoint *) elem; + waypoint* tpt = (waypoint*) elem; int first_in_trk = tpt->Q.prev == &header->waypoint_list; if (tpt->wpt_flags.new_trkseg) { - if(!first_in_trk) { + if (!first_in_trk) { kml_write_xml(-1, "\n"); kml_write_xml(-1, "\n"); } @@ -885,23 +979,18 @@ static void kml_output_tailer(const route_head *header) } if (kml_altitude_known(tpt)) { kml_write_xml(0, COORD_FORMAT "," COORD_FORMAT "," ALT_FORMAT "\n", - tpt->longitude, tpt->latitude, tpt->altitude); - } else { - kml_write_xml(0, COORD_FORMAT "," COORD_FORMAT "\n", - tpt->longitude, - tpt->latitude); - } - if (kml_altitude_known(tpt)) { - kml_write_xml(0, "%f,%f,%f\n", tpt->longitude, tpt->latitude, - tpt->altitude); - } else { - kml_write_xml(0, "%f,%f\n", tpt->longitude, tpt->latitude); - } + tpt->longitude, tpt->latitude, tpt->altitude); + } else { + kml_write_xml(0, COORD_FORMAT "," COORD_FORMAT "\n", + tpt->longitude, + tpt->latitude); + } } kml_write_xml(-1, "\n"); kml_write_xml(-1, "\n"); - if (needs_multigeometry) + if (needs_multigeometry) { kml_write_xml(-1, "\n"); + } kml_write_xml(-1, "\n"); } @@ -913,266 +1002,531 @@ static void kml_output_tailer(const route_head *header) /* * Completely different writer for geocaches. */ + +// Text that's common to all tabs. +static +void kml_gc_all_tabs_text(void) +{ + // kml_write_xml(0, " \n"); + kml_write_xml(0, "\n"); + kml_write_xml(0, "$[gc_num] $[gc_name] \n"); + kml_write_xml(0, "a $[gc_type],
on $[gc_placed] by $[gc_placer]
\n"); + kml_write_xml(0, "Difficulty: \"$[gc_diff]\"\n"); + kml_write_xml(0, " Terrain: \"$[gc_terr]\"
\n"); + kml_write_xml(0, "Size: \"$[gc_cont_icon]\"/ ($[gc_cont_icon])
\n"); + +} + +const char* map_templates[] = { + "Google Maps", + "Google Street View", + "Geocaching.com Google Map", + "MyTopo Maps", + "MapQuest", + "Bing Maps", + "Yahoo Maps", + "Rand McNally", + "MSR Maps (Formerly Terraserver)", + "Open Cycle Maps", + "Open Street Maps", + NULL +}; + + static -void kml_gc_make_ballonstyle(void) +void kml_gc_make_balloonstyletext(void) { - // BalloonStyle for Geocaches. - kml_write_xml(1, "\n"); + const char** tp; + kml_write_xml(1, "\n"); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + + kml_write_xml(0, "\n"); + kml_write_xml(0, "
\n"); + + // The tabbed menu bar. Oddly, it has to be on top. + kml_write_xml(1, "
    \n"); + kml_write_xml(0, "
  • Description
  • \n"); + kml_write_xml(0, "
  • Logs
  • \n"); + kml_write_xml(0, "
  • Extras
  • \n"); + kml_write_xml(-1, "
\n"); + kml_write_xml(0, "\n"); + + kml_write_xml(1, "
\n"); + kml_gc_all_tabs_text(); + kml_write_xml(0, "

$[gc_issues]\n"); + kml_write_xml(0, "$[gc_short_desc]\n"); + kml_write_xml(0, "$[gc_long_desc]\n"); + kml_write_xml(-1, "

\n"); + + kml_write_xml(1, "
\n"); + kml_gc_all_tabs_text(); + kml_write_xml(0, "$[gc_logs]\n"); + kml_write_xml(-1, "
\n"); + + // "Extra" stuff tab. + kml_write_xml(1, "
\n"); + kml_gc_all_tabs_text(); + kml_write_xml(0, "

Extra Maps

\n"); + + kml_write_xml(1, "
    \n"); + // Fortunately, all the mappy map URLs take lat/longs in the URLs, so + // the substition is easy. + for (tp = map_templates; *tp; tp++) { + kml_write_xml(0, "
  • \n"); + kml_write_xml(0, *tp); + kml_write_xml(0, "
  • \n"); + } + kml_write_xml(-1, "
      \n"); + + kml_write_xml(-1, "
\n"); // fragment-3. + + kml_write_xml(0, "
\n"); // tabs. + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + + kml_write_xml(-1, "]]>
\n"); } static -char * -kml_lookup_gc_icon(const waypoint *waypointp) +void kml_gc_make_balloonstyle(void) { - const char *icon; - char *rb; - - /* This could be done so much better in C99 with designated - * initializers... - */ - switch (waypointp->gc_data->type) { - case gt_traditional: icon = "2.png"; break; - case gt_multi: icon = "3.png"; break; - case gt_virtual: icon = "4.png"; break; - case gt_letterbox: icon = "5.png"; break; - case gt_event: icon = "6.png"; break; - case gt_ape: icon = "7.png"; break; - case gt_locationless: icon = "8.png"; break; // No unique icon. - case gt_suprise: icon = "8.png"; break; - case gt_webcam: icon = "11.png"; break; - case gt_cito: icon = "13.png"; break; - case gt_earth: icon = "earthcache.png"; break; - case gt_mega: icon = "453.png"; break; - case gt_wherigo: icon = "1858.png"; break; - default: icon = "8.png"; break; - } - - xasprintf(&rb, "http://www.geocaching.com/images/kml/%s", icon); - return rb; + // For Normal style of gecoaches, scale of label is set to zero + // to make the label invisible. On hover (highlight?) enlarge + // the icon sightly and set the scale of the label to 1 so the + // label pops. + // It's unfortunate that we have to repeat so much of the template + // but KML doesn't have a cascading style-like substance. + // + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(0, "normal\n"); + kml_write_xml(0, "#geocache_n\n"); + kml_write_xml(-1, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(0, "highlight\n"); + kml_write_xml(0, "#geocache_h\n"); + kml_write_xml(-1, "\n"); + + kml_write_xml(-1, "\n"); +} + +static +char* +kml_lookup_gc_icon(const waypoint* waypointp) +{ + const char* icon; + char* rb; + + /* This could be done so much better in C99 with designated + * initializers... + */ + switch (waypointp->gc_data->type) { + case gt_traditional: + icon = "2.png"; + break; + case gt_multi: + icon = "3.png"; + break; + case gt_virtual: + icon = "4.png"; + break; + case gt_letterbox: + icon = "5.png"; + break; + case gt_event: + icon = "6.png"; + break; + case gt_ape: + icon = "7.png"; + break; + case gt_locationless: + icon = "8.png"; + break; // No unique icon. + case gt_suprise: + icon = "8.png"; + break; + case gt_webcam: + icon = "11.png"; + break; + case gt_cito: + icon = "13.png"; + break; + case gt_earth: + icon = "earthcache.png"; + break; + case gt_mega: + icon = "453.png"; + break; + case gt_wherigo: + icon = "1858.png"; + break; + default: + icon = "8.png"; + break; + } + + xasprintf(&rb, "http://www.geocaching.com/images/kml/%s", icon); + return rb; } static const -char * -kml_lookup_gc_container(const waypoint *waypointp) +char* +kml_lookup_gc_container(const waypoint* waypointp) { - const char *cont; - - switch (waypointp->gc_data->container) { - case gc_micro: cont="micro"; break; - case gc_regular: cont="regular"; break; - case gc_large: cont="large"; break; - case gc_small: cont="small"; break; - case gc_virtual: cont="virtual"; break; - case gc_other: cont="other"; break; - default: cont="not_chosen"; break; - } - - return cont; + const char* cont; + + switch (waypointp->gc_data->container) { + case gc_micro: + cont="micro"; + break; + case gc_regular: + cont="regular"; + break; + case gc_large: + cont="large"; + break; + case gc_small: + cont="small"; + break; + case gc_virtual: + cont="virtual"; + break; + case gc_other: + cont="other"; + break; + default: + cont="not_chosen"; + break; + } + + return cont; } // Not thread safe. Return strings are small and it's silly to xasprintf/free // them so we use a static buffer. -char * kml_gc_mkstar(int rating) +char* kml_gc_mkstar(int rating) +{ + static char tmp[40]; + + if (rating < 0 || rating > 50 || rating % 5 != 0) { + fatal("Bogus difficulty or terrain rating."); + } + + if (0 == rating % 10) { + snprintf(tmp, sizeof(tmp), "stars%d", rating / 10); + } else { + snprintf(tmp, sizeof(tmp), "stars%d_%d", rating / 10, rating % 10); + } + + return tmp; +} + +// Returns an allocated buffer that must be freed. +char* kml_geocache_get_logs(const waypoint* wpt) { - static char tmp[40]; - if (0 == rating % 10) { - snprintf(tmp, sizeof(tmp), "stars%d", rating / 10); - } else { - snprintf(tmp, sizeof(tmp), "stars%d_%d", rating / 10, rating % 10); - } - - return tmp; + char* r = xstrdup(""); + + fs_xml* fs_gpx = (fs_xml*)fs_chain_find(wpt->fs, FS_GPX); + xml_tag* root = NULL; + xml_tag* curlog = NULL; + xml_tag* logpart = NULL; + + if (!fs_gpx) { + return r; + } + + root = fs_gpx->tag; + curlog = xml_findfirst(root, "groundspeak:log"); + while (curlog) { + time_t logtime = 0; + struct tm* logtm = NULL; + + // Unless we have a broken GPX input, these logparts + // branches will always be taken. + logpart = xml_findfirst(curlog, "groundspeak:type"); + if (logpart) { + r = xstrappend(r, "

"); + r = xstrappend(r, logpart->cdata); + r = xstrappend(r, ""); + } + + logpart = xml_findfirst(curlog, "groundspeak:finder"); + if (logpart) { + r = xstrappend(r, " by "); + r = xstrappend(r, logpart->cdata); + // xfree( f ); + } + + logpart = xml_findfirst(curlog, "groundspeak:date"); + if (logpart) { + logtime = xml_parse_time(logpart->cdata, NULL); + logtm = localtime(&logtime); + if (logtm) { + char* temp; + xasprintf(&temp, + " %04d-%02d-%02d", + logtm->tm_year+1900, + logtm->tm_mon+1, + logtm->tm_mday); + r = xstrappend(r, temp); + xfree(temp); + } + } + + logpart = xml_findfirst(curlog, "groundspeak:text"); + if (logpart) { + char* encstr = NULL; + char* s = NULL; + char* t = NULL; + int encoded = 0; + encstr = xml_attribute(logpart, "encoded"); + encoded = (toupper(encstr[0]) != 'F'); + + if (html_encrypt && encoded) { + s = rot13(logpart->cdata); + } else { + s = xstrdup(logpart->cdata); + } + + r = xstrappend(r, "
"); + t = html_entitize(s); + r = xstrappend(r, t); + xfree(t); + xfree(s); + } + + r = xstrappend(r, "

"); + curlog = xml_findnext(root, curlog, "groundspeak:log"); + } + return r; } -static void kml_geocache_pr(const waypoint *waypointp) +static void kml_geocache_pr(const waypoint* waypointp) { - char *p, *is; - - kml_write_xml(1, "\n"); - - kml_write_xml(1, "\n"); - kml_write_xml(0, "\n", waypointp->url_link_text); - kml_write_xml(-1, "\n"); - - // Timestamp - kml_output_timestamp(waypointp); - - kml_write_xml(0, "#geocache\n"); - is = kml_lookup_gc_icon(waypointp); - kml_write_xml(1, "\n"); - - kml_write_xml(1, "\n"); - - if (waypointp->shortname) { - p = xml_entitize(waypointp->shortname); - kml_write_xml(0, "%s\n", p); - xfree(p); - } - - if (waypointp->url_link_text) { - p = xml_entitize(waypointp->url_link_text); - kml_write_xml(0, "%s\n", p); - xfree(p); - } - - if (waypointp->gc_data->placer) { - p = xml_entitize(waypointp->gc_data->placer); - kml_write_xml(0, "%s\n", p); - xfree(p); - } - - kml_write_xml(0, "%d\n", waypointp->gc_data->placer_id); - - kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data->diff)); - kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data->terr)); - - kml_write_xml(0, "%s\n", kml_lookup_gc_container(waypointp)); - - // Highlight any issues with the cache, such as temp unavail - // or archived. - kml_write_xml(0, ""); - if (waypointp->gc_data->is_archived == status_true) { - kml_write_xml(0, "<font color=\"red\">This cache has been archived.</font><br/>\n"); - } else if (waypointp->gc_data->is_available == status_false) { - kml_write_xml(0, "<font color=\"red\">This cache is temporarily unavailable.</font><br/>\n"); - } - kml_write_xml(0, "\n"); - - kml_write_xml(0, "%s\n", gs_get_cachetype(waypointp->gc_data->type)); - kml_write_xml(0, "\n", waypointp->gc_data->desc_short.utfstring ? waypointp->gc_data->desc_short.utfstring : ""); - kml_write_xml(0, "\n", waypointp->gc_data->desc_long.utfstring ? waypointp->gc_data->desc_long.utfstring : ""); - - kml_write_xml(-1, "\n"); - - // Location - kml_write_xml(1, "\n"); - kml_write_coordinates(waypointp); - - kml_write_xml(-1, "\n"); - kml_write_xml(-1, "\n"); - - xfree(is); + char* p, *is; + char date_placed[100]; // Always long engough for a date. + + const char* issues = ""; + char* logs; + + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(0, "\n", waypointp->url_link_text); + kml_write_xml(-1, "\n"); + + // Timestamp + kml_output_timestamp(waypointp); + if (waypointp->creation_time) { + strftime(date_placed, sizeof(date_placed), + "%d-%b-%Y", localtime(&waypointp->creation_time)); + } else { + date_placed[0] = '\0'; + } + + kml_write_xml(0, "#geocache\n"); + is = kml_lookup_gc_icon(waypointp); + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + + if (waypointp->shortname) { + p = xml_entitize(waypointp->shortname); + kml_write_xml(0, "%s\n", p); + xfree(p); + } + + if (waypointp->url_link_text) { + p = xml_entitize(waypointp->url_link_text); + kml_write_xml(0, "%s\n", p); + xfree(p); + } + + if (waypointp->gc_data->placer) { + p = xml_entitize(waypointp->gc_data->placer); + kml_write_xml(0, "%s\n", p); + xfree(p); + } + + kml_write_xml(0, "%d\n", waypointp->gc_data->placer_id); + kml_write_xml(0, "%s\n", date_placed); + + kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data->diff)); + kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data->terr)); + + kml_write_xml(0, "%s\n", kml_lookup_gc_container(waypointp)); + + // Highlight any issues with the cache, such as temp unavail + // or archived. + if (waypointp->gc_data->is_archived == status_true) { + issues = "<font color=\"red\">This cache has been archived.</font><br/>\n"; + } else if (waypointp->gc_data->is_available == status_false) { + issues = "<font color=\"red\">This cache is temporarily unavailable.</font><br/>\n"; + } + kml_write_xml(0, "%s\n", issues); + + kml_write_xml(0, "%f\n", waypointp->latitude); + kml_write_xml(0, "%f\n", waypointp->longitude); + + kml_write_xml(0, "%s\n", gs_get_cachetype(waypointp->gc_data->type)); + kml_write_xml(0, "%s\n", is); + kml_write_xml(0, "\n", waypointp->gc_data->desc_short.utfstring ? waypointp->gc_data->desc_short.utfstring : ""); + kml_write_xml(0, "\n", waypointp->gc_data->desc_long.utfstring ? waypointp->gc_data->desc_long.utfstring : ""); + logs = kml_geocache_get_logs(waypointp); + kml_write_xml(0, "\n", logs); + xfree(logs); + + kml_write_xml(-1, "\n"); + + // Location + kml_write_xml(1, "\n"); + kml_write_coordinates(waypointp); + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); + + xfree(is); } /* * WAYPOINTS */ -static void kml_waypt_pr(const waypoint *waypointp) +static void kml_waypt_pr(const waypoint* waypointp) { - const char *icon; + const char* icon; #if 0 // Experimental - if(realtime_positioning) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "%f\n", waypointp->longitude); - kml_write_xml(0, "%f\n", waypointp->latitude); - kml_write_xml(0, "1000\n"); - kml_write_xml(-1, "\n"); - } + if (realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "%f\n", waypointp->longitude); + kml_write_xml(0, "%f\n", waypointp->latitude); + kml_write_xml(0, "1000\n"); + kml_write_xml(-1, "\n"); + } #endif - waypt_add_to_bounds(&kml_bounds, waypointp); - kml_recompute_time_bounds(waypointp); - - if (waypointp->gc_data->diff && waypointp->gc_data->terr) { - kml_geocache_pr(waypointp); - return; - } - - kml_write_xml(1, "\n"); - - kml_write_xmle("name", waypointp->shortname); - - // Description - if (waypointp->url && waypointp->url[0]) { - char * odesc = xml_entitize(waypointp->url); - kml_write_xml(0, "\n"); - kml_write_xml(0, "\n"); - if (waypointp->url_link_text && waypointp->url_link_text[0]) { - char *olink = xml_entitize(waypointp->url_link_text); - kml_write_xml(0, "%s]]>", odesc, olink); - xfree(olink); - } else { - gbfputs(odesc, ofd); - } - - kml_write_xml(0, "\n"); - xfree(odesc); - } else { - if (strcmp(waypointp->shortname, waypointp->description)) - kml_write_xmle("description", waypointp->description); - } - - // Timestamp - kml_output_timestamp(waypointp); - - // Icon - but only if it looks like a URL. - icon = opt_deficon ? opt_deficon : waypointp->icon_descr; - if (icon && strstr(icon, "://")) { - kml_write_xml(1, "\n"); - } else { - kml_write_xml(0, "#waypoint\n"); - } - - // Location - kml_write_xml(1, "\n"); - kml_output_positioning(); - kml_write_coordinates(waypointp); - kml_write_xml(-1, "\n"); - - kml_write_xml(-1, "\n"); + + if (waypointp->gc_data->diff && waypointp->gc_data->terr) { + kml_geocache_pr(waypointp); + return; + } + + kml_write_xml(1, "\n"); + + kml_write_xmle("name", waypointp->shortname); + + // Description + if (waypointp->url && waypointp->url[0]) { + char* odesc = xml_entitize(waypointp->url); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + if (waypointp->url_link_text && waypointp->url_link_text[0]) { + char* olink = xml_entitize(waypointp->url_link_text); + kml_write_xml(0, "%s]]>", odesc, olink); + xfree(olink); + } else { + gbfputs(odesc, ofd); + } + + kml_write_xml(0, "\n"); + xfree(odesc); + } else { + if (strcmp(waypointp->shortname, waypointp->description)) { + kml_write_xmle("description", waypointp->description); + } + } + + // Timestamp + kml_output_timestamp(waypointp); + + // Icon - but only if it looks like a URL. + icon = opt_deficon ? opt_deficon : waypointp->icon_descr; + if (icon && strstr(icon, "://")) { + kml_write_xml(1, "\n"); + } else { + kml_write_xml(0, "#waypoint\n"); + } + + // Location + kml_write_xml(1, "\n"); + kml_output_positioning(); + kml_write_coordinates(waypointp); + kml_write_xml(-1, "\n"); + + kml_write_xml(-1, "\n"); } /* * TRACKPOINTS */ -static void kml_track_hdr(const route_head *header) +static void kml_track_hdr(const route_head* header) { - computed_trkdata *td; - track_recompute(header, &td); - if (header->rte_waypt_ct > 0 && (export_lines || export_points)) { - kml_output_header(header, td); - } - xfree(td); + computed_trkdata* td; + track_recompute(header, &td); + if (header->rte_waypt_ct > 0 && (export_lines || export_points)) { + kml_output_header(header, td); + } + xfree(td); } -static void kml_track_disp(const waypoint *waypointp) +static void kml_track_disp(const waypoint* waypointp) { - kml_output_point(waypointp, kmlpt_track); + kml_output_point(waypointp, kmlpt_track); } -static void kml_track_tlr(const route_head *header) +static void kml_track_tlr(const route_head* header) { - if (header->rte_waypt_ct > 0 && (export_lines || export_points)) { - kml_output_tailer(header); - } + if (header->rte_waypt_ct > 0 && (export_lines || export_points)) { + kml_output_tailer(header); + } } /* @@ -1191,83 +1545,84 @@ typedef enum { sl_float, sl_double, } sl_element; -static void kml_mt_simple_array(const route_head *header, - const char *name, const char *fmt_string, +static void kml_mt_simple_array(const route_head* header, + const char* name, const char* fmt_string, int offset, sl_element type) { - queue *elem, *tmp; + queue* elem, *tmp; kml_write_xml(1, "\n", name); QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) { - char *datap = (char*) elem + offset; + char* datap = (char*) elem + offset; - switch(type) { - case sl_char: { - char data = *(char *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - case sl_uchar: { - unsigned char data = *(unsigned char *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - case sl_int: { - int data = *(int *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - case sl_float: { - float data = *(float *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - case sl_double: { - double data = *(double *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - default: - fatal(MYNAME ": invalid type passed to kml_mt_simple_array.\n"); + switch (type) { + case sl_char: { + char data = *(char*) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + case sl_uchar: { + unsigned char data = *(unsigned char*) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + case sl_int: { + int data = *(int*) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + case sl_float: { + float data = *(float*) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + case sl_double: { + double data = *(double*) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + default: + fatal(MYNAME ": invalid type passed to kml_mt_simple_array.\n"); } } kml_write_xml(-1, "\n"); } // True if at least two points in the track have timestamps. -static int track_has_time(const route_head *header) +static int track_has_time(const route_head* header) { - queue *elem, *tmp; + queue* elem, *tmp; int points_with_time = 0; QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) { - waypoint *tpt = (waypoint *)elem; + waypoint* tpt = (waypoint*)elem; if (tpt->creation_time) { points_with_time++; - if (points_with_time >= 2) + if (points_with_time >= 2) { return 1; + } } } return 0; } // Simulate a track_disp_all callback sequence for a single track. -static void write_as_linestring(const route_head *header) +static void write_as_linestring(const route_head* header) { - queue *elem, *tmp; + queue* elem, *tmp; kml_track_hdr(header); QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) { - waypoint *tpt = (waypoint *)elem; + waypoint* tpt = (waypoint*)elem; kml_track_disp(tpt); } kml_track_tlr(header); } -static void kml_mt_hdr(const route_head *header) +static void kml_mt_hdr(const route_head* header) { - queue *elem, *tmp; + queue* elem, *tmp; int has_cadence = 0; int has_depth = 0; int has_heartrate = 0; @@ -1289,16 +1644,13 @@ static void kml_mt_hdr(const route_head *header) QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) { char time_string[64]; - waypoint *tpt = (waypoint *)elem; + waypoint* tpt = (waypoint*)elem; - // Add it to our bounding box so our default LookAt/flyto does a good - // thing. - waypt_add_to_bounds(&kml_bounds, tpt); if (tpt->creation_time) { xml_fill_in_time(time_string, tpt->creation_time, tpt->microseconds, XML_LONG_TIME); if (time_string[0]) { - kml_write_xmle("when", time_string); + kml_write_xmle("when", time_string); } } else { kml_write_xml(0, "\n"); @@ -1307,31 +1659,36 @@ static void kml_mt_hdr(const route_head *header) // TODO: How to handle clamped, floating, extruded, etc.? QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) { - waypoint *tpt = (waypoint *)elem; + waypoint* tpt = (waypoint*)elem; if (kml_altitude_known(tpt)) { kml_write_xmle("gx:coord", COORD_FORMAT " " COORD_FORMAT " " ALT_FORMAT, - tpt->longitude, tpt->latitude,tpt->altitude); + tpt->longitude, tpt->latitude,tpt->altitude); } else { kml_write_xmle("gx:coord", COORD_FORMAT " " COORD_FORMAT, - tpt->longitude, tpt->latitude); + tpt->longitude, tpt->latitude); } // Capture interesting traits to see if we need to do an ExtendedData // section later. - if (tpt->cadence) + if (tpt->cadence) { has_cadence = 1; - if (WAYPT_HAS(tpt, depth)) + } + if (WAYPT_HAS(tpt, depth)) { has_depth = 1; - if (tpt->heartrate) + } + if (tpt->heartrate) { has_heartrate = 1; - if (WAYPT_HAS(tpt, temperature)) + } + if (WAYPT_HAS(tpt, temperature)) { has_temperature = 1; - if (tpt->power) + } + if (tpt->power) { has_power = 1; + } } - if (has_cadence || has_depth || has_heartrate || has_temperature || + if (has_cadence || has_depth || has_heartrate || has_temperature || has_power) { kml_write_xml(1, "\n"); kml_write_xml(1, "\n"); @@ -1361,7 +1718,7 @@ static void kml_mt_hdr(const route_head *header) } } -static void kml_mt_tlr(const route_head *header) +static void kml_mt_tlr(const route_head* header) { if (track_has_time(header)) { kml_write_xml(-1, "\n"); @@ -1373,27 +1730,39 @@ static void kml_mt_tlr(const route_head *header) * ROUTES */ -static void kml_route_hdr(const route_head *header) +static void kml_route_hdr(const route_head* header) { - kml_output_header(header, NULL); + kml_output_header(header, NULL); } -static void kml_route_disp(const waypoint *waypointp) +static void kml_route_disp(const waypoint* waypointp) { - kml_output_point(waypointp, kmlpt_route); + kml_output_point(waypointp, kmlpt_route); } -static void kml_route_tlr(const route_head *header) +static void kml_route_tlr(const route_head* header) { - kml_output_tailer(header); + kml_output_tailer(header); } -// For Earth 5.0, we write a LookAt that encompasses +// For Earth 5.0 and later, we write a LookAt that encompasses // the bounding box of our entire data set and set the event times // to include all our data. -void kml_write_AbstractView(void) { +void kml_write_AbstractView(void) +{ double bb_size; + // Make a pass through all the points to find the bounds. + if (waypt_count()) { + waypt_disp_all(kml_add_to_bounds); + } + if (track_waypt_count()) { + track_disp_all(NULL, NULL, kml_add_to_bounds); + } + if (route_waypt_count()) { + route_disp_all(NULL, NULL, kml_add_to_bounds); + } + kml_write_xml(1, "\n"); if (kml_time_min || kml_time_max) { @@ -1424,12 +1793,12 @@ void kml_write_AbstractView(void) { kml_write_xml(-1, "\n"); } - // If our BB spans the antemeridian, flip sign on one. - // This doesn't make our BB optimal, but it at least prevents us from - // zooming to the wrong hemisphere. - if (kml_bounds.min_lon * kml_bounds.max_lon < 0) { - kml_bounds.min_lon = -kml_bounds.max_lon; - } +// If our BB spans the antemeridian, flip sign on one. +// This doesn't make our BB optimal, but it at least prevents us from +// zooming to the wrong hemisphere. + if (kml_bounds.min_lon * kml_bounds.max_lon < 0) { + kml_bounds.min_lon = -kml_bounds.max_lon; + } kml_write_xml(0, "%f\n", (kml_bounds.min_lon + kml_bounds.max_lon) / 2); @@ -1439,7 +1808,7 @@ void kml_write_AbstractView(void) { // It turns out the length of the diagonal of the bounding box gives us a // reasonable guess for setting the camera altitude. bb_size = gcgeodist(kml_bounds.min_lat, kml_bounds.min_lon, - kml_bounds.max_lat, kml_bounds.max_lon); + kml_bounds.max_lat, kml_bounds.max_lon); // Clamp bottom zoom level. Otherwise, a single point zooms to grass. if (bb_size < 1000) { bb_size = 1000; @@ -1450,263 +1819,270 @@ void kml_write_AbstractView(void) { } static -void kml_mt_array_schema(const char *field_name, const char *display_name, - const char *type) +void kml_mt_array_schema(const char* field_name, const char* display_name, + const char* type) { - kml_write_xml(1, "\n", - field_name, type); - kml_write_xml(0, " %s\n", display_name); - kml_write_xml(-1, "\n"); + kml_write_xml(1, "\n", + field_name, type); + kml_write_xml(0, " %s\n", display_name); + kml_write_xml(-1, "\n"); } void kml_write(void) { - char import_time[100]; - time_t now; - const global_trait* traits = get_traits(); - - // Parse options - export_lines = (0 == strcmp("1", opt_export_lines)); - export_points = (0 == strcmp("1", opt_export_points)); - export_track = (0 == strcmp("1", opt_export_track)); - floating = (!! strcmp("0", opt_floating)); - extrude = (!! strcmp("0", opt_extrude)); - trackdata = (!! strcmp("0", opt_trackdata)); - trackdirection = (!! strcmp("0", opt_trackdirection)); - line_width = atol(opt_line_width); - - kml_write_xml(0, "\n"); - - kml_write_xml(1, kml22_hdr); - - kml_write_xml(1, "\n"); - - now = current_time(); - strftime(import_time, sizeof(import_time), "%c", localtime(&now)); - if (realtime_positioning) - kml_write_xml(0, "GPS position\n"); - else - kml_write_xml(0, "GPS device\n"); - - if (now) { - kml_write_xml(0, "Created %s\n", import_time); - } - - if(traits->trait_heartrate || - traits->trait_cadence || - traits->trait_power || - traits->trait_temperature || - traits->trait_depth) { - kml_write_xml(1, "\n"); - - if(traits->trait_heartrate) { - kml_mt_array_schema(kmt_heartrate, "Heart Rate", "int"); - } - if(traits->trait_cadence) { - kml_mt_array_schema(kmt_cadence, "Cadence", "int"); - } - if(traits->trait_power) { - kml_mt_array_schema(kmt_power, "Power", "float"); - } - if(traits->trait_temperature) { - kml_mt_array_schema(kmt_temperature, "Temperature", "float"); - } - if(traits->trait_depth) { - kml_mt_array_schema(kmt_depth, "Depth", "float"); - } - kml_write_xml(-1, "\n"); - } - - // Style settings for bitmaps - if (route_waypt_count()) { - kml_write_bitmap_style(kmlpt_route, ICON_RTE, NULL); - } - - if (track_waypt_count()) { - if (trackdirection) { - int i; - kml_write_bitmap_style(kmlpt_other, ICON_TRK, "track-none"); - for (i = 0; i < 16; i++) { - char buf1[100]; - char buf2[100]; - - sprintf(buf1, "track-%d", i); - sprintf(buf2, ICON_DIR, i); - kml_write_bitmap_style(kmlpt_other, buf2, buf1); - } - } else { - kml_write_bitmap_style(kmlpt_track, ICON_TRK, NULL); - } - if (export_track) - kml_write_bitmap_style(kmlpt_multitrack, ICON_MULTI_TRK, - "track-none"); - } - - kml_write_bitmap_style(kmlpt_waypoint, ICON_WPT, NULL); - - if (track_waypt_count() || route_waypt_count()) { - kml_write_xml(1, "\n"); - } - - if (traits->trait_geocaches) { - kml_gc_make_ballonstyle(); - } - if (waypt_count()) { - if (!realtime_positioning) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "Waypoints\n"); - } - - waypt_disp_all(kml_waypt_pr); - - if (!realtime_positioning) { - kml_write_xml(-1, "\n"); - } - } - - // Output trackpoints - if (track_waypt_count()) { - if (!realtime_positioning) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "Tracks\n"); - } - - if (export_track) - track_disp_all(kml_mt_hdr, kml_mt_tlr, NULL); - - track_disp_all(kml_track_hdr, kml_track_tlr, - kml_track_disp); - - if (!realtime_positioning) { - kml_write_xml(-1, "\n"); - } - } - - // Output routes - if (route_waypt_count()) { - if (!realtime_positioning) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "Routes\n"); - - route_disp_all(kml_route_hdr, - kml_route_tlr, kml_route_disp); - kml_write_xml(-1, "\n"); - } - } + char import_time[100]; + time_t now; + const global_trait* traits = get_traits(); + + // Parse options + export_lines = (0 == strcmp("1", opt_export_lines)); + export_points = (0 == strcmp("1", opt_export_points)); + export_track = (0 == strcmp("1", opt_export_track)); + floating = (!! strcmp("0", opt_floating)); + extrude = (!! strcmp("0", opt_extrude)); + trackdata = (!! strcmp("0", opt_trackdata)); + trackdirection = (!! strcmp("0", opt_trackdirection)); + line_width = atol(opt_line_width); + + kml_write_xml(0, "\n"); + + kml_write_xml(1, kml22_hdr); + + kml_write_xml(1, "\n"); + + now = current_time(); + strftime(import_time, sizeof(import_time), "%c", localtime(&now)); + if (realtime_positioning) { + kml_write_xml(0, "GPS position\n"); + } else { + kml_write_xml(0, "GPS device\n"); + } + + if (now) { + kml_write_xml(0, "Created %s\n", import_time); + } + + kml_write_AbstractView(); + + // Style settings for bitmaps + if (route_waypt_count()) { + kml_write_bitmap_style(kmlpt_route, ICON_RTE, NULL); + } - kml_write_AbstractView(); - kml_write_xml(-1, "\n"); - kml_write_xml(-1, "\n"); + if (track_waypt_count()) { + if (trackdirection) { + int i; + kml_write_bitmap_style(kmlpt_other, ICON_TRK, "track-none"); + for (i = 0; i < 16; i++) { + char buf1[100]; + char buf2[100]; + + sprintf(buf1, "track-%d", i); + sprintf(buf2, ICON_DIR, i); + kml_write_bitmap_style(kmlpt_other, buf2, buf1); + } + } else { + kml_write_bitmap_style(kmlpt_track, ICON_TRK, NULL); + } + if (export_track) + kml_write_bitmap_style(kmlpt_multitrack, ICON_MULTI_TRK, + "track-none"); + } + + kml_write_bitmap_style(kmlpt_waypoint, ICON_WPT, NULL); + + if (track_waypt_count() || route_waypt_count()) { + kml_write_xml(1, "\n"); + } + + if (traits->trait_geocaches) { + kml_gc_make_balloonstyle(); + } + + if (traits->trait_heartrate || + traits->trait_cadence || + traits->trait_power || + traits->trait_temperature || + traits->trait_depth) { + kml_write_xml(1, "\n"); + + if (traits->trait_heartrate) { + kml_mt_array_schema(kmt_heartrate, "Heart Rate", "int"); + } + if (traits->trait_cadence) { + kml_mt_array_schema(kmt_cadence, "Cadence", "int"); + } + if (traits->trait_power) { + kml_mt_array_schema(kmt_power, "Power", "float"); + } + if (traits->trait_temperature) { + kml_mt_array_schema(kmt_temperature, "Temperature", "float"); + } + if (traits->trait_depth) { + kml_mt_array_schema(kmt_depth, "Depth", "float"); + } + kml_write_xml(-1, "\n"); + } + + if (waypt_count()) { + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Waypoints\n"); + } + + waypt_disp_all(kml_waypt_pr); + + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } + } + + // Output trackpoints + if (track_waypt_count()) { + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Tracks\n"); + } + + if (export_track) { + track_disp_all(kml_mt_hdr, kml_mt_tlr, NULL); + } + + track_disp_all(kml_track_hdr, kml_track_tlr, + kml_track_disp); + + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } + } + + // Output routes + if (route_waypt_count()) { + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Routes\n"); + + route_disp_all(kml_route_hdr, + kml_route_tlr, kml_route_disp); + kml_write_xml(-1, "\n"); + } + } + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); } /* * This depends on the table being sorted correctly. */ static const -char * +char* kml_get_posn_icon(int freshness) { - int i; - int n_stations = sizeof(kml_tracking_icons) / sizeof(kml_tracking_icons[0]); - - for (i = 0; i < n_stations ; i++) { - if (freshness >= kml_tracking_icons[i].freshness) - return kml_tracking_icons[i].icon; - } - return ICON_NOSAT; + int i; + int n_stations = sizeof(kml_tracking_icons) / sizeof(kml_tracking_icons[0]); + + for (i = 0; i < n_stations ; i++) { + if (freshness >= kml_tracking_icons[i].freshness) { + return kml_tracking_icons[i].icon; + } + } + return ICON_NOSAT; } -static route_head *posn_trk_head = NULL; +static route_head* posn_trk_head = NULL; static void -kml_wr_position(waypoint *wpt) +kml_wr_position(waypoint* wpt) { - static time_t last_valid_fix; - - kml_wr_init(posnfilenametmp); - - if (!posn_trk_head) { - posn_trk_head = route_head_alloc(); - track_add_head(posn_trk_head); - } - - if (last_valid_fix == 0) last_valid_fix = current_time(); - - /* We want our waypoint to have a name, but not our trackpoint */ - if (!wpt->shortname) { - if (wpt->fix == fix_none) { - wpt->shortname = xstrdup("ESTIMATED Position"); - } else { - wpt->shortname = xstrdup("Position"); - } - } - - switch (wpt->fix) { - case fix_none: - if (wpt->shortname) { - xfree (wpt->shortname); - } - wpt->shortname = xstrdup("ESTIMATED Position"); - break; - case fix_unknown: - break; - default: - last_valid_fix = wpt->creation_time; - } - - wpt->icon_descr = kml_get_posn_icon(wpt->creation_time - last_valid_fix); - - - /* In order to avoid clutter while we're sitting still, don't add - track points if we've not moved a minimum distance from the - beginnning of our accumulated track. */ - { - waypoint *newest_posn= (waypoint *) QUEUE_LAST(&posn_trk_head->waypoint_list); - - if(radtometers(gcdist(RAD(wpt->latitude), RAD(wpt->longitude), - RAD(newest_posn->latitude), RAD(newest_posn->longitude))) > 50) { - track_add_wpt(posn_trk_head, waypt_dupe(wpt)); - } else { - /* If we haven't move more than our threshold, pretend - * we didn't move at all to prevent Earth from jittering - * the zoom levels on us. - */ - wpt->latitude = newest_posn->latitude; - wpt->longitude = newest_posn->longitude; - } - } - - waypt_add(wpt); - kml_write(); - waypt_del(wpt); - - /* - * If we are keeping only a recent subset of the trail, trim the - * head here. - */ - while (max_position_points && - (posn_trk_head->rte_waypt_ct >= max_position_points)) { - waypoint *tonuke = (waypoint *) QUEUE_FIRST(&posn_trk_head->waypoint_list); - track_del_wpt(posn_trk_head, tonuke); - } - - kml_wr_deinit(); + static time_t last_valid_fix; + + kml_wr_init(posnfilenametmp); + + if (!posn_trk_head) { + posn_trk_head = route_head_alloc(); + track_add_head(posn_trk_head); + } + + if (last_valid_fix == 0) { + last_valid_fix = current_time(); + } + + /* We want our waypoint to have a name, but not our trackpoint */ + if (!wpt->shortname) { + if (wpt->fix == fix_none) { + wpt->shortname = xstrdup("ESTIMATED Position"); + } else { + wpt->shortname = xstrdup("Position"); + } + } + + switch (wpt->fix) { + case fix_none: + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("ESTIMATED Position"); + break; + case fix_unknown: + break; + default: + last_valid_fix = wpt->creation_time; + } + + wpt->icon_descr = kml_get_posn_icon(wpt->creation_time - last_valid_fix); + + + /* In order to avoid clutter while we're sitting still, don't add + track points if we've not moved a minimum distance from the + beginnning of our accumulated track. */ + { + waypoint* newest_posn= (waypoint*) QUEUE_LAST(&posn_trk_head->waypoint_list); + + if (radtometers(gcdist(RAD(wpt->latitude), RAD(wpt->longitude), + RAD(newest_posn->latitude), RAD(newest_posn->longitude))) > 50) { + track_add_wpt(posn_trk_head, waypt_dupe(wpt)); + } else { + /* If we haven't move more than our threshold, pretend + * we didn't move at all to prevent Earth from jittering + * the zoom levels on us. + */ + wpt->latitude = newest_posn->latitude; + wpt->longitude = newest_posn->longitude; + } + } + + waypt_add(wpt); + kml_write(); + waypt_del(wpt); + + /* + * If we are keeping only a recent subset of the trail, trim the + * head here. + */ + while (max_position_points && + (posn_trk_head->rte_waypt_ct >= max_position_points)) { + waypoint* tonuke = (waypoint*) QUEUE_FIRST(&posn_trk_head->waypoint_list); + track_del_wpt(posn_trk_head, tonuke); + } + + kml_wr_deinit(); } ff_vecs_t kml_vecs = { - ff_type_file, - FF_CAP_RW_ALL, /* Format can do RW_ALL */ - kml_rd_init, - kml_wr_init, - kml_rd_deinit, - kml_wr_deinit, - kml_read, - kml_write, - NULL, - kml_args, - CET_CHARSET_UTF8, 1, /* CET-REVIEW */ - { NULL, NULL, NULL, kml_wr_position_init, kml_wr_position, kml_wr_position_deinit } + ff_type_file, + FF_CAP_RW_ALL, /* Format can do RW_ALL */ + kml_rd_init, + kml_wr_init, + kml_rd_deinit, + kml_wr_deinit, + kml_read, + kml_write, + NULL, + kml_args, + CET_CHARSET_UTF8, 1, /* CET-REVIEW */ + { NULL, NULL, NULL, kml_wr_position_init, kml_wr_position, kml_wr_position_deinit } }; diff --git a/gpsbabel/lmx.c b/gpsbabel/lmx.c index 84fd561ea..53d43eef7 100644 --- a/gpsbabel/lmx.c +++ b/gpsbabel/lmx.c @@ -29,19 +29,21 @@ #include "defs.h" #include "xmlgeneric.h" -static gbfile *ofd; -static waypoint *wpt_tmp; -char *urllink, *urllinkt; -static char *binary = NULL; +static gbfile* ofd; +static waypoint* wpt_tmp; +char* urllink, *urllinkt; +static char* binary = NULL; #define MYNAME "lmx" static arglist_t lmx_args[] = { - { "binary", &binary, - "Compact binary representation", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "binary", &binary, + "Compact binary representation", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /* @@ -50,192 +52,237 @@ arglist_t lmx_args[] = { static void -lmx_wr_init(const char *fname) +lmx_wr_init(const char* fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void lmx_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } -static char * +static char* lmx_stag(int tag) { - switch (tag) { - case 0xC5: return "lmx"; - case 0x46: return "landmarkCollection"; - case 0x47: return "landmark"; - case 0x48: return "name"; - case 0x49: return "description"; - case 0x4A: return "coordinates"; - case 0x4B: return "latitude"; - case 0x4C: return "longitude"; - case 0x4D: return "altitude"; - case 0x4E: return "horizontalAccuracy"; - case 0x4F: return "verticalAccuracy"; - case 0x50: return "timeStamp"; - case 0x51: return "coverageRadius"; - case 0x52: return "category"; - case 0x53: return "id"; - case 0x54: return "addressInfo"; - case 0x55: return "country"; - case 0x56: return "countryCode"; - case 0x57: return "state"; - case 0x58: return "county"; - case 0x59: return "city"; - case 0x5A: return "district"; - case 0x5B: return "postalCode"; - case 0x5C: return "crossing1"; - case 0x5D: return "crossing2"; - case 0x5E: return "street"; - case 0x5F: return "buildingName"; - case 0x60: return "buildingFloor"; - case 0x61: return "buildingZone"; - case 0x62: return "buildingRoom"; - case 0x63: return "extension"; - case 0x64: return "phoneNumber"; - case 0x65: return "mediaLink"; - case 0x66: return "mime"; - case 0x67: return "url"; - default: return 0; - } + switch (tag) { + case 0xC5: + return "lmx"; + case 0x46: + return "landmarkCollection"; + case 0x47: + return "landmark"; + case 0x48: + return "name"; + case 0x49: + return "description"; + case 0x4A: + return "coordinates"; + case 0x4B: + return "latitude"; + case 0x4C: + return "longitude"; + case 0x4D: + return "altitude"; + case 0x4E: + return "horizontalAccuracy"; + case 0x4F: + return "verticalAccuracy"; + case 0x50: + return "timeStamp"; + case 0x51: + return "coverageRadius"; + case 0x52: + return "category"; + case 0x53: + return "id"; + case 0x54: + return "addressInfo"; + case 0x55: + return "country"; + case 0x56: + return "countryCode"; + case 0x57: + return "state"; + case 0x58: + return "county"; + case 0x59: + return "city"; + case 0x5A: + return "district"; + case 0x5B: + return "postalCode"; + case 0x5C: + return "crossing1"; + case 0x5D: + return "crossing2"; + case 0x5E: + return "street"; + case 0x5F: + return "buildingName"; + case 0x60: + return "buildingFloor"; + case 0x61: + return "buildingZone"; + case 0x62: + return "buildingRoom"; + case 0x63: + return "extension"; + case 0x64: + return "phoneNumber"; + case 0x65: + return "mediaLink"; + case 0x66: + return "mime"; + case 0x67: + return "url"; + default: + return 0; + } } static void lmx_indent(int count) { - int i; - for (i=0; i", lmx_stag(tag)); - } + if (binary) { + gbfputc(tag, ofd); + } else { + lmx_indent(indent); + gbfprintf(ofd, "", lmx_stag(tag)); + } } static void lmx_end_tag(int tag, int indent) { - if (binary) - gbfputc(0x01, ofd); - else { - lmx_indent(indent); - gbfprintf(ofd, "\n", lmx_stag(tag)); - } + if (binary) { + gbfputc(0x01, ofd); + } else { + lmx_indent(indent); + gbfprintf(ofd, "\n", lmx_stag(tag)); + } } static void -lmx_write_xml(int tag, const char *data, int indent) +lmx_write_xml(int tag, const char* data, int indent) { - lmx_start_tag(tag, indent); - - if (binary) { - gbfputc(0x03, ofd); // inline string follows - gbfputcstr(data, ofd); - } - else { - char *tmp_ent = xml_entitize(data); - gbfputs(tmp_ent, ofd); - xfree(tmp_ent); - } - - lmx_end_tag(tag, 0); + lmx_start_tag(tag, indent); + + if (binary) { + gbfputc(0x03, ofd); // inline string follows + gbfputcstr(data, ofd); + } else { + char* tmp_ent = xml_entitize(data); + gbfputs(tmp_ent, ofd); + xfree(tmp_ent); + } + + lmx_end_tag(tag, 0); } static void -lmx_print(const waypoint *wpt) -{ - const char *oname; - char *odesc; - char tbuf[100]; - - /* - * Desparation time, try very hard to get a good shortname - */ - odesc = wpt->notes; - if (!odesc) { - odesc = wpt->description; - } - if (!odesc) { - odesc = wpt->shortname; - } - - oname = global_opts.synthesize_shortnames ? odesc : wpt->shortname; - - lmx_start_tag(0x47, 2); // landmark - if (!binary) gbfputc('\n', ofd); - if (oname) { - lmx_write_xml(0x48, oname, 3); // name - } - if (wpt->description) { - lmx_write_xml(0x49, wpt->description, 3); // description - } - lmx_start_tag(0x4A, 3); // coordinates - if (!binary) gbfputc('\n', ofd); - - sprintf(tbuf, "%f", wpt->latitude); - lmx_write_xml(0x4B, tbuf, 4); // latitude - - sprintf(tbuf, "%f", wpt->longitude); - lmx_write_xml(0x4C, tbuf, 4); // longitude - - if (wpt->altitude && (wpt->altitude != unknown_alt)) { - sprintf(tbuf, "%f", wpt->altitude); - lmx_write_xml(0x4D, tbuf, 4); // altitude - } - lmx_end_tag(0x4A, 3); // coordinates - - if (wpt->url && wpt->url[0]) { - lmx_start_tag(0x65, 3); // mediaLink - if (!binary) gbfputc('\n', ofd); - if (wpt->url_link_text) - lmx_write_xml(0x48, wpt->url_link_text, 4); // name - lmx_write_xml(0x67, wpt->url, 4); // url - lmx_end_tag(0x65, 3); // mediaLink - } - - lmx_end_tag(0x47, 2); // landmark +lmx_print(const waypoint* wpt) +{ + const char* oname; + char* odesc; + char tbuf[100]; + + /* + * Desparation time, try very hard to get a good shortname + */ + odesc = wpt->notes; + if (!odesc) { + odesc = wpt->description; + } + if (!odesc) { + odesc = wpt->shortname; + } + + oname = global_opts.synthesize_shortnames ? odesc : wpt->shortname; + + lmx_start_tag(0x47, 2); // landmark + if (!binary) { + gbfputc('\n', ofd); + } + if (oname) { + lmx_write_xml(0x48, oname, 3); // name + } + if (wpt->description) { + lmx_write_xml(0x49, wpt->description, 3); // description + } + lmx_start_tag(0x4A, 3); // coordinates + if (!binary) { + gbfputc('\n', ofd); + } + + sprintf(tbuf, "%f", wpt->latitude); + lmx_write_xml(0x4B, tbuf, 4); // latitude + + sprintf(tbuf, "%f", wpt->longitude); + lmx_write_xml(0x4C, tbuf, 4); // longitude + + if (wpt->altitude && (wpt->altitude != unknown_alt)) { + sprintf(tbuf, "%f", wpt->altitude); + lmx_write_xml(0x4D, tbuf, 4); // altitude + } + lmx_end_tag(0x4A, 3); // coordinates + + if (wpt->url && wpt->url[0]) { + lmx_start_tag(0x65, 3); // mediaLink + if (!binary) { + gbfputc('\n', ofd); + } + if (wpt->url_link_text) { + lmx_write_xml(0x48, wpt->url_link_text, 4); // name + } + lmx_write_xml(0x67, wpt->url, 4); // url + lmx_end_tag(0x65, 3); // mediaLink + } + + lmx_end_tag(0x47, 2); // landmark } static void lmx_write(void) { - if (binary) { - gbfputc(0x03, ofd); // WBXML version 1.3 - gbfputuint16(0x04A4, ofd); // "-//NOKIA//DTD LANDMARKS 1.0//EN" - gbfputc(106, ofd); // Charset=UTF-8 - gbfputc(0x00, ofd); // empty string table - gbfputc(0xC5, ofd); // lmx - gbfputc(0x05, ofd); // xmlns=http://www.nokia.com/schemas/location/landmarks/ - gbfputc(0x85, ofd); // 1/0/ - gbfputc(0x06, ofd); // xmlns:xsi= - gbfputc(0x86, ofd); // http://www.w3.org/2001/XMLSchema-instance - gbfputc(0x07, ofd); // xsi:schemaLocation=http://www.nokia.com/schemas/location/landmarks/ - gbfputc(0x85, ofd); // 1/0/ - gbfputc(0x87, ofd); // whitespace - gbfputc(0x88, ofd); // lmx.xsd - gbfputc(0x01, ofd); // END lmx attributes - } else { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); - } - - lmx_start_tag(0x46, 1); // landmarkCollection - if (!binary) gbfputc('\n', ofd); - waypt_disp_all(lmx_print); - lmx_end_tag(0x46, 1); // landmarkCollection - lmx_end_tag(0xC5, 0); // lmx + if (binary) { + gbfputc(0x03, ofd); // WBXML version 1.3 + gbfputuint16(0x04A4, ofd); // "-//NOKIA//DTD LANDMARKS 1.0//EN" + gbfputc(106, ofd); // Charset=UTF-8 + gbfputc(0x00, ofd); // empty string table + gbfputc(0xC5, ofd); // lmx + gbfputc(0x05, ofd); // xmlns=http://www.nokia.com/schemas/location/landmarks/ + gbfputc(0x85, ofd); // 1/0/ + gbfputc(0x06, ofd); // xmlns:xsi= + gbfputc(0x86, ofd); // http://www.w3.org/2001/XMLSchema-instance + gbfputc(0x07, ofd); // xsi:schemaLocation=http://www.nokia.com/schemas/location/landmarks/ + gbfputc(0x85, ofd); // 1/0/ + gbfputc(0x87, ofd); // whitespace + gbfputc(0x88, ofd); // lmx.xsd + gbfputc(0x01, ofd); // END lmx attributes + } else { + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + } + + lmx_start_tag(0x46, 1); // landmarkCollection + if (!binary) { + gbfputc('\n', ofd); + } + waypt_disp_all(lmx_print); + lmx_end_tag(0x46, 1); // landmarkCollection + lmx_end_tag(0xC5, 0); // lmx } /* @@ -250,121 +297,121 @@ static xg_callback lmx_lm_link, lmx_lm_linkt; static xg_tag_mapping gl_map[] = { #define LM "/lm:lmx/lm:landmarkCollection/lm:landmark" - { lmx_lm_start, cb_start, LM }, - { lmx_lm_end, cb_end, LM }, - { lmx_lm_name, cb_cdata, LM "/lm:name" }, - { lmx_lm_desc, cb_cdata, LM "/lm:description" }, - { lmx_lm_lat, cb_cdata, LM "/lm:coordinates/lm:latitude" }, - { lmx_lm_lon, cb_cdata, LM "/lm:coordinates/lm:longitude" }, - { lmx_lm_alt, cb_cdata, LM "/lm:coordinates/lm:altitude" }, - { lmx_lm_mlink_s, cb_start, LM "/lm:mediaLink" }, - { lmx_lm_link, cb_cdata, LM "/lm:mediaLink/lm:url" }, - { lmx_lm_linkt, cb_cdata, LM "/lm:mediaLink/lm:name" }, - { lmx_lm_mlink_e, cb_end, LM "/lm:mediaLink" }, - { NULL, 0, NULL} + { lmx_lm_start, cb_start, LM }, + { lmx_lm_end, cb_end, LM }, + { lmx_lm_name, cb_cdata, LM "/lm:name" }, + { lmx_lm_desc, cb_cdata, LM "/lm:description" }, + { lmx_lm_lat, cb_cdata, LM "/lm:coordinates/lm:latitude" }, + { lmx_lm_lon, cb_cdata, LM "/lm:coordinates/lm:longitude" }, + { lmx_lm_alt, cb_cdata, LM "/lm:coordinates/lm:altitude" }, + { lmx_lm_mlink_s, cb_start, LM "/lm:mediaLink" }, + { lmx_lm_link, cb_cdata, LM "/lm:mediaLink/lm:url" }, + { lmx_lm_linkt, cb_cdata, LM "/lm:mediaLink/lm:name" }, + { lmx_lm_mlink_e, cb_end, LM "/lm:mediaLink" }, + { NULL, (xg_cb_type)0, NULL} }; static void -lmx_rd_init(const char *fname) +lmx_rd_init(const char* fname) { - xml_init(fname, gl_map, NULL); + xml_init(fname, gl_map, NULL); } static void lmx_read(void) { - xml_read(); + xml_read(); } static void lmx_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void -lmx_lm_start(const char *args, const char **unused) +lmx_lm_start(const char* args, const char** unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } static void -lmx_lm_end(const char *args, const char **unused) +lmx_lm_end(const char* args, const char** unused) { - waypt_add(wpt_tmp); + waypt_add(wpt_tmp); } static void -lmx_lm_lat(const char *args, const char **unused) +lmx_lm_lat(const char* args, const char** unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } static void -lmx_lm_lon(const char *args, const char **unused) +lmx_lm_lon(const char* args, const char** unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } static void -lmx_lm_alt(const char *args, const char **unused) +lmx_lm_alt(const char* args, const char** unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } static void -lmx_lm_name(const char *args, const char **unused) +lmx_lm_name(const char* args, const char** unused) { - wpt_tmp->shortname = xstrdup(args); + wpt_tmp->shortname = xstrdup(args); } -static void -lmx_lm_desc(const char *args, const char **unused) +static void +lmx_lm_desc(const char* args, const char** unused) { - wpt_tmp->description = xstrdup(args); + wpt_tmp->description = xstrdup(args); } static void -lmx_lm_mlink_s(const char *args, const char **unused) +lmx_lm_mlink_s(const char* args, const char** unused) { - urllink = urllinkt = NULL; + urllink = urllinkt = NULL; } static void -lmx_lm_link(const char *args, const char **unused) +lmx_lm_link(const char* args, const char** unused) { - urllink = xstrdup(args); + urllink = xstrdup(args); } static void -lmx_lm_linkt(const char *args, const char **unused) +lmx_lm_linkt(const char* args, const char** unused) { - urllinkt = xstrdup(args); + urllinkt = xstrdup(args); } static void -lmx_lm_mlink_e(const char *args, const char **unused) +lmx_lm_mlink_e(const char* args, const char** unused) { - waypt_add_url(wpt_tmp, urllink, urllinkt); + waypt_add_url(wpt_tmp, urllink, urllinkt); } ff_vecs_t lmx_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write, /* waypoints */ - ff_cap_none, /* tracks */ - ff_cap_none /* routes */ - }, - lmx_rd_init, - lmx_wr_init, - lmx_rd_deinit, - lmx_wr_deinit, - lmx_read, - lmx_write, - NULL, - lmx_args, - CET_CHARSET_UTF8, 0 /* CET-REVIEW */ + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write), /* waypoints */ + ff_cap_none, /* tracks */ + ff_cap_none /* routes */ + }, + lmx_rd_init, + lmx_wr_init, + lmx_rd_deinit, + lmx_wr_deinit, + lmx_read, + lmx_write, + NULL, + lmx_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/lowranceusr.c b/gpsbabel/lowranceusr.c index 90f2cf362..abad2ce30 100644 --- a/gpsbabel/lowranceusr.c +++ b/gpsbabel/lowranceusr.c @@ -37,163 +37,163 @@ #include /* for lat/lon conversion */ typedef struct lowranceusr_icon_mapping { - const int value; - const char *icon; + const int value; + const char* icon; } lowranceusr_icon_mapping_t; #define DEF_ICON 10001 /* Taken from iFinder 1.8 */ const lowranceusr_icon_mapping_t lowranceusr_icon_value_table[] = { - { 10000, "diamond 1" }, - { 10001, "diamond 2" }, - { 10002, "diamond 3" }, - { 10003, "x 1" }, - { 10004, "x 2" }, - { 10005, "x 3" }, - { 10006, "cross" }, - { 10007, "house" }, - { 10008, "car" }, - { 10009, "store" }, - { 10010, "gas station" }, - { 10011, "fork and spoon" }, - { 10012, "telephone" }, - { 10013, "airplane" }, - { 10014, "exit sign" }, - { 10015, "stop sign" }, - { 10016, "exclamation" }, - { 10017, "traffic light" }, - { 10018, "american flag" }, - { 10019, "person" }, - { 10020, "restrooms" }, - { 10021, "tree" }, - { 10022, "mountains" }, - { 10023, "campsite" }, - { 10024, "picnic table" }, - { 10025, "deer" }, - { 10026, "deer tracks" }, - { 10027, "turkey tracks" }, - { 10028, "tree stand" }, - { 10029, "bridge" }, - { 10030, "skull and crossbones" }, - { 10031, "fish" }, - { 10032, "two fish" }, - { 10033, "dive flag" }, - { 10034, "wreck" }, - { 10035, "anchor" }, - { 10036, "boat" }, - { 10037, "boat ramp" }, - { 10038, "flag buoy" }, - { 10039, "dam" }, - { 10040, "swimmer" }, - { 10041, "pier"}, - -/* The following list is from TopoFusion */ - - { 10000, "Waypoint" }, /* diamond 1 */ - { DEF_ICON, "Text Label (No Dot)" }, - { 10018, "Trailhead" }, /* american flag */ - { 10023, "Campground" }, /* campsite */ - { 10022, "Summit" }, /* mountains */ - { DEF_ICON, "Tall Tower" }, - { DEF_ICON, "Short Tower" }, - { 10021, "Forest" }, /* tree */ - { DEF_ICON, "Mine" }, + { 10000, "diamond 1" }, + { 10001, "diamond 2" }, + { 10002, "diamond 3" }, + { 10003, "x 1" }, + { 10004, "x 2" }, + { 10005, "x 3" }, + { 10006, "cross" }, + { 10007, "house" }, + { 10008, "car" }, + { 10009, "store" }, + { 10010, "gas station" }, + { 10011, "fork and spoon" }, + { 10012, "telephone" }, + { 10013, "airplane" }, + { 10014, "exit sign" }, + { 10015, "stop sign" }, + { 10016, "exclamation" }, + { 10017, "traffic light" }, + { 10018, "american flag" }, + { 10019, "person" }, + { 10020, "restrooms" }, + { 10021, "tree" }, + { 10022, "mountains" }, + { 10023, "campsite" }, + { 10024, "picnic table" }, + { 10025, "deer" }, + { 10026, "deer tracks" }, + { 10027, "turkey tracks" }, + { 10028, "tree stand" }, + { 10029, "bridge" }, + { 10030, "skull and crossbones" }, + { 10031, "fish" }, + { 10032, "two fish" }, + { 10033, "dive flag" }, + { 10034, "wreck" }, + { 10035, "anchor" }, + { 10036, "boat" }, + { 10037, "boat ramp" }, + { 10038, "flag buoy" }, + { 10039, "dam" }, + { 10040, "swimmer" }, + { 10041, "pier"}, + + /* The following list is from TopoFusion */ + + { 10000, "Waypoint" }, /* diamond 1 */ + { DEF_ICON, "Text Label (No Dot)" }, + { 10018, "Trailhead" }, /* american flag */ + { 10023, "Campground" }, /* campsite */ + { 10022, "Summit" }, /* mountains */ + { DEF_ICON, "Tall Tower" }, + { DEF_ICON, "Short Tower" }, + { 10021, "Forest" }, /* tree */ + { DEF_ICON, "Mine" }, // { 10038, "Geocache" }, /* flag buoy */ // { 10016, "Geocache Found" }, /* exclamation */ - { DEF_ICON, "Skiing Area" }, - { 10029, "Crossing" }, /* bridge */ - { 10007, "House" }, /* house */ - { 10003, "Dot" }, /* x 1 */ - { 10025, "Hunting Area" }, /* deer */ - { 10031, "Fishing Area" }, /* fish */ - { 10040, "Swimming Area" }, /* swimmer */ - { 10012, "Telephone" }, /* telephone */ - { 10024, "Rest Area" }, /* picnic table */ - { 10021, "Park" }, /* tree */ - { 10007, "Information" }, /* house */ - { 10022, "Scenic Area" }, /* mountains */ - { DEF_ICON, "Bank/Dollar" }, - { 10009, "Hotel" }, /* store */ - { 10011, "Restaurant" }, /* fork and spoon */ - { 10030, "Danger Area" }, /* skull and crossbones */ - { 10035, "Anchor" }, /* anchor */ - { 10002, "City (Large)" }, /* diamond 3 */ - { 10001, "City (Medium)" }, /* diamond 2 */ - { 10000, "City (Small)" }, /* diamond 1 */ - { DEF_ICON, "Drinking Water" }, - { 10008, "Parking Area" }, /* car */ - { 10023, "RV Park" }, /* campsite */ - { 10020, "Rest Room" }, /* restroom */ - { 10019, "Shower" }, /* person */ - { DEF_ICON, "Tunnel" }, - - /* This list comes from 'wifinder' from ifinder H20 Color */ - - { 10062, "Interesting Land Feature" }, - { 10063, "Global Location" }, - { 10064, "Note" }, - { 10065, "Ghost" }, - { 10066, "Letter" }, - { 10067, "Multi-Treasure" }, - { 10068, "Mystery Or Puzzle" }, - { 10069, "Treasure" }, - { 10070, "Webmail" }, - { 10071, "Sun" }, - { 10072, "Musical Note" }, - { 10073, "Camera/Movie Theater" }, - { 10074, "Star" }, - { 10075, "Coffee Mug" }, - { 10076, "Books" }, - { 10077, "Historical Marker" }, - { 10078, "Tools/Repair" }, - { 10079, "Favorite" }, - { 10080, "Arena" }, - { 10081, "Golf Course" }, - { 10082, "Money/Atm" }, - - /* This list comes from Alan Porter , using an iFinder Expedition C */ - - { 10042, "icon42" }, // black box with red X - { 10043, "icon43" }, // small red dot - { 10044, "icon44" }, // 4-wheeler - { 10045, "icon45" }, // hiding hunter - { 10046, "icon46" }, // tree (yellow base) - { 10047, "icon47" }, // windmill - { 10048, "icon48" }, // camera - { 10049, "icon49" }, // tree (something in front of base) - { 10050, "icon50" }, // tree (something hanging from left side) - { 10051, "icon51" }, // 4 dots in rhombus shape - { 10052, "icon52" }, // bare winter tree - { 10053, "icon53" }, // hiding deer head peeking over bushes - { 10054, "icon54" }, // piston? over a pile of salt? - { 10055, "icon55" }, // corn - { 10056, "icon56" }, // turkey - { 10057, "icon57" }, // duck - { 10058, "icon58" }, // hen - { 10059, "icon59" }, // rabbit - { 10060, "icon60" }, // paw print - { 10061, "icon61" }, // 2 red flames? - - /* These are the icons that gpsbabel will use */ - - { 10038, "Geocache" }, // flag buoy - { 10016, "Geocache Found" }, // exclamation - { 10043, "Micro-Cache" }, // small red dot - { 10065, "Virtual cache" }, // ghost - { 10051, "Multi-Cache" }, // 4 dots in rhombus shape - { 10068, "Unknown Cache" }, // ? mark - { 10045, "Locationless (Reverse) Cache" }, // hiding hunter - { 10066, "Post Office" }, // letter - { 10019, "Event Cache" }, // person - { 10070, "Webcam Cache" }, // webcam - { 10042, "Disabled Cache" }, // black box with red X - - { -1, NULL } + { DEF_ICON, "Skiing Area" }, + { 10029, "Crossing" }, /* bridge */ + { 10007, "House" }, /* house */ + { 10003, "Dot" }, /* x 1 */ + { 10025, "Hunting Area" }, /* deer */ + { 10031, "Fishing Area" }, /* fish */ + { 10040, "Swimming Area" }, /* swimmer */ + { 10012, "Telephone" }, /* telephone */ + { 10024, "Rest Area" }, /* picnic table */ + { 10021, "Park" }, /* tree */ + { 10007, "Information" }, /* house */ + { 10022, "Scenic Area" }, /* mountains */ + { DEF_ICON, "Bank/Dollar" }, + { 10009, "Hotel" }, /* store */ + { 10011, "Restaurant" }, /* fork and spoon */ + { 10030, "Danger Area" }, /* skull and crossbones */ + { 10035, "Anchor" }, /* anchor */ + { 10002, "City (Large)" }, /* diamond 3 */ + { 10001, "City (Medium)" }, /* diamond 2 */ + { 10000, "City (Small)" }, /* diamond 1 */ + { DEF_ICON, "Drinking Water" }, + { 10008, "Parking Area" }, /* car */ + { 10023, "RV Park" }, /* campsite */ + { 10020, "Rest Room" }, /* restroom */ + { 10019, "Shower" }, /* person */ + { DEF_ICON, "Tunnel" }, + + /* This list comes from 'wifinder' from ifinder H20 Color */ + + { 10062, "Interesting Land Feature" }, + { 10063, "Global Location" }, + { 10064, "Note" }, + { 10065, "Ghost" }, + { 10066, "Letter" }, + { 10067, "Multi-Treasure" }, + { 10068, "Mystery Or Puzzle" }, + { 10069, "Treasure" }, + { 10070, "Webmail" }, + { 10071, "Sun" }, + { 10072, "Musical Note" }, + { 10073, "Camera/Movie Theater" }, + { 10074, "Star" }, + { 10075, "Coffee Mug" }, + { 10076, "Books" }, + { 10077, "Historical Marker" }, + { 10078, "Tools/Repair" }, + { 10079, "Favorite" }, + { 10080, "Arena" }, + { 10081, "Golf Course" }, + { 10082, "Money/Atm" }, + + /* This list comes from Alan Porter , using an iFinder Expedition C */ + + { 10042, "icon42" }, // black box with red X + { 10043, "icon43" }, // small red dot + { 10044, "icon44" }, // 4-wheeler + { 10045, "icon45" }, // hiding hunter + { 10046, "icon46" }, // tree (yellow base) + { 10047, "icon47" }, // windmill + { 10048, "icon48" }, // camera + { 10049, "icon49" }, // tree (something in front of base) + { 10050, "icon50" }, // tree (something hanging from left side) + { 10051, "icon51" }, // 4 dots in rhombus shape + { 10052, "icon52" }, // bare winter tree + { 10053, "icon53" }, // hiding deer head peeking over bushes + { 10054, "icon54" }, // piston? over a pile of salt? + { 10055, "icon55" }, // corn + { 10056, "icon56" }, // turkey + { 10057, "icon57" }, // duck + { 10058, "icon58" }, // hen + { 10059, "icon59" }, // rabbit + { 10060, "icon60" }, // paw print + { 10061, "icon61" }, // 2 red flames? + + /* These are the icons that gpsbabel will use */ + + { 10038, "Geocache" }, // flag buoy + { 10016, "Geocache Found" }, // exclamation + { 10043, "Micro-Cache" }, // small red dot + { 10065, "Virtual cache" }, // ghost + { 10051, "Multi-Cache" }, // 4 dots in rhombus shape + { 10068, "Unknown Cache" }, // ? mark + { 10045, "Locationless (Reverse) Cache" }, // hiding hunter + { 10066, "Post Office" }, // letter + { 10019, "Event Cache" }, // person + { 10070, "Webcam Cache" }, // webcam + { 10042, "Disabled Cache" }, // black box with red X + + { -1, NULL } }; -static gbfile *file_in; -static gbfile *file_out; +static gbfile* file_in; +static gbfile* file_out; static short_handle mkshort_handle; static unsigned short waypt_out_count; @@ -201,13 +201,13 @@ static unsigned int trail_count, lowrance_route_count; static int trail_point_count; static char continuous = 1; static short num_section_points; -static route_head *trk_head; -static route_head *rte_head; -static char *ignoreicons; -static char *writeasicons; -static char *merge; -static char *seg_break; -static char *wversion_arg; +static route_head* trk_head; +static route_head* rte_head; +static char* ignoreicons; +static char* writeasicons; +static char* merge; +static char* seg_break; +static char* wversion_arg; static int reading_version; static int writing_version; @@ -224,202 +224,224 @@ static int writing_version; const time_t base_time_secs = 946706400; static int -lowranceusr_readstr(char *buf, const int maxlen, gbfile *file) +lowranceusr_readstr(char* buf, const int maxlen, gbfile* file) { - int org, len; - - org = len = gbfgetint32(file); - if (len < 0) fatal(MYNAME ": Invalid item length (%d)!\n", len); - else if (len) { - int i; - if (len > maxlen) len = maxlen; - (void) gbfread(buf, 1, len, file); - if (org > maxlen) (void) gbfseek(file, org - maxlen, SEEK_CUR); - // IWay 350C puts 0x01 for the accented o in the street name - // of the Montreal Holiday Inn. - for (i = 0; i < len; i++) { - if (buf[i] == 0x01) - buf[i] = '*'; - } - - } - - return len; + int org, len; + + org = len = gbfgetint32(file); + if (len < 0) { + fatal(MYNAME ": Invalid item length (%d)!\n", len); + } else if (len) { + int i; + if (len > maxlen) { + len = maxlen; + } + (void) gbfread(buf, 1, len, file); + if (org > maxlen) { + (void) gbfseek(file, org - maxlen, SEEK_CUR); + } + // IWay 350C puts 0x01 for the accented o in the street name + // of the Montreal Holiday Inn. + for (i = 0; i < len; i++) { + if (buf[i] == 0x01) { + buf[i] = '*'; + } + } + + } + + return len; } -const char * +const char* lowranceusr_find_desc_from_icon_number(const int icon) { - const lowranceusr_icon_mapping_t *i; + const lowranceusr_icon_mapping_t* i; - for (i = lowranceusr_icon_value_table; i->icon; i++) { - if (icon == i->value) { - return i->icon; - } - } + for (i = lowranceusr_icon_value_table; i->icon; i++) { + if (icon == i->value) { + return i->icon; + } + } - return ""; + return ""; } int -lowranceusr_find_icon_number_from_desc(const char *desc) +lowranceusr_find_icon_number_from_desc(const char* desc) { - const lowranceusr_icon_mapping_t *i; - int n; - - if (!desc) { - return DEF_ICON; - } - - /* - * If we were given a numeric icon number as a description - * (i.e. 8255), just return that. - */ - n = atoi(desc); - if (n) { - return n; - } - - - for (i = lowranceusr_icon_value_table; i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - return i->value; - } - } - - return DEF_ICON; + const lowranceusr_icon_mapping_t* i; + int n; + + if (!desc) { + return DEF_ICON; + } + + /* + * If we were given a numeric icon number as a description + * (i.e. 8255), just return that. + */ + n = atoi(desc); + if (n) { + return n; + } + + + for (i = lowranceusr_icon_value_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + return i->value; + } + } + + return DEF_ICON; } static arglist_t lowranceusr_args[] = { - {"ignoreicons", &ignoreicons, "Ignore event marker icons on read", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"writeasicons", &writeasicons, "Treat waypoints as icons on write", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"merge", &merge, "(USR output) Merge into one segmented track", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"break", &seg_break, "(USR input) Break segments into separate tracks", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"wversion", &wversion_arg, "(USR output) Write version", - "2", ARGTYPE_INT, "2", "3" }, - ARG_TERMINATOR + { + "ignoreicons", &ignoreicons, "Ignore event marker icons on read", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "writeasicons", &writeasicons, "Treat waypoints as icons on write", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "merge", &merge, "(USR output) Merge into one segmented track", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "break", &seg_break, "(USR input) Break segments into separate tracks", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "wversion", &wversion_arg, "(USR output) Write version", + "2", ARGTYPE_INT, "2", "3" + }, + ARG_TERMINATOR }; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); - waypt_out_count = 0; - writing_version = atoi(wversion_arg); + file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); + waypt_out_count = 0; + writing_version = atoi(wversion_arg); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } /** * Latitude and longitude for USR coords are in the lowrance mercator meter * format in WGS84. The below code converts them to degrees. */ -static double -lon_mm_to_deg(double x) { - return x / (DEGREESTORADIANS * SEMIMINOR); +static double +lon_mm_to_deg(double x) +{ + return x / (DEGREESTORADIANS * SEMIMINOR); } -static long -lon_deg_to_mm(double x) { - return (long)(x * SEMIMINOR * DEGREESTORADIANS); +static long +lon_deg_to_mm(double x) +{ + return (long)(x * SEMIMINOR * DEGREESTORADIANS); } -static double -lat_mm_to_deg(double x) { - return (2.0 * atan(exp(x / SEMIMINOR)) - M_PI / 2.0) / DEGREESTORADIANS; +static double +lat_mm_to_deg(double x) +{ + return (2.0 * atan(exp(x / SEMIMINOR)) - M_PI / 2.0) / DEGREESTORADIANS; } static long -lat_deg_to_mm(double x) { - return (long)(SEMIMINOR * log(tan((x * DEGREESTORADIANS + M_PI / 2.0) / 2.0))); +lat_deg_to_mm(double x) +{ + return (long)(SEMIMINOR * log(tan((x * DEGREESTORADIANS + M_PI / 2.0) / 2.0))); } static void -lowranceusr_parse_waypt(waypoint *wpt_tmp) +lowranceusr_parse_waypt(waypoint* wpt_tmp) { - char buff[MAXUSRSTRINGSIZE + 1]; - int text_len; - time_t waypt_time; - short waypt_type; - - wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->altitude = FEET_TO_METERS(gbfgetint32(file_in)); - if (METERS_TO_FEET(wpt_tmp->altitude) <= -10000) { - wpt_tmp->altitude = unknown_alt; - } - - text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); - if (text_len) { - buff[text_len] = '\0'; - wpt_tmp->shortname = xstrdup(buff); - } - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_waypt: Waypt name = %s Lat = %f Lon = %f alt = %f\n",wpt_tmp->shortname, wpt_tmp->latitude, - wpt_tmp->longitude, wpt_tmp->altitude); - - text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); - if (text_len) { - buff[text_len] = '\0'; - wpt_tmp->description = xstrdup(buff); - } - /* Time is number of seconds since Jan. 1, 2000 */ - waypt_time = gbfgetint32(file_in); - if (waypt_time) - wpt_tmp->creation_time = base_time_secs + waypt_time; - - if (global_opts.debug_level >= 2) - { - printf(MYNAME " parse_waypt: creation time %d\n", - (int)wpt_tmp->creation_time); - printf(MYNAME " parse_waypt: base_time %d\n", (int)base_time_secs); - printf(MYNAME " parse_waypt: waypt time %d\n", (int)waypt_time); - } - - /* Symbol ID */ - wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); - if (!wpt_tmp->icon_descr[0]) { - char nbuf[10]; - snprintf(nbuf, sizeof(nbuf), "%d", le_read32(buff)); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - wpt_tmp->icon_descr = xstrdup(nbuf); - } - - /* Waypoint Type (USER, TEMPORARY, POINT_OF_INTEREST) */ - waypt_type = gbfgetint16(file_in); - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_waypt: waypt_type = %d\n",waypt_type); - - // Version 3 has a depth field here. - if (reading_version >= 3) { - float depth_feet = gbfgetflt(file_in); - if (abs(depth_feet - 99999.0) > .1) - WAYPT_SET(wpt_tmp, depth, FEET_TO_METERS(depth_feet)); - } + char buff[MAXUSRSTRINGSIZE + 1]; + int text_len; + time_t waypt_time; + short waypt_type; + + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->altitude = FEET_TO_METERS(gbfgetint32(file_in)); + if (METERS_TO_FEET(wpt_tmp->altitude) <= -10000) { + wpt_tmp->altitude = unknown_alt; + } + + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) { + buff[text_len] = '\0'; + wpt_tmp->shortname = xstrdup(buff); + } + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_waypt: Waypt name = %s Lat = %f Lon = %f alt = %f\n",wpt_tmp->shortname, wpt_tmp->latitude, + wpt_tmp->longitude, wpt_tmp->altitude); + + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) { + buff[text_len] = '\0'; + wpt_tmp->description = xstrdup(buff); + } + /* Time is number of seconds since Jan. 1, 2000 */ + waypt_time = gbfgetint32(file_in); + if (waypt_time) { + wpt_tmp->creation_time = base_time_secs + waypt_time; + } + + if (global_opts.debug_level >= 2) { + printf(MYNAME " parse_waypt: creation time %d\n", + (int)wpt_tmp->creation_time); + printf(MYNAME " parse_waypt: base_time %d\n", (int)base_time_secs); + printf(MYNAME " parse_waypt: waypt time %d\n", (int)waypt_time); + } + + /* Symbol ID */ + wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); + if (!wpt_tmp->icon_descr[0]) { + char nbuf[10]; + snprintf(nbuf, sizeof(nbuf), "%d", le_read32(buff)); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(nbuf); + } + + /* Waypoint Type (USER, TEMPORARY, POINT_OF_INTEREST) */ + waypt_type = gbfgetint16(file_in); + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_waypt: waypt_type = %d\n",waypt_type); + } + + // Version 3 has a depth field here. + if (reading_version >= 3) { + float depth_feet = gbfgetflt(file_in); + if (abs(depth_feet - 99999.0) > .1) { + WAYPT_SET(wpt_tmp, depth, FEET_TO_METERS(depth_feet)); + } + } } @@ -428,46 +450,44 @@ lowranceusr_parse_waypt(waypoint *wpt_tmp) static void lowranceusr_parse_routes(void) { - char buff[MAXUSRSTRINGSIZE + 1]; - short int num_routes, num_legs; - int i,j; - int text_len; - waypoint *wpt_tmp; - - num_routes = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_routes: Num Routes = %d\n", num_routes); - - for (i=0; i < num_routes; i++) - { - rte_head = route_head_alloc(); - route_add_head(rte_head); - rte_head->rte_num = i+1; - - /* route name */ - text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); - if (text_len) - { - buff[text_len] = '\0'; - rte_head->rte_name = xstrdup(buff); - } - rte_head->rte_desc = '\0'; /* ???????? */ - - /* num Legs */ - num_legs = gbfgetint16(file_in); - - /* route reversed */ - (void) gbfread(&buff[0], 1, 1, file_in); - - /* waypoints */ - for (j=0; j < num_legs; j++) - { - wpt_tmp = waypt_new(); - lowranceusr_parse_waypt(wpt_tmp); - route_add_wpt(rte_head, wpt_tmp); - } - } + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_routes, num_legs; + int i,j; + int text_len; + waypoint* wpt_tmp; + + num_routes = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_routes: Num Routes = %d\n", num_routes); + } + + for (i=0; i < num_routes; i++) { + rte_head = route_head_alloc(); + route_add_head(rte_head); + rte_head->rte_num = i+1; + + /* route name */ + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) { + buff[text_len] = '\0'; + rte_head->rte_name = xstrdup(buff); + } + rte_head->rte_desc = '\0'; /* ???????? */ + + /* num Legs */ + num_legs = gbfgetint16(file_in); + + /* route reversed */ + (void) gbfread(&buff[0], 1, 1, file_in); + + /* waypoints */ + for (j=0; j < num_legs; j++) { + wpt_tmp = waypt_new(); + lowranceusr_parse_waypt(wpt_tmp); + route_add_wpt(rte_head, wpt_tmp); + } + } } /* @@ -477,319 +497,328 @@ lowranceusr_parse_routes(void) static void lowranceusr_parse_icons(void) { - char buff[MAXUSRSTRINGSIZE + 1]; - short int num_icons; - int i; - - num_icons = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_icons: num Icons = %d\n", num_icons); - - for (i=0; i < num_icons; i++) - { - if (ignoreicons) - { - /* position coord lat & long */ - (void) gbfread(&buff[0], 4, 2, file_in); - /* symbol */ - (void) gbfread(&buff[0], 4, 1, file_in); - } - else - { - waypoint *wpt_tmp; - wpt_tmp = waypt_new(); - - /* position coord lat & long */ - wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->altitude = 0; - snprintf(buff, sizeof(buff), "Icon %d", i+1); - wpt_tmp->shortname = xstrdup(buff); - /* symbol */ - wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); - waypt_add(wpt_tmp); - } - } + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_icons; + int i; + + num_icons = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_icons: num Icons = %d\n", num_icons); + } + + for (i=0; i < num_icons; i++) { + if (ignoreicons) { + /* position coord lat & long */ + (void) gbfread(&buff[0], 4, 2, file_in); + /* symbol */ + (void) gbfread(&buff[0], 4, 1, file_in); + } else { + waypoint* wpt_tmp; + wpt_tmp = waypt_new(); + + /* position coord lat & long */ + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->altitude = 0; + snprintf(buff, sizeof(buff), "Icon %d", i+1); + wpt_tmp->shortname = xstrdup(buff); + /* symbol */ + wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); + waypt_add(wpt_tmp); + } + } } static void lowranceusr_parse_trails(void) { - char buff[MAXUSRSTRINGSIZE + 1]; - short int num_trails, num_trail_points, num_section_points; - int i,j, trk_num, itmp; - int text_len; - waypoint *wpt_tmp; - route_head *trk_tmp; - - /* num trails */ - num_trails = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: num trails = %d\n", num_trails); - - for (i=trk_num=0; i < num_trails; i++) - { - trk_head = route_head_alloc(); - trk_head->rte_num = ++trk_num; - track_add_head(trk_head); - - /* trail name */ - text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: name text len = %d\n", text_len); - - if (text_len) { - buff[text_len] = '\0'; - trk_head->rte_name = xstrdup(buff); - } - trk_head->rte_desc = '\0'; - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: trail name = %s\n", trk_head->rte_name); - - /* visible */ - (void) gbfread(&buff[0], 1, 1, file_in); - /* num trail points */ - num_trail_points = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: num trail points = %d\n", num_trail_points); - - /* max trail size */ - itmp = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: max trail size = %d\n", itmp); - - if (num_trail_points) - { - - while (num_trail_points) - { - /* num section points */ - num_section_points = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: num section points = %d\n", num_section_points); - - for (j=0; j < num_section_points; j++, num_trail_points--) - { - wpt_tmp = waypt_new(); - wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); - /* continuous */ - (void) gbfread(&buff[0], 1, 1, file_in); - if (!buff[0] && seg_break && j) - { - trk_tmp = route_head_alloc(); - trk_tmp->rte_num = ++trk_num; - trk_tmp->rte_name = xstrdup(trk_head->rte_name); - trk_tmp->rte_desc = '\0'; - track_add_head(trk_tmp); - trk_head = trk_tmp; - } - track_add_wpt(trk_head, wpt_tmp); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: Trail pt lat %f lon %f\n", wpt_tmp->latitude, wpt_tmp->longitude); - } - } - } - /* remove the trail since it's empty */ - else track_del_head(trk_head); - } + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_trails, num_trail_points, num_section_points; + int i,j, trk_num, itmp; + int text_len; + waypoint* wpt_tmp; + route_head* trk_tmp; + + /* num trails */ + num_trails = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: num trails = %d\n", num_trails); + } + + for (i=trk_num=0; i < num_trails; i++) { + trk_head = route_head_alloc(); + trk_head->rte_num = ++trk_num; + track_add_head(trk_head); + + /* trail name */ + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: name text len = %d\n", text_len); + } + + if (text_len) { + buff[text_len] = '\0'; + trk_head->rte_name = xstrdup(buff); + } + trk_head->rte_desc = '\0'; + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: trail name = %s\n", trk_head->rte_name); + } + + /* visible */ + (void) gbfread(&buff[0], 1, 1, file_in); + /* num trail points */ + num_trail_points = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: num trail points = %d\n", num_trail_points); + } + + /* max trail size */ + itmp = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: max trail size = %d\n", itmp); + } + + if (num_trail_points) { + + while (num_trail_points) { + /* num section points */ + num_section_points = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: num section points = %d\n", num_section_points); + } + + for (j=0; j < num_section_points; j++, num_trail_points--) { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + /* continuous */ + (void) gbfread(&buff[0], 1, 1, file_in); + if (!buff[0] && seg_break && j) { + trk_tmp = route_head_alloc(); + trk_tmp->rte_num = ++trk_num; + trk_tmp->rte_name = xstrdup(trk_head->rte_name); + trk_tmp->rte_desc = '\0'; + track_add_head(trk_tmp); + trk_head = trk_tmp; + } + track_add_wpt(trk_head, wpt_tmp); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: Trail pt lat %f lon %f\n", wpt_tmp->latitude, wpt_tmp->longitude); + } + } + } + } + /* remove the trail since it's empty */ + else { + track_del_head(trk_head); + } + } } static void data_read(void) { - short int NumWaypoints, MajorVersion, MinorVersion, object_num; - int i; + short int NumWaypoints, MajorVersion, MinorVersion, object_num; + int i; + + MajorVersion = gbfgetint16(file_in); + reading_version = MajorVersion; + MinorVersion = gbfgetint16(file_in); - MajorVersion = gbfgetint16(file_in); - reading_version = MajorVersion; - MinorVersion = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " data_read: Major Version %d Minor Version %d\n", MajorVersion, MinorVersion); + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_read: Major Version %d Minor Version %d\n", MajorVersion, MinorVersion); + } - if (MajorVersion < 2) { - fatal(MYNAME ": input file is from an old version of the USR file and is not supported\n"); - } - if (MajorVersion > 3) { - fatal(MYNAME ": input file version %d is not supported\n", - MajorVersion); - } + if (MajorVersion < 2) { + fatal(MYNAME ": input file is from an old version of the USR file and is not supported\n"); + } + if (MajorVersion > 3) { + fatal(MYNAME ": input file version %d is not supported\n", + MajorVersion); + } - NumWaypoints = gbfgetint16(file_in); + NumWaypoints = gbfgetint16(file_in); - if (global_opts.debug_level >= 1) - printf(MYNAME " data_read: Num waypoints %d\n", NumWaypoints); + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_read: Num waypoints %d\n", NumWaypoints); + } - for (i = 0; i < NumWaypoints; i++) { - waypoint *wpt_tmp; + for (i = 0; i < NumWaypoints; i++) { + waypoint* wpt_tmp; - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); - /* Object num */ - object_num = gbfgetint16(file_in); - if (global_opts.debug_level >= 1) - printf(MYNAME " data_read: object_num = %d\n", object_num); + /* Object num */ + object_num = gbfgetint16(file_in); + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_read: object_num = %d\n", object_num); + } - /* waypoint */ - lowranceusr_parse_waypt(wpt_tmp); + /* waypoint */ + lowranceusr_parse_waypt(wpt_tmp); - waypt_add(wpt_tmp); - } + waypt_add(wpt_tmp); + } - lowranceusr_parse_routes(); - lowranceusr_parse_icons(); - lowranceusr_parse_trails(); + lowranceusr_parse_routes(); + lowranceusr_parse_icons(); + lowranceusr_parse_trails(); } static void -lowranceusr_waypt_disp(const waypoint *wpt) +lowranceusr_waypt_disp(const waypoint* wpt) { - int text_len, Lat, Lon, Time, SymbolId; - short int WayptType; - char *name; - char *comment; - int alt = METERS_TO_FEET(wpt->altitude); - - if (wpt->altitude == unknown_alt) { - alt = UNKNOWN_USR_ALTITUDE; - } - - Lat = lat_deg_to_mm(wpt->latitude); - Lon = lon_deg_to_mm(wpt->longitude); - gbfputint32(Lat, file_out); - gbfputint32(Lon, file_out); - gbfputint32(alt, file_out); - - if (writing_version >= 3) { - float depth = WAYPT_HAS(wpt, depth) ? - METERS_TO_FEET(wpt->depth) : -99999.0; - gbfputflt(depth, file_out); - } - - if (global_opts.debug_level >= 1) { - /* print lat/lon/alt on one easily greppable line */ - printf(MYNAME " waypt_disp: Lat = %d Lon = %d Alt = %d\n",Lat, Lon, alt); - } - - /* Try and make sure we have a name */ - if ((! wpt->shortname) || global_opts.synthesize_shortnames) { - if (wpt->description && global_opts.synthesize_shortnames) { - name = mkshort_from_wpt(mkshort_handle, wpt); - } else if (wpt->shortname) { - name = xstrdup(wpt->shortname); - } else if (wpt->description) { - name = xstrdup(wpt->description); - } else { - name = xstrdup(""); - } - } else { - name = xstrdup(wpt->shortname); - } - - text_len = strlen(name); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - gbfputint32(text_len, file_out); - gbfwrite(name, 1, text_len, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " waypt_disp: Waypt name = %s\n",name); - - xfree(name); - - /** - * Comments are now used by the iFinder (Expedition C supports them) - */ - if (wpt->description && strcmp(wpt->description, wpt->shortname) != 0) { - comment = xstrdup(wpt->description); - text_len = strlen(comment); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - gbfputint32(text_len, file_out); - gbfwrite(comment, 1, text_len, file_out); - xfree(comment); - } else { - text_len = 0; - gbfputint32(text_len, file_out); - } - - if (wpt->creation_time > base_time_secs) { - Time = wpt->creation_time - base_time_secs; - } else { - Time = 0; - } - - if (global_opts.debug_level >= 2) - { - time_t wpt_time = Time; - printf(MYNAME " waypt_disp: base_time : %d\n", (int)base_time_secs); - printf(MYNAME " waypt_disp: creation time : %d\n", (int)wpt->creation_time); - printf(MYNAME " waypt_disp: waypt time : %d\n", (int)wpt_time); - printf(MYNAME " waypt_disp: waypt time (local): %s\n", ctime(&wpt_time)); - } - - gbfputint32(Time, file_out); - - if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { - SymbolId = lowranceusr_find_icon_number_from_desc(get_cache_icon(wpt)); - } else { - SymbolId = lowranceusr_find_icon_number_from_desc(wpt->icon_descr); - } - /* If the waypoint is archived or disabled, use a "disabled" icon instead. */ - if ( (wpt->gc_data->is_archived==status_true) || (wpt->gc_data->is_available==status_false) ) { - SymbolId = lowranceusr_find_icon_number_from_desc("Disabled Cache"); - } - - gbfputint32(SymbolId, file_out); - - /* USER waypoint type */ - WayptType = 0; - gbfputint16(WayptType, file_out); + int text_len, Lat, Lon, Time, SymbolId; + short int WayptType; + char* name; + char* comment; + int alt = METERS_TO_FEET(wpt->altitude); + + if (wpt->altitude == unknown_alt) { + alt = UNKNOWN_USR_ALTITUDE; + } + + Lat = lat_deg_to_mm(wpt->latitude); + Lon = lon_deg_to_mm(wpt->longitude); + gbfputint32(Lat, file_out); + gbfputint32(Lon, file_out); + gbfputint32(alt, file_out); + + if (writing_version >= 3) { + float depth = WAYPT_HAS(wpt, depth) ? + METERS_TO_FEET(wpt->depth) : -99999.0; + gbfputflt(depth, file_out); + } + + if (global_opts.debug_level >= 1) { + /* print lat/lon/alt on one easily greppable line */ + printf(MYNAME " waypt_disp: Lat = %d Lon = %d Alt = %d\n",Lat, Lon, alt); + } + + /* Try and make sure we have a name */ + if ((! wpt->shortname) || global_opts.synthesize_shortnames) { + if (wpt->description && global_opts.synthesize_shortnames) { + name = mkshort_from_wpt(mkshort_handle, wpt); + } else if (wpt->shortname) { + name = xstrdup(wpt->shortname); + } else if (wpt->description) { + name = xstrdup(wpt->description); + } else { + name = xstrdup(""); + } + } else { + name = xstrdup(wpt->shortname); + } + + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + gbfputint32(text_len, file_out); + gbfwrite(name, 1, text_len, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " waypt_disp: Waypt name = %s\n",name); + } + + xfree(name); + + /** + * Comments are now used by the iFinder (Expedition C supports them) + */ + if (wpt->description && strcmp(wpt->description, wpt->shortname) != 0) { + comment = xstrdup(wpt->description); + text_len = strlen(comment); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + gbfputint32(text_len, file_out); + gbfwrite(comment, 1, text_len, file_out); + xfree(comment); + } else { + text_len = 0; + gbfputint32(text_len, file_out); + } + + if (wpt->creation_time > base_time_secs) { + Time = wpt->creation_time - base_time_secs; + } else { + Time = 0; + } + + if (global_opts.debug_level >= 2) { + time_t wpt_time = Time; + printf(MYNAME " waypt_disp: base_time : %d\n", (int)base_time_secs); + printf(MYNAME " waypt_disp: creation time : %d\n", (int)wpt->creation_time); + printf(MYNAME " waypt_disp: waypt time : %d\n", (int)wpt_time); + printf(MYNAME " waypt_disp: waypt time (local): %s\n", ctime(&wpt_time)); + } + + gbfputint32(Time, file_out); + + if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { + SymbolId = lowranceusr_find_icon_number_from_desc(get_cache_icon(wpt)); + } else { + SymbolId = lowranceusr_find_icon_number_from_desc(wpt->icon_descr); + } + /* If the waypoint is archived or disabled, use a "disabled" icon instead. */ + if ((wpt->gc_data->is_archived==status_true) || (wpt->gc_data->is_available==status_false)) { + SymbolId = lowranceusr_find_icon_number_from_desc("Disabled Cache"); + } + + gbfputint32(SymbolId, file_out); + + /* USER waypoint type */ + WayptType = 0; + gbfputint16(WayptType, file_out); } static void -lowranceusr_waypt_pr(const waypoint *wpt) +lowranceusr_waypt_pr(const waypoint* wpt) { - /* our personal waypoint counter */ - gbfputint16(waypt_out_count, file_out); + /* our personal waypoint counter */ + gbfputint16(waypt_out_count, file_out); - if (global_opts.debug_level >= 1) - printf(MYNAME " waypt_pr: waypoint #%d ",waypt_out_count); + if (global_opts.debug_level >= 1) { + printf(MYNAME " waypt_pr: waypoint #%d ",waypt_out_count); + } - waypt_out_count++; + waypt_out_count++; - lowranceusr_waypt_disp(wpt); + lowranceusr_waypt_disp(wpt); } /* - * In Lowrance parlance, an "Icon" is a waypoint but without any + * In Lowrance parlance, an "Icon" is a waypoint but without any * kind of a name. The header count of icons has already been written - * before we get here, so it's just a matter of spitting out + * before we get here, so it's just a matter of spitting out * 4 bytes lat * 4 bytes long * 4 bytes symbol */ static void -lowranceusr_write_icon(const waypoint *wpt) +lowranceusr_write_icon(const waypoint* wpt) { - int latmm = lat_deg_to_mm(wpt->latitude); - int lonmm = lon_deg_to_mm(wpt->longitude); - int icon = wpt->icon_descr ? - lowranceusr_find_icon_number_from_desc(wpt->icon_descr) : - 10003; - - gbfputint32(latmm, file_out); - gbfputint32(lonmm, file_out); - gbfputint32(icon, file_out); + int latmm = lat_deg_to_mm(wpt->latitude); + int lonmm = lon_deg_to_mm(wpt->longitude); + int icon = wpt->icon_descr ? + lowranceusr_find_icon_number_from_desc(wpt->icon_descr) : + 10003; + + gbfputint32(latmm, file_out); + gbfputint32(lonmm, file_out); + gbfputint32(icon, file_out); } /* @@ -806,263 +835,268 @@ lowranceusr_write_icon(const waypoint *wpt) * == Once this is known then the waypoints ought to be * == broken up into sections */ - + static void -lowranceusr_track_hdr(const route_head *trk) +lowranceusr_track_hdr(const route_head* trk) { - int text_len; - char *name, tmp_name[20]; - short num_trail_points, max_trail_size; - char visible=1; - - ++trail_count; - if (trk->rte_name) { - name = xstrdup(trk->rte_name); - } else if (trk->rte_desc) { - name = xstrdup(trk->rte_desc); - } else - { - tmp_name[0]='\0'; - snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); - name = xstrdup(tmp_name); - } - - text_len = strlen(name); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - if (global_opts.debug_level >= 1) - printf(MYNAME " track_hdr: trail name text len = %d\n", text_len); - gbfputint32(text_len, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " track_hdr: trail name = %s\n", name); - - gbfwrite(name, 1, text_len, file_out); - - num_trail_points = (short) trk->rte_waypt_ct; - max_trail_size = MAX_TRAIL_POINTS; - if (num_trail_points > max_trail_size) - num_trail_points = max_trail_size; - num_section_points = num_trail_points; - - if (global_opts.debug_level >= 1) - printf(MYNAME " track_hdr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", - num_trail_points, max_trail_size, num_section_points); - - gbfwrite(&visible, 1, 1, file_out); - gbfputint16(num_trail_points, file_out); - gbfputint16(max_trail_size, file_out); - gbfputint16(num_section_points, file_out); - xfree(name); - trail_point_count=1; + int text_len; + char* name, tmp_name[20]; + short num_trail_points, max_trail_size; + char visible=1; + + ++trail_count; + if (trk->rte_name) { + name = xstrdup(trk->rte_name); + } else if (trk->rte_desc) { + name = xstrdup(trk->rte_desc); + } else { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); + name = xstrdup(tmp_name); + } + + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + if (global_opts.debug_level >= 1) { + printf(MYNAME " track_hdr: trail name text len = %d\n", text_len); + } + gbfputint32(text_len, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " track_hdr: trail name = %s\n", name); + } + + gbfwrite(name, 1, text_len, file_out); + + num_trail_points = (short) trk->rte_waypt_ct; + max_trail_size = MAX_TRAIL_POINTS; + if (num_trail_points > max_trail_size) { + num_trail_points = max_trail_size; + } + num_section_points = num_trail_points; + + if (global_opts.debug_level >= 1) + printf(MYNAME " track_hdr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", + num_trail_points, max_trail_size, num_section_points); + + gbfwrite(&visible, 1, 1, file_out); + gbfputint16(num_trail_points, file_out); + gbfputint16(max_trail_size, file_out); + gbfputint16(num_section_points, file_out); + xfree(name); + trail_point_count=1; } static void -lowranceusr_route_hdr(const route_head *rte) +lowranceusr_route_hdr(const route_head* rte) { - int text_len; - char *name, tmp_name[20]; - short num_legs; - char route_reversed=0; - - /* route name */ - if (rte->rte_name) { - name = xstrdup(rte->rte_name); - } else if (rte->rte_desc) { - name = xstrdup(rte->rte_desc); - } else - { - tmp_name[0]='\0'; - snprintf(tmp_name, sizeof(tmp_name), "Babel R%d", ++lowrance_route_count); - name = xstrdup(tmp_name); - } - text_len = strlen(name); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - gbfputint32(text_len, file_out); - gbfwrite(name, 1, text_len, file_out); - xfree(name); - - /* num legs */ - num_legs = (short) rte->rte_waypt_ct; - gbfputint16(num_legs, file_out); - gbfwrite(&route_reversed, 1, 1, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " route_hdr: route name \"%s\" num_legs = %d\n", - rte->rte_name, num_legs); + int text_len; + char* name, tmp_name[20]; + short num_legs; + char route_reversed=0; + + /* route name */ + if (rte->rte_name) { + name = xstrdup(rte->rte_name); + } else if (rte->rte_desc) { + name = xstrdup(rte->rte_desc); + } else { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel R%d", ++lowrance_route_count); + name = xstrdup(tmp_name); + } + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + gbfputint32(text_len, file_out); + gbfwrite(name, 1, text_len, file_out); + xfree(name); + + /* num legs */ + num_legs = (short) rte->rte_waypt_ct; + gbfputint16(num_legs, file_out); + gbfwrite(&route_reversed, 1, 1, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " route_hdr: route name \"%s\" num_legs = %d\n", + rte->rte_name, num_legs); } static void -lowranceusr_track_disp(const waypoint *wpt) +lowranceusr_track_disp(const waypoint* wpt) { - int lat, lon; - - if (++trail_point_count <= MAX_TRAIL_POINTS) - { - lat = lat_deg_to_mm(wpt->latitude); - lon = lon_deg_to_mm(wpt->longitude); - - if (global_opts.debug_level >= 1) - printf(MYNAME " track_disp: Trail point #%d lat = %d long = %d\n",trail_point_count, lat, lon); - - gbfputint32(lat, file_out); - gbfputint32(lon, file_out); - gbfwrite(&continuous, 1, 1, file_out); - if (!continuous) - continuous = 1; - } + int lat, lon; + + if (++trail_point_count <= MAX_TRAIL_POINTS) { + lat = lat_deg_to_mm(wpt->latitude); + lon = lon_deg_to_mm(wpt->longitude); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " track_disp: Trail point #%d lat = %d long = %d\n",trail_point_count, lat, lon); + } + + gbfputint32(lat, file_out); + gbfputint32(lon, file_out); + gbfwrite(&continuous, 1, 1, file_out); + if (!continuous) { + continuous = 1; + } + } } static void -lowranceusr_merge_track_hdr(const route_head *trk) +lowranceusr_merge_track_hdr(const route_head* trk) { - int text_len; - char *name, tmp_name[20]; - - if (++trail_count == 1) - { - if (trk->rte_name) { - name = xstrdup(trk->rte_name); - } else if (trk->rte_desc) { - name = xstrdup(trk->rte_desc); - } else - { - tmp_name[0]='\0'; - snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); - name = xstrdup(tmp_name); - } - text_len = strlen(name); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - gbfputint32(text_len, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " track_hdr: trail name = %s\n", name); - - gbfwrite(name, 1, text_len, file_out); - } - - trail_point_count += (short) trk->rte_waypt_ct; + int text_len; + char* name, tmp_name[20]; + + if (++trail_count == 1) { + if (trk->rte_name) { + name = xstrdup(trk->rte_name); + } else if (trk->rte_desc) { + name = xstrdup(trk->rte_desc); + } else { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); + name = xstrdup(tmp_name); + } + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + gbfputint32(text_len, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " track_hdr: trail name = %s\n", name); + } + + gbfwrite(name, 1, text_len, file_out); + } + + trail_point_count += (short) trk->rte_waypt_ct; } static void -lowranceusr_merge_track_tlr(const route_head *trk) +lowranceusr_merge_track_tlr(const route_head* trk) { - short num_trail_points, max_trail_size; - char visible=1; - - if (trail_count == track_count()) /* last trail */ - { - num_trail_points = trail_point_count; - max_trail_size = MAX_TRAIL_POINTS; - if (num_trail_points > max_trail_size) - num_trail_points = max_trail_size; - num_section_points = num_trail_points; - - if (global_opts.debug_level >= 1) - printf(MYNAME " merge_track_tlr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", - num_trail_points, max_trail_size, num_section_points); - - gbfwrite(&visible, 1, 1, file_out); - gbfputint16(num_trail_points, file_out); - gbfputint16(max_trail_size, file_out); - gbfputint16(num_section_points, file_out); - } + short num_trail_points, max_trail_size; + char visible=1; + + if (trail_count == track_count()) { /* last trail */ + num_trail_points = trail_point_count; + max_trail_size = MAX_TRAIL_POINTS; + if (num_trail_points > max_trail_size) { + num_trail_points = max_trail_size; + } + num_section_points = num_trail_points; + + if (global_opts.debug_level >= 1) + printf(MYNAME " merge_track_tlr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", + num_trail_points, max_trail_size, num_section_points); + + gbfwrite(&visible, 1, 1, file_out); + gbfputint16(num_trail_points, file_out); + gbfputint16(max_trail_size, file_out); + gbfputint16(num_section_points, file_out); + } } static void -lowranceusr_merge_track_hdr_2(const route_head *trk) +lowranceusr_merge_track_hdr_2(const route_head* trk) { - continuous = 0; + continuous = 0; } static void data_write(void) { - short int NumWaypoints, MajorVersion, MinorVersion, NumRoutes, NumTrails, NumIcons; - setshort_length(mkshort_handle, 15); - MajorVersion = writing_version; - MinorVersion = 0; - - NumWaypoints = waypt_count(); - - gbfputint16(MajorVersion, file_out); - gbfputint16(MinorVersion, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " data_write: Num waypoints = %d\n", NumWaypoints); - - if (writeasicons) { - short zero = 0; - gbfputint16(zero, file_out); - } else { - gbfputint16(NumWaypoints, file_out); - waypt_disp_all(lowranceusr_waypt_pr); - } - - /* Route support added 6/21/05 */ - NumRoutes = route_count(); - gbfputint16(NumRoutes, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " data_write: Num routes = %d\n", NumRoutes); - - if (NumRoutes) - { - lowrance_route_count=0; - route_disp_all(lowranceusr_route_hdr, NULL, lowranceusr_waypt_disp); - } - - if (NumWaypoints && writeasicons) { - gbfputint16(NumWaypoints, file_out); - waypt_disp_all(lowranceusr_write_icon); - } else { - NumIcons = 0; - gbfputint16(NumIcons, file_out); - } - - /* Track support added 6/21/05 */ - NumTrails = track_count(); - - if (NumTrails && merge) - { - NumTrails = 1; - gbfputint16(NumTrails, file_out); - trail_point_count = 0; - trail_count = 0; - /* count the number of total track points */ - track_disp_all(lowranceusr_merge_track_hdr, lowranceusr_merge_track_tlr, NULL); - /* write out the new track header */ - trail_point_count = 0; - track_disp_all(lowranceusr_merge_track_hdr_2, NULL, lowranceusr_track_disp); - - } - else - { - - gbfputint16(NumTrails, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " data_write: Num tracks = %d\n", NumTrails); - - if (NumTrails) - { - trail_count=0; - track_disp_all(lowranceusr_track_hdr, NULL, lowranceusr_track_disp); - } - } + short int NumWaypoints, MajorVersion, MinorVersion, NumRoutes, NumTrails, NumIcons; + setshort_length(mkshort_handle, 15); + MajorVersion = writing_version; + MinorVersion = 0; + + NumWaypoints = waypt_count(); + + gbfputint16(MajorVersion, file_out); + gbfputint16(MinorVersion, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_write: Num waypoints = %d\n", NumWaypoints); + } + + if (writeasicons) { + short zero = 0; + gbfputint16(zero, file_out); + } else { + gbfputint16(NumWaypoints, file_out); + waypt_disp_all(lowranceusr_waypt_pr); + } + + /* Route support added 6/21/05 */ + NumRoutes = route_count(); + gbfputint16(NumRoutes, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_write: Num routes = %d\n", NumRoutes); + } + + if (NumRoutes) { + lowrance_route_count=0; + route_disp_all(lowranceusr_route_hdr, NULL, lowranceusr_waypt_disp); + } + + if (NumWaypoints && writeasicons) { + gbfputint16(NumWaypoints, file_out); + waypt_disp_all(lowranceusr_write_icon); + } else { + NumIcons = 0; + gbfputint16(NumIcons, file_out); + } + + /* Track support added 6/21/05 */ + NumTrails = track_count(); + + if (NumTrails && merge) { + NumTrails = 1; + gbfputint16(NumTrails, file_out); + trail_point_count = 0; + trail_count = 0; + /* count the number of total track points */ + track_disp_all(lowranceusr_merge_track_hdr, lowranceusr_merge_track_tlr, NULL); + /* write out the new track header */ + trail_point_count = 0; + track_disp_all(lowranceusr_merge_track_hdr_2, NULL, lowranceusr_track_disp); + + } else { + + gbfputint16(NumTrails, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_write: Num tracks = %d\n", NumTrails); + } + + if (NumTrails) { + trail_count=0; + track_disp_all(lowranceusr_track_hdr, NULL, lowranceusr_track_disp); + } + } } ff_vecs_t lowranceusr_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - lowranceusr_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + lowranceusr_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/mac/libusb/darwin.c b/gpsbabel/mac/libusb/darwin.c index d550fa6b1..749e09ecc 100644 --- a/gpsbabel/mac/libusb/darwin.c +++ b/gpsbabel/mac/libusb/darwin.c @@ -1115,7 +1115,7 @@ int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices) result = (*(device))->GetDeviceAddress(device, (USBDeviceAddress *)&address); if (usb_debug >= 2) - fprintf(stderr, "usb_os_find_devices: Found USB device at location 0x%08x\n", location); + fprintf(stderr, "usb_os_find_devices: Found USB device at location 0x%08lx\n", (long) location); /* first byte of location appears to be associated with the device's bus */ if (location >> 24 == bus_loc >> 24) { @@ -1142,8 +1142,8 @@ int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices) LIST_ADD(fdev, dev); if (usb_debug >= 2) - fprintf(stderr, "usb_os_find_devices: Found %s on %s at location 0x%08x\n", - dev->filename, bus->dirname, location); + fprintf(stderr, "usb_os_find_devices: Found %s on %s at location 0x%08lx\n", + dev->filename, bus->dirname, (long) location); } /* release the device now */ diff --git a/gpsbabel/mag_pdb.c b/gpsbabel/mag_pdb.c index c9ebcca29..2eb2b1df8 100644 --- a/gpsbabel/mag_pdb.c +++ b/gpsbabel/mag_pdb.c @@ -1,4 +1,4 @@ -/* +/* Support of Palm/OS files from Map&Guide based products like "PowerRoute" 5+6, "Motorrad Routenplaner" @@ -34,200 +34,197 @@ #define PROUTE_MAGIC 0x766d6170 /* vmap */ #define PROUTE_ROUTE 0x49444154 /* IDAT */ -static pdbfile *file_in; +static pdbfile* file_in; -static arglist_t magpdb_args[] = -{ - ARG_TERMINATOR +static arglist_t magpdb_args[] = { + ARG_TERMINATOR }; static double magpdb_to_degree(const int degx) { - int m, d, x; - double s, res; - - d = degx / 100000; - x = degx % 100000; - m = x / 1000; - x = x % 1000; - s = (double)(x) / 10; - - GPS_Math_DegMinSec_To_Deg(d, m, s, &res); - - return res; + int m, d, x; + double s, res; + + d = degx / 100000; + x = degx % 100000; + m = x / 1000; + x = x % 1000; + s = (double)(x) / 10; + + GPS_Math_DegMinSec_To_Deg(d, m, s, &res); + + return res; } static void -magpdb_read_data(const char *data, const size_t data_len) +magpdb_read_data(const char* data, const size_t data_len) { - route_head *route; - char *cin = (char *)data; - char *cend = cin + data_len; - - route = route_head_alloc(); - route_add_head(route); - - while (cin < cend) - { - char *lend; - int len; - - lend = strchr(cin, '\x0A'); - if (lend == NULL) break; - - len = (lend - cin); - if (len > 0) - { - double distance; - int hour, min; - *lend = '\0'; - - if (case_ignore_strncmp(cin, "Wegname=", 8) == 0) /* This only works with the german release */ - { /* test-data created with other releases are welcome */ - cin += 8; - if (*cin != '\0') - route->rte_name = xstrdup(cin); - } - else if (case_ignore_strncmp(cin, "Fahrzeit=", 9) == 0) - { - } - else if (case_ignore_strncmp(cin, "Kosten=", 7) == 0) - { - } - else if (case_ignore_strncmp(cin, "Entfernung=", 11) == 0) - { - } - /* check, if line starts with time and distance */ - else if (3 == sscanf(cin, "%d:%d %lf", &hour, &min, &distance)) - { - char *buff, *comma; - - /* detect time-format settings, 12,0 or 12.0 */ - - comma = strchr(cin, '.'); - buff = strchr(cin, ','); - if (comma == NULL) - comma = buff; - else - if ((buff != NULL) && (buff < comma)) - comma = buff; - if (comma != NULL) - { - char separator = *comma; - - /* now we are looking for a sequence like 0,1 NE (123456,654321) */ - - buff = xmalloc(strlen(cin) + 1); /* safe target space for sscanf( ... */ - - comma = cin; - while ((comma = strchr(comma, separator))) - { - int i, xlat, xlon; - waypoint *wpt; - char *cx; - - comma++; - - if (isdigit(*comma) == 0) continue; - if (isdigit(*(comma - 2)) == 0) continue; - - if (4 != sscanf(comma, "%d %s (%d,%d)", &i, buff, &xlon, &xlat)) continue; - if (strchr("NESW", *buff) == NULL) continue; /* north, east, ... */ - - cx = comma - 2; /* go left over delta distance */ - while (isdigit(*cx) != 0) *cx-- = '\0'; - cin = lrtrim(cin); - - for (i = 0; i < 2; i++) /* skip time and distance at start of line */ - { - cin = strchr(cin, ' '); - cin = lrtrim(cin); - } - - wpt = waypt_new(); - - wpt->latitude = magpdb_to_degree(xlat); - wpt->longitude = magpdb_to_degree(xlon); - wpt->description = xstrdup(cin); - - cx = strchr(comma, ')'); /* find tailing notes after the coordinates */ - if (cx != NULL) - { - char *tail = lrtrim(++cx); - if (*tail != '\0') - { - wpt->notes = xstrdup(tail); - } - } - /* generate some waypoints from our route-only format */ - if ((*cin != '-') && (case_ignore_strncmp(cin, "bei ", 4) != 0)) - waypt_add(waypt_dupe(wpt)); - - route_add_wpt(route, wpt); - break; - } - xfree(buff); - } - } - - } - cin = lend + 1; - } + route_head* route; + char* cin = (char*)data; + char* cend = cin + data_len; + + route = route_head_alloc(); + route_add_head(route); + + while (cin < cend) { + char* lend; + int len; + + lend = strchr(cin, '\x0A'); + if (lend == NULL) { + break; + } + + len = (lend - cin); + if (len > 0) { + double distance; + int hour, min; + *lend = '\0'; + + if (case_ignore_strncmp(cin, "Wegname=", 8) == 0) { /* This only works with the german release */ + /* test-data created with other releases are welcome */ + cin += 8; + if (*cin != '\0') { + route->rte_name = xstrdup(cin); + } + } else if (case_ignore_strncmp(cin, "Fahrzeit=", 9) == 0) { + } else if (case_ignore_strncmp(cin, "Kosten=", 7) == 0) { + } else if (case_ignore_strncmp(cin, "Entfernung=", 11) == 0) { + } + /* check, if line starts with time and distance */ + else if (3 == sscanf(cin, "%d:%d %lf", &hour, &min, &distance)) { + char* buff, *comma; + + /* detect time-format settings, 12,0 or 12.0 */ + + comma = strchr(cin, '.'); + buff = strchr(cin, ','); + if (comma == NULL) { + comma = buff; + } else if ((buff != NULL) && (buff < comma)) { + comma = buff; + } + if (comma != NULL) { + char separator = *comma; + + /* now we are looking for a sequence like 0,1 NE (123456,654321) */ + + buff = (char*) xmalloc(strlen(cin) + 1); /* safe target space for sscanf( ... */ + + comma = cin; + while ((comma = strchr(comma, separator))) { + int i, xlat, xlon; + waypoint* wpt; + char* cx; + + comma++; + + if (isdigit(*comma) == 0) { + continue; + } + if (isdigit(*(comma - 2)) == 0) { + continue; + } + + if (4 != sscanf(comma, "%d %s (%d,%d)", &i, buff, &xlon, &xlat)) { + continue; + } + if (strchr("NESW", *buff) == NULL) { + continue; /* north, east, ... */ + } + + cx = comma - 2; /* go left over delta distance */ + while (isdigit(*cx) != 0) { + *cx-- = '\0'; + } + cin = lrtrim(cin); + + for (i = 0; i < 2; i++) { /* skip time and distance at start of line */ + cin = strchr(cin, ' '); + cin = lrtrim(cin); + } + + wpt = waypt_new(); + + wpt->latitude = magpdb_to_degree(xlat); + wpt->longitude = magpdb_to_degree(xlon); + wpt->description = xstrdup(cin); + + cx = strchr(comma, ')'); /* find tailing notes after the coordinates */ + if (cx != NULL) { + char* tail = lrtrim(++cx); + if (*tail != '\0') { + wpt->notes = xstrdup(tail); + } + } + /* generate some waypoints from our route-only format */ + if ((*cin != '-') && (case_ignore_strncmp(cin, "bei ", 4) != 0)) { + waypt_add(waypt_dupe(wpt)); + } + + route_add_wpt(route, wpt); + break; + } + xfree(buff); + } + } + + } + cin = lend + 1; + } } /* ============================================================================================ * &&& gobal callbacks &&& * ----------------------------------------------------------------------------------------- */ -static void magpdb_rd_init(const char *fname) +static void magpdb_rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void magpdb_rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void magpdb_read(void) { - pdbrec_t *pdb_rec; - - is_fatal((file_in->creator != PROUTE_MAGIC), /* identify the database */ - MYNAME ": Not a Map&Guide pdb file (0x%08x).", file_in->creator); - - is_fatal((file_in->version != 0), /* only version "0" currently seen and tested */ - MYNAME ": This file is from an unsupported version (%d) of Map&Guide and is unsupported.", file_in->version + 5); - - is_fatal((file_in->type != PROUTE_ROUTE), - MYNAME ": Unknown pdb data type (0x%08x).", file_in->type); - - for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - char *data = (char *)pdb_rec->data; - - if (be_read16(data) == 0) - { - int len = be_read16(data + 2); - magpdb_read_data(data + 4, len); - } - } + pdbrec_t* pdb_rec; + + is_fatal((file_in->creator != PROUTE_MAGIC), /* identify the database */ + MYNAME ": Not a Map&Guide pdb file (0x%08x).", file_in->creator); + + is_fatal((file_in->version != 0), /* only version "0" currently seen and tested */ + MYNAME ": This file is from an unsupported version (%d) of Map&Guide and is unsupported.", file_in->version + 5); + + is_fatal((file_in->type != PROUTE_ROUTE), + MYNAME ": Unknown pdb data type (0x%08x).", file_in->type); + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + char* data = (char*)pdb_rec->data; + + if (be_read16(data) == 0) { + int len = be_read16(data + 2); + magpdb_read_data(data + 4, len); + } + } } /* ======================================================================================= */ ff_vecs_t magpdb_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_none, ff_cap_read }, /* real route + emulated waypoints */ - magpdb_rd_init, - NULL, - magpdb_rd_deinit, - NULL, - magpdb_read, - NULL, - NULL, - magpdb_args, - CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_read }, /* real route + emulated waypoints */ + magpdb_rd_init, + NULL, + magpdb_rd_deinit, + NULL, + magpdb_read, + NULL, + NULL, + magpdb_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/magellan.h b/gpsbabel/magellan.h index 062742634..582f9c75a 100644 --- a/gpsbabel/magellan.h +++ b/gpsbabel/magellan.h @@ -24,31 +24,31 @@ * (Donations welcome. :-) */ typedef enum { - mm_unknown = 0 , - mm_gps315320, - mm_map410, - mm_map330, - mm_gps310, - mm_meridian, - mm_sportrak + mm_unknown = 0 , + mm_gps315320, + mm_map410, + mm_map330, + mm_gps310, + mm_meridian, + mm_sportrak } meridian_model; typedef struct pid_to_model { - meridian_model model; - int pid; - const char *model_n; + meridian_model model; + int pid; + const char* model_n; } pid_to_model_t; typedef struct icon_mapping { - const char *token; - const char *icon; + const char* token; + const char* icon; } icon_mapping_t; -const char * mag_find_descr_from_token(const char *token); -const char * mag_find_token_from_descr(const char *icon); +const char* mag_find_descr_from_token(const char* token); +const char* mag_find_token_from_descr(const char* icon); -unsigned int mag_checksum(const char *const buf); -char * m330_cleanse(char *istring); +unsigned int mag_checksum(const char* const buf); +char* m330_cleanse(char* istring); -waypoint * mag_trkparse(char *trkmsg); -void mag_rteparse(char *rtemsg); +waypoint* mag_trkparse(char* trkmsg); +void mag_rteparse(char* rtemsg); diff --git a/gpsbabel/maggeo.c b/gpsbabel/maggeo.c index 68dddb355..954729d84 100644 --- a/gpsbabel/maggeo.c +++ b/gpsbabel/maggeo.c @@ -30,155 +30,165 @@ /* Turn this on (remove) after 5.2 becomes widespread. */ #define FIRMWARE_DOES_88591 0 -static gbfile *maggeofile_in; -static gbfile *maggeofile_out; +static gbfile* maggeofile_in; +static gbfile* maggeofile_out; static short_handle desc_handle = NULL; -static time_t maggeo_parsedate(char *dmy); +static time_t maggeo_parsedate(char* dmy); static void -maggeo_writemsg(const char * const buf) +maggeo_writemsg(const char* const buf) { - unsigned int osum = mag_checksum(buf); - gbfprintf(maggeofile_out, "$%s*%02X\r\n",buf, osum); + unsigned int osum = mag_checksum(buf); + gbfprintf(maggeofile_out, "$%s*%02X\r\n",buf, osum); } static void -maggeo_rd_init(const char *fname) +maggeo_rd_init(const char* fname) { - maggeofile_in = gbfopen(fname, "rb", MYNAME); + maggeofile_in = gbfopen(fname, "rb", MYNAME); } static void maggeo_rd_deinit(void) { - gbfclose(maggeofile_in); + gbfclose(maggeofile_in); } static void -maggeo_wr_init(const char *fname) +maggeo_wr_init(const char* fname) { - if (waypt_count() > 200) { - fatal(MYNAME ": eXplorist does not support more than 200 waypoints in one .gs file.\nDecrease the number of waypoints sent.\n"); - } - maggeofile_out = gbfopen(fname, "wb", MYNAME); - desc_handle = mkshort_new_handle(); - setshort_length(desc_handle, 20); - setshort_badchars(desc_handle, "\"$,"); + if (waypt_count() > 200) { + fatal(MYNAME ": eXplorist does not support more than 200 waypoints in one .gs file.\nDecrease the number of waypoints sent.\n"); + } + maggeofile_out = gbfopen(fname, "wb", MYNAME); + desc_handle = mkshort_new_handle(); + setshort_length(desc_handle, 20); + setshort_badchars(desc_handle, "\"$,"); } static void maggeo_wr_deinit(void) { - maggeo_writemsg("PMGNCMD,END"); - mkshort_del_handle(&desc_handle); - gbfclose(maggeofile_out); + maggeo_writemsg("PMGNCMD,END"); + mkshort_del_handle(&desc_handle); + gbfclose(maggeofile_out); } static void maggeo_read(void) { - char *buff; - - while ((buff = gbfgetstr(maggeofile_in))) { - waypoint *wpt_tmp; - geocache_data *gcdata; - char *s = NULL; - int fld; - - buff = lrtrim(buff); - if (*buff == '\0') continue; - if (strncmp(buff, "$PMGNGEO,", 9)) continue; - - buff += 9; /* skip field no. 1 */ - fld = 1; - - wpt_tmp = waypt_new(); - gcdata = waypt_alloc_gc_data(wpt_tmp); - - while ((s = csv_lineparse(buff, ",", "", fld++))) { - buff = NULL; - - s = lrtrim(s); - if (*s == '\0') continue; - - switch(fld) { - case 2: - wpt_tmp->latitude = ddmm2degrees(atof(s)); - break; - case 3: - if (s[0] == 'S') - wpt_tmp->latitude = -wpt_tmp->latitude; - break; - case 4: - wpt_tmp->longitude = ddmm2degrees(atof(s)); - break; - case 5: - if (s[0] == 'W') - wpt_tmp->longitude = -wpt_tmp->longitude; - break; - case 6: - wpt_tmp->altitude = atof(s); - break; - case 7: - if (s[0] == 'F') wpt_tmp->altitude = METERS_TO_FEET(wpt_tmp->altitude); - break; - case 8: - wpt_tmp->shortname = xstrdup(s); - break; - case 9: - wpt_tmp->description = xstrdup(s); - break; - case 10: - gcdata->placer = xstrdup(s); - break; - case 11: - gcdata->hint = xstrdup(s); - break; - case 12: // cache type - gcdata->type = gs_mktype(s); - break; - case 13: - wpt_tmp->creation_time = maggeo_parsedate(s); - break; - case 14: // last found date is ignored. - break; - case 15: - gcdata->diff = 10 * atof(s); - break; - case 16: - gcdata->terr = 10 * atof(s); - break; - } - } - waypt_add(wpt_tmp); - } + char* buff; + + while ((buff = gbfgetstr(maggeofile_in))) { + waypoint* wpt_tmp; + geocache_data* gcdata; + char* s = NULL; + int fld; + + buff = lrtrim(buff); + if (*buff == '\0') { + continue; + } + if (strncmp(buff, "$PMGNGEO,", 9)) { + continue; + } + + buff += 9; /* skip field no. 1 */ + fld = 1; + + wpt_tmp = waypt_new(); + gcdata = waypt_alloc_gc_data(wpt_tmp); + + while ((s = csv_lineparse(buff, ",", "", fld++))) { + buff = NULL; + + s = lrtrim(s); + if (*s == '\0') { + continue; + } + + switch (fld) { + case 2: + wpt_tmp->latitude = ddmm2degrees(atof(s)); + break; + case 3: + if (s[0] == 'S') { + wpt_tmp->latitude = -wpt_tmp->latitude; + } + break; + case 4: + wpt_tmp->longitude = ddmm2degrees(atof(s)); + break; + case 5: + if (s[0] == 'W') { + wpt_tmp->longitude = -wpt_tmp->longitude; + } + break; + case 6: + wpt_tmp->altitude = atof(s); + break; + case 7: + if (s[0] == 'F') { + wpt_tmp->altitude = METERS_TO_FEET(wpt_tmp->altitude); + } + break; + case 8: + wpt_tmp->shortname = xstrdup(s); + break; + case 9: + wpt_tmp->description = xstrdup(s); + break; + case 10: + gcdata->placer = xstrdup(s); + break; + case 11: + gcdata->hint = xstrdup(s); + break; + case 12: // cache type + gcdata->type = gs_mktype(s); + break; + case 13: + wpt_tmp->creation_time = maggeo_parsedate(s); + break; + case 14: // last found date is ignored. + break; + case 15: + gcdata->diff = 10 * atof(s); + break; + case 16: + gcdata->terr = 10 * atof(s); + break; + } + } + waypt_add(wpt_tmp); + } } /* * Note: returns allocated buffer that must be freed by caller. */ -static -char * +static +char* maggeo_fmtdate(time_t t) { - #define SZ 16 - - struct tm *tm = NULL; - int date; - char *cbuf = xmalloc(SZ); - - cbuf[0] = '\0'; - if (t > 0) { - tm = gmtime(&t); - if ( tm ) { - date = tm->tm_mday * 100000 + (1+tm->tm_mon) * 1000 + - tm->tm_year; - snprintf(cbuf, SZ, "%07d", date); - } - } - return cbuf; +#define SZ 16 + + struct tm* tm = NULL; + int date; + char* cbuf = (char*) xmalloc(SZ); + + cbuf[0] = '\0'; + if (t > 0) { + tm = gmtime(&t); + if (tm) { + date = tm->tm_mday * 100000 + (1+tm->tm_mon) * 1000 + + tm->tm_year; + snprintf(cbuf, SZ, "%07d", date); + } + } + return cbuf; } /* @@ -187,171 +197,181 @@ maggeo_fmtdate(time_t t) * century is three digits but anything from before 2000, we'd have * two digit years. This makes this easier to parse as strings. */ -static time_t maggeo_parsedate(char *dmy) +static time_t maggeo_parsedate(char* dmy) { - struct tm tm; - char dd[3]; - char mm[3]; + struct tm tm; + char dd[3]; + char mm[3]; - if (strlen(dmy) < 5) return 0; + if (strlen(dmy) < 5) { + return 0; + } - memset(&tm, 0, sizeof(tm)); + memset(&tm, 0, sizeof(tm)); - dd[0] = dmy[0]; - dd[1] = dmy[1]; - dd[2] = 0; + dd[0] = dmy[0]; + dd[1] = dmy[1]; + dd[2] = 0; - mm[0] = dmy[2]; - mm[1] = dmy[3]; - mm[2] = 0; + mm[0] = dmy[2]; + mm[1] = dmy[3]; + mm[2] = 0; - tm.tm_mday = atoi(dd); - tm.tm_mon = atoi(mm) - 1; - tm.tm_year = atoi(dmy + 4); + tm.tm_mday = atoi(dd); + tm.tm_mon = atoi(mm) - 1; + tm.tm_year = atoi(dmy + 4); - return mktime(&tm); + return mktime(&tm); } /* - * Append an optional UTF string to buf, prepending a comma, + * Append an optional UTF string to buf, prepending a comma, * cleansing it of NMEA-isms and decomposing to ASCII as we go. */ static void -append(char *buf, const char *str) +append(char* buf, const char* str) { - char *cleansed1, *cleansed2; + char* cleansed1, *cleansed2; - strcat(buf, ","); + strcat(buf, ","); - if (!str) { - return; - } + if (!str) { + return; + } - cleansed1 = xstrdup(str); + cleansed1 = xstrdup(str); #if FIRMWARE_DOES_88591 -/* Actually, this function needs needs refactored... */ - cleansed2 = xstrdup(cleansed1); + /* Actually, this function needs needs refactored... */ + cleansed2 = xstrdup(cleansed1); #else - cleansed2 = m330_cleanse(cleansed1); + cleansed2 = m330_cleanse(cleansed1); #endif - strcat(buf, cleansed2); + strcat(buf, cleansed2); - xfree(cleansed1); - xfree(cleansed2); + xfree(cleansed1); + xfree(cleansed2); } static void -maggeo_waypt_pr(const waypoint *waypointp) +maggeo_waypt_pr(const waypoint* waypointp) { - char obuf[4096]; - double ilon, ilat; - double lon, lat; - int lon_deg, lat_deg; - char *shortname; - char *cname = NULL; - const char *ctype = NULL; - char *placer = NULL; - char *lfounddate = NULL; - char *placeddate = NULL; - - ilat = waypointp->latitude; - ilon = waypointp->longitude; - shortname = waypointp->shortname; - - lon = fabs(ilon); - lat = fabs(ilat); - - lon_deg = lon; - lat_deg = lat; - - lon = (lon - lon_deg) * 60.0; - lat = (lat - lat_deg) * 60.0; - - lon = (lon_deg * 100.0 + lon); - lat = (lat_deg * 100.0 + lat); - - /* - * For some reason, Magellan used exactly the GPX spellings of - * everything except this one... - */ - if (waypointp->gc_data->type == gt_suprise) { - ctype = "Mystery Cache"; - } else { - ctype = gs_get_cachetype(waypointp->gc_data->type); - } - placeddate = maggeo_fmtdate(waypointp->creation_time); - lfounddate = maggeo_fmtdate(waypointp->gc_data->last_found); - cname = mkshort(desc_handle, waypointp->notes ? waypointp->notes : waypointp->description); - placer = waypointp->gc_data->placer; - - /* - * As of this writing on 05/04, the firmware in the units will - * let you write fields of just about any width, but appears to - * only use the following: - * shortname - 8 chars - * cname - 20 chars (scrolls in some places, not others) - * placer - display limited by width - * hint - 50 chars - * cache type - appears to be parsed by f/w for icon matching. - * - * - */ - snprintf(obuf, sizeof(obuf), - "PMGNGEO,%4.3f,%c,%08.3f,%c,%04.0f,F", - lat, ilat < 0 ? 'S' : 'N', - lon, ilon < 0 ? 'W' : 'E', - waypointp->altitude == unknown_alt ? - 0 : waypointp->altitude); - append(obuf, shortname); - append(obuf, cname); - append(obuf, placer); - append(obuf, waypointp->gc_data->hint); - append(obuf, ctype); - append(obuf, placeddate); - append(obuf, lfounddate); - - if (waypointp->gc_data->diff/10.0) - sprintf(obuf + strlen(obuf), ",%3.1f", - waypointp->gc_data->diff/10.0); - else - strcat(obuf, ","); - - if (waypointp->gc_data->terr/10.0) - sprintf(obuf + strlen(obuf), ",%3.1f", - waypointp->gc_data->terr/10.0); - else - strcat(obuf, ","); - - if (lfounddate) xfree(lfounddate); - if (placeddate) xfree(placeddate); - if (cname) xfree(cname); - - maggeo_writemsg(obuf); + char obuf[4096]; + double ilon, ilat; + double lon, lat; + int lon_deg, lat_deg; + char* shortname; + char* cname = NULL; + const char* ctype = NULL; + char* placer = NULL; + char* lfounddate = NULL; + char* placeddate = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + shortname = waypointp->shortname; + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + /* + * For some reason, Magellan used exactly the GPX spellings of + * everything except this one... + */ + if (waypointp->gc_data->type == gt_suprise) { + ctype = "Mystery Cache"; + } else { + ctype = gs_get_cachetype(waypointp->gc_data->type); + } + placeddate = maggeo_fmtdate(waypointp->creation_time); + lfounddate = maggeo_fmtdate(waypointp->gc_data->last_found); + cname = mkshort(desc_handle, waypointp->notes ? waypointp->notes : waypointp->description); + placer = waypointp->gc_data->placer; + + /* + * As of this writing on 05/04, the firmware in the units will + * let you write fields of just about any width, but appears to + * only use the following: + * shortname - 8 chars + * cname - 20 chars (scrolls in some places, not others) + * placer - display limited by width + * hint - 50 chars + * cache type - appears to be parsed by f/w for icon matching. + * + * + */ + snprintf(obuf, sizeof(obuf), + "PMGNGEO,%4.3f,%c,%08.3f,%c,%04.0f,F", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude); + append(obuf, shortname); + append(obuf, cname); + append(obuf, placer); + append(obuf, waypointp->gc_data->hint); + append(obuf, ctype); + append(obuf, placeddate); + append(obuf, lfounddate); + + if (waypointp->gc_data->diff/10.0) + sprintf(obuf + strlen(obuf), ",%3.1f", + waypointp->gc_data->diff/10.0); + else { + strcat(obuf, ","); + } + + if (waypointp->gc_data->terr/10.0) + sprintf(obuf + strlen(obuf), ",%3.1f", + waypointp->gc_data->terr/10.0); + else { + strcat(obuf, ","); + } + + if (lfounddate) { + xfree(lfounddate); + } + if (placeddate) { + xfree(placeddate); + } + if (cname) { + xfree(cname); + } + + maggeo_writemsg(obuf); } static void maggeo_write(void) { - waypt_disp_all(maggeo_waypt_pr); + waypt_disp_all(maggeo_waypt_pr); } ff_vecs_t maggeo_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none }, - maggeo_rd_init, - maggeo_wr_init, - maggeo_rd_deinit, - maggeo_wr_deinit, - maggeo_read, - maggeo_write, - NULL, - NULL, + ff_type_file, + { (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none, ff_cap_none }, + maggeo_rd_init, + maggeo_wr_init, + maggeo_rd_deinit, + maggeo_wr_deinit, + maggeo_read, + maggeo_write, + NULL, + NULL, #if FIRMWARE_DOES_88591 - CET_CHARSET_LATIN1, 0 /* CET-REVIEW */ + CET_CHARSET_LATIN1, 0 /* CET-REVIEW */ #else - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ #endif }; diff --git a/gpsbabel/magnav.c b/gpsbabel/magnav.c index 038cd8919..49a6a1e28 100644 --- a/gpsbabel/magnav.c +++ b/gpsbabel/magnav.c @@ -28,226 +28,225 @@ #define MYCREATOR 0x4d47747a /* MGtz */ struct record { - pdb_16 crt_sec; /* Big endian, creation time */ - pdb_16 crt_min; - pdb_16 crt_hour; - pdb_16 crt_mday; - pdb_16 crt_mon; /* 1 = Jan */ - pdb_16 crt_year; /* includes century. */ - pdb_16 unknown; - pdb_16 xx_sec; /* appears to be time, but we don't know what it is. */ - pdb_16 xx_min; - pdb_16 xx_hour; - pdb_16 xx_mday; - pdb_16 xx_mon; - pdb_16 xx_year; - pdb_16 unknown2; - pdb_32 latitude; /* lat * 1e5 */ - pdb_32 longitude; /* lon * 1e5 */ - pdb_32 elevation; /* meters */ - char plot; /* 1 = plot on map screen. default = 0 */ - char unknown3; /* always 'a' */ + pdb_16 crt_sec; /* Big endian, creation time */ + pdb_16 crt_min; + pdb_16 crt_hour; + pdb_16 crt_mday; + pdb_16 crt_mon; /* 1 = Jan */ + pdb_16 crt_year; /* includes century. */ + pdb_16 unknown; + pdb_16 xx_sec; /* appears to be time, but we don't know what it is. */ + pdb_16 xx_min; + pdb_16 xx_hour; + pdb_16 xx_mday; + pdb_16 xx_mon; + pdb_16 xx_year; + pdb_16 unknown2; + pdb_32 latitude; /* lat * 1e5 */ + pdb_32 longitude; /* lon * 1e5 */ + pdb_32 elevation; /* meters */ + char plot; /* 1 = plot on map screen. default = 0 */ + char unknown3; /* always 'a' */ }; -static pdbfile *file_in; -static pdbfile *file_out; +static pdbfile* file_in; +static pdbfile* file_out; static short_handle mkshort_handle; static int ct; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, 20); - ct = 0; + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, 20); + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - mkshort_del_handle(&mkshort_handle); + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; - - if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { - fatal(MYNAME ": Not a Magellan Navigator file.\n"); - } - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { - waypoint *wpt_tmp; - char *vdata; - struct tm tm; - - memset (&tm, 0, sizeof(tm)); - wpt_tmp = waypt_new(); - rec = (struct record *) pdb_rec->data; - wpt_tmp->altitude = be_read32(&rec->elevation); - - wpt_tmp->longitude = be_read32(&rec->longitude) / 1e5; - wpt_tmp->latitude = be_read32(&rec->latitude) / 1e5; - - vdata = (char *) pdb_rec->data + sizeof(*rec); - - wpt_tmp->shortname = xstrdup(vdata); - vdata += strlen (vdata) + 1; - - wpt_tmp->description = xstrdup(vdata); - vdata += strlen (vdata) + 1; - - tm.tm_sec = be_read16(&rec->crt_sec); - tm.tm_min = be_read16(&rec->crt_min); - tm.tm_hour = be_read16(&rec->crt_hour); - tm.tm_mday = be_read16(&rec->crt_mday); - tm.tm_mon = be_read16(&rec->crt_mon) - 1; - tm.tm_year = be_read16(&rec->crt_year) - 1900; - if (mkgmtime(&tm) > 0) - wpt_tmp->creation_time = mktime(&tm); - waypt_add(wpt_tmp); - - } + struct record* rec; + pdbrec_t* pdb_rec; + + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a Magellan Navigator file.\n"); + } + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint* wpt_tmp; + char* vdata; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + wpt_tmp = waypt_new(); + rec = (struct record*) pdb_rec->data; + wpt_tmp->altitude = be_read32(&rec->elevation); + + wpt_tmp->longitude = be_read32(&rec->longitude) / 1e5; + wpt_tmp->latitude = be_read32(&rec->latitude) / 1e5; + + vdata = (char*) pdb_rec->data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata += strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata += strlen(vdata) + 1; + + tm.tm_sec = be_read16(&rec->crt_sec); + tm.tm_min = be_read16(&rec->crt_min); + tm.tm_hour = be_read16(&rec->crt_hour); + tm.tm_mday = be_read16(&rec->crt_mday); + tm.tm_mon = be_read16(&rec->crt_mon) - 1; + tm.tm_year = be_read16(&rec->crt_year) - 1900; + if (mkgmtime(&tm) > 0) { + wpt_tmp->creation_time = mktime(&tm); + } + waypt_add(wpt_tmp); + + } } static void -my_writewpt(const waypoint *wpt) +my_writewpt(const waypoint* wpt) { - struct record *rec; - struct tm *tm; - char *vdata; - time_t tm_t; - const char *sn = global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, wpt) : - wpt->shortname; - - rec = xcalloc(sizeof(*rec)+56,1); - - tm = NULL; - if ( wpt->creation_time ) { - tm = gmtime( &wpt->creation_time); - } - if ( !tm ) { - tm_t = current_time(); - tm = gmtime( &tm_t ); - } - - be_write16( &rec->crt_sec, tm->tm_sec ); - be_write16( &rec->crt_min, tm->tm_min ); - be_write16( &rec->crt_hour, tm->tm_hour ); - be_write16( &rec->crt_mday, tm->tm_mday ); - be_write16( &rec->crt_mon, tm->tm_mon + 1 ); - be_write16( &rec->crt_year, tm->tm_year + 1900 ); - - be_write16( &rec->unknown, 0); - - be_write16( &rec->xx_sec, tm->tm_sec ); - be_write16( &rec->xx_min, tm->tm_min ); - be_write16( &rec->xx_hour, tm->tm_hour ); - be_write16( &rec->xx_mday, tm->tm_mday ); - be_write16( &rec->xx_mon, tm->tm_mon + 1 ); - be_write16( &rec->xx_year, tm->tm_year + 1900 ); - - be_write16( &rec->unknown2, 0); - - be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); - be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); - be_write32(&rec->elevation, (unsigned int) (wpt->altitude)); - - rec->plot = 0; - rec->unknown3 = 'a'; - - vdata = (char *)rec + sizeof(*rec); - if ( sn ) { - strncpy( vdata, sn, 21 ); - vdata[20] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - if ( wpt->description ) { - strncpy( vdata, wpt->description, 33 ); - vdata[32] = '\0'; - } - else { - vdata[0] = '\0'; - } - vdata += strlen( vdata ) + 1; - vdata[0] = '\0'; - vdata[1] = '\0'; - vdata += 2; - - pdb_write_rec(file_out, 0, 0, ct++, rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct record* rec; + struct tm* tm; + char* vdata; + time_t tm_t; + const char* sn = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname; + + rec = (struct record*) xcalloc(sizeof(*rec)+56,1); + + tm = NULL; + if (wpt->creation_time) { + tm = gmtime(&wpt->creation_time); + } + if (!tm) { + tm_t = current_time(); + tm = gmtime(&tm_t); + } + + be_write16(&rec->crt_sec, tm->tm_sec); + be_write16(&rec->crt_min, tm->tm_min); + be_write16(&rec->crt_hour, tm->tm_hour); + be_write16(&rec->crt_mday, tm->tm_mday); + be_write16(&rec->crt_mon, tm->tm_mon + 1); + be_write16(&rec->crt_year, tm->tm_year + 1900); + + be_write16(&rec->unknown, 0); + + be_write16(&rec->xx_sec, tm->tm_sec); + be_write16(&rec->xx_min, tm->tm_min); + be_write16(&rec->xx_hour, tm->tm_hour); + be_write16(&rec->xx_mday, tm->tm_mday); + be_write16(&rec->xx_mon, tm->tm_mon + 1); + be_write16(&rec->xx_year, tm->tm_year + 1900); + + be_write16(&rec->unknown2, 0); + + be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); + be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); + be_write32(&rec->elevation, (unsigned int)(wpt->altitude)); + + rec->plot = 0; + rec->unknown3 = 'a'; + + vdata = (char*)rec + sizeof(*rec); + if (sn) { + strncpy(vdata, sn, 21); + vdata[20] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + if (wpt->description) { + strncpy(vdata, wpt->description, 33); + vdata[32] = '\0'; + } else { + vdata[0] = '\0'; + } + vdata += strlen(vdata) + 1; + vdata[0] = '\0'; + vdata[1] = '\0'; + vdata += 2; + + pdb_write_rec(file_out, 0, 0, ct++, rec, (char*)vdata - (char*)rec); + + xfree(rec); } static void data_write(void) { - static char *appinfo = - "\0\x01" - "User\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\x01\x02\x03\x04\x05\x06\x07\x08" - "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; - - strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - file_out->appinfo = (void *)appinfo; - file_out->appinfo_len = 276; - - waypt_disp_all(my_writewpt); + static char* appinfo = + "\0\x01" + "User\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; + + strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + file_out->appinfo = (void*)appinfo; + file_out->appinfo_len = 276; + + waypt_disp_all(my_writewpt); } ff_vecs_t magnav_vec = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/magproto.c b/gpsbabel/magproto.c index 96aba229f..40da8aa28 100644 --- a/gpsbabel/magproto.c +++ b/gpsbabel/magproto.c @@ -1,7 +1,8 @@ /* Communicate Thales/Magellan serial protocol. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, + 2008, 2010 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +26,11 @@ #include "defs.h" #include "magellan.h" #include "gbser.h" +#include "explorist_ini.h" + +#if HAVE_GLOB +#include +#endif static int bitrate = 4800; static int wptcmtcnt; @@ -36,22 +42,27 @@ static int broken_sportrak; #define debug_serial (global_opts.debug_level > 1) -static char *termread(char *ibuf, int size); -static void termwrite(char *obuf, int size); +static char* termread(char* ibuf, int size); +static void termwrite(char* obuf, int size); static void mag_readmsg(gpsdata_type objective); static void mag_handon(void); static void mag_handoff(void); static short_handle mkshort_handle = NULL; -static char *deficon = NULL; -static char *bs = NULL; -static char *cmts = NULL; -static char *noack = NULL; -static char *nukewpt = NULL; +static char* deficon = NULL; +static char* bs = NULL; +static char* cmts = NULL; +static char* noack = NULL; +static char* nukewpt = NULL; static int route_out_count; static int waypoint_read_count; static int wpt_len = 8; -static const char *curfname; +static const char* curfname; static int extension_hint; +// For Explorist GC/510/610/710 familes, bludgeon in GPX support. +// (This has nothing to do with the Explorist 100...600 products.) +static ff_vecs_t* gpx_vec; +static mag_info* explorist_info; +static char** os_gpx_files(const char* dirname); /* * Magellan's firmware is *horribly* slow to send the next packet after @@ -64,336 +75,336 @@ static int extension_hint; static int suppress_ack; typedef enum { - mrs_handoff = 0, - mrs_handon, - mrs_awaiting_ack + mrs_handoff = 0, + mrs_handon, + mrs_awaiting_ack } mag_rxstate; /* * An individual element of a route. */ typedef struct mag_rte_elem { - queue Q; /* My link pointers */ - char *wpt_name; - char *wpt_icon; + queue Q; /* My link pointers */ + char* wpt_name; + char* wpt_icon; } mag_rte_elem; /* * A header of a route. Related elements of a route belong to this. */ -typedef struct mag_rte_head { - queue Q; /* Queue head for child rte_elems */ - char *rte_name; - int nelems; +typedef struct mag_rte_head_ { + queue Q; /* Queue head for child rte_elems */ + char* rte_name; + int nelems; } mag_rte_head; static queue rte_wpt_tmp; /* temporary PGMNWPL msgs for routes */ -static gbfile *magfile_h; +static gbfile* magfile_h; static mag_rxstate magrxstate; static int mag_error; static unsigned int last_rx_csum; static int found_done; static int got_version; static int is_file = 0; -static route_head *trk_head; +static route_head* trk_head; static int ignore_unable; -static waypoint * mag_wptparse(char *); -typedef char * (cleanse_fn) (char *); -static cleanse_fn *mag_cleanse; +static waypoint* mag_wptparse(char*); +typedef char* (cleanse_fn)(char*); +static cleanse_fn* mag_cleanse; +static const char** os_get_magellan_mountpoints(); static icon_mapping_t gps315_icon_table[] = { - { "a", "filled circle" }, - { "b", "box" }, - { "c", "red buoy" }, - { "d", "green buoy" }, - { "e", "buoy" }, - { "f", "rocks" }, - { "g", "red daymark" }, - { "h", "green daymark" }, - { "i", "bell" }, - { "j", "danger" }, - { "k", "diver down" }, - { "l", "fish" }, - { "m", "house" }, - { "n", "mark" }, - { "o", "car" }, - { "p", "tent" }, - { "q", "boat" }, - { "r", "food" }, - { "s", "fuel" }, - { "t", "tree" }, - { NULL, NULL } + { "a", "filled circle" }, + { "b", "box" }, + { "c", "red buoy" }, + { "d", "green buoy" }, + { "e", "buoy" }, + { "f", "rocks" }, + { "g", "red daymark" }, + { "h", "green daymark" }, + { "i", "bell" }, + { "j", "danger" }, + { "k", "diver down" }, + { "l", "fish" }, + { "m", "house" }, + { "n", "mark" }, + { "o", "car" }, + { "p", "tent" }, + { "q", "boat" }, + { "r", "food" }, + { "s", "fuel" }, + { "t", "tree" }, + { NULL, NULL } }; static icon_mapping_t map330_icon_table[] = { - { "a", "crossed square" }, - { "b", "box" }, - { "c", "house" }, - { "d", "aerial" }, - { "e", "airport" }, - { "f", "amusement park" }, - { "g", "ATM" }, - { "g", "Bank" }, - { "h", "auto repair" }, - { "i", "boating" }, - { "j", "camping" }, - { "k", "exit ramp" }, - { "l", "first aid" }, - { "m", "nav aid" }, - { "n", "buoy" }, - { "o", "fuel" }, - { "p", "garden" }, - { "q", "golf" }, - { "r", "hotel" }, - { "s", "hunting/fishing" }, - { "t", "large city" }, - { "u", "lighthouse" }, - { "v", "major city" }, - { "w", "marina" }, - { "x", "medium city" }, - { "y", "museum" }, - { "z", "obstruction" }, - { "aa", "park" }, - { "ab", "resort" }, - { "ac", "restaurant" }, - { "ad", "rock" }, - { "ae", "scuba" }, - { "af", "RV service" }, - { "ag", "shooting" }, - { "ah", "sight seeing" }, - { "ai", "small city" }, - { "aj", "sounding" }, - { "ak", "sports arena" }, - { "al", "tourist info" }, - { "am", "truck service" }, - { "an", "winery" }, - { "ao", "wreck" }, - { "ap", "zoo" }, - { "ah", "Virtual cache"}, /* Binos: because you "see" them. */ - { "ak", "Micro-Cache" }, /* Looks like a film canister. */ - { "an", "Multi-Cache"}, /* Winery: grapes 'coz they "bunch" */ - { "s", "Unknown Cache"}, /* 'Suprise' cache: use a target. */ - { "ac", "Event Cache"}, /* Event caches. May be food. */ - { NULL, NULL } + { "a", "crossed square" }, + { "b", "box" }, + { "c", "house" }, + { "d", "aerial" }, + { "e", "airport" }, + { "f", "amusement park" }, + { "g", "ATM" }, + { "g", "Bank" }, + { "h", "auto repair" }, + { "i", "boating" }, + { "j", "camping" }, + { "k", "exit ramp" }, + { "l", "first aid" }, + { "m", "nav aid" }, + { "n", "buoy" }, + { "o", "fuel" }, + { "p", "garden" }, + { "q", "golf" }, + { "r", "hotel" }, + { "s", "hunting/fishing" }, + { "t", "large city" }, + { "u", "lighthouse" }, + { "v", "major city" }, + { "w", "marina" }, + { "x", "medium city" }, + { "y", "museum" }, + { "z", "obstruction" }, + { "aa", "park" }, + { "ab", "resort" }, + { "ac", "restaurant" }, + { "ad", "rock" }, + { "ae", "scuba" }, + { "af", "RV service" }, + { "ag", "shooting" }, + { "ah", "sight seeing" }, + { "ai", "small city" }, + { "aj", "sounding" }, + { "ak", "sports arena" }, + { "al", "tourist info" }, + { "am", "truck service" }, + { "an", "winery" }, + { "ao", "wreck" }, + { "ap", "zoo" }, + { "ah", "Virtual cache"}, /* Binos: because you "see" them. */ + { "ak", "Micro-Cache" }, /* Looks like a film canister. */ + { "an", "Multi-Cache"}, /* Winery: grapes 'coz they "bunch" */ + { "s", "Unknown Cache"}, /* 'Suprise' cache: use a target. */ + { "ac", "Event Cache"}, /* Event caches. May be food. */ + { NULL, NULL } }; -pid_to_model_t pid_to_model[] = -{ - { mm_gps315320, 19, "ColorTrak" }, - { mm_gps315320, 24, "GPS 315/320" }, - { mm_map410, 25, "Map 410" }, - { mm_map330, 30, "Map 330" }, - { mm_gps310, 31, "GPS 310" }, - { mm_meridian, 33, "Meridian" }, - { mm_meridian, 35, "ProMark 2" }, - { mm_sportrak, 36, "SporTrak Map/Pro" }, - { mm_sportrak, 37, "SporTrak" }, - { mm_meridian, 38, "FX324 Plotter" }, - { mm_meridian, 39, "Meridian Color" }, - { mm_meridian, 40, "FX324C Plotter" }, - { mm_sportrak, 41, "Sportrak Color" }, - { mm_sportrak, 42, "Sportrak Marine" }, - { mm_meridian, 43, "Meridian Marine" }, - { mm_sportrak, 44, "Sportrak Topo" }, - { mm_sportrak, 45, "Mystic" }, - { mm_meridian, 46, "MobileMapper" }, - { mm_meridian, 110, "Explorist 100" }, - { mm_meridian, 111, "Explorist 200" }, - { mm_unknown, 0, NULL } +pid_to_model_t pid_to_model[] = { + { mm_gps315320, 19, "ColorTrak" }, + { mm_gps315320, 24, "GPS 315/320" }, + { mm_map410, 25, "Map 410" }, + { mm_map330, 30, "Map 330" }, + { mm_gps310, 31, "GPS 310" }, + { mm_meridian, 33, "Meridian" }, + { mm_meridian, 35, "ProMark 2" }, + { mm_sportrak, 36, "SporTrak Map/Pro" }, + { mm_sportrak, 37, "SporTrak" }, + { mm_meridian, 38, "FX324 Plotter" }, + { mm_meridian, 39, "Meridian Color" }, + { mm_meridian, 40, "FX324C Plotter" }, + { mm_sportrak, 41, "Sportrak Color" }, + { mm_sportrak, 42, "Sportrak Marine" }, + { mm_meridian, 43, "Meridian Marine" }, + { mm_sportrak, 44, "Sportrak Topo" }, + { mm_sportrak, 45, "Mystic" }, + { mm_meridian, 46, "MobileMapper" }, + { mm_meridian, 110, "Explorist 100" }, + { mm_meridian, 111, "Explorist 200" }, + { mm_unknown, 0, NULL } }; -static icon_mapping_t *icon_mapping = map330_icon_table; +static icon_mapping_t* icon_mapping = map330_icon_table; /* * For each receiver type, return a "cleansed" version of the string * that's valid for a waypoint name or comment. The string should be * freed when you're done with it. */ -static char * -m315_cleanse(char *istring) +static char* +m315_cleanse(char* istring) { - char *rstring = xmalloc(strlen(istring)+1); - char *i,*o; - static char m315_valid_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"; - for (o=rstring,i=istring; *i; i++) { - if (strchr(m315_valid_chars, toupper(*i))) { - *o++ = toupper(*i); - } - } - *o = 0; - return rstring; + char* rstring = (char*) xmalloc(strlen(istring)+1); + char* i,*o; + static char m315_valid_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"; + for (o=rstring,i=istring; *i; i++) { + if (strchr(m315_valid_chars, toupper(*i))) { + *o++ = toupper(*i); + } + } + *o = 0; + return rstring; } /* * Do same for 330, Meridian, and SportTrak. */ -char * -m330_cleanse(char *istring) +char* +m330_cleanse(char* istring) { - static char m330_valid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " - "abcdefghijklmnopqrstuvwxyz" - "0123456789+-.'/!@#<%^&>()=:\\"; - char *rstring = xmalloc(strlen(istring)+1); - char *o, *i; - - for (o=rstring,i=istring; *i;i++) { - if (strchr(m330_valid_chars, *i)) { - *o++ = *i; - } - } - *o = 0; - return rstring; + static char m330_valid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + "abcdefghijklmnopqrstuvwxyz" + "0123456789+-.'/!@#<%^&>()=:\\"; + char* rstring = (char*) xmalloc(strlen(istring)+1); + char* o, *i; + + for (o=rstring,i=istring; *i; i++) { + if (strchr(m330_valid_chars, *i)) { + *o++ = *i; + } + } + *o = 0; + return rstring; } /* - * Given a protocol message, compute the checksum as needed by + * Given a protocol message, compute the checksum as needed by * the Magellan protocol. */ -unsigned int -mag_checksum(const char * const buf) +unsigned int +mag_checksum(const char* const buf) { - int csum = 0; - const char *p; - - for(p = buf; *p; p++) { - csum ^= *p; - } - - return csum; + int csum = 0; + const char* p; + + for (p = buf; *p; p++) { + csum ^= *p; + } + + return csum; } static unsigned int -mag_pchecksum(const char * const buf, int len) +mag_pchecksum(const char* const buf, int len) { - int csum = 0; - const char *p = buf; - for (; len ; len--) { - csum ^= *p++; - } - return csum; + int csum = 0; + const char* p = buf; + for (; len ; len--) { + csum ^= *p++; + } + return csum; } static void -mag_writemsg(const char * const buf) +mag_writemsg(const char* const buf) { - unsigned int osum = mag_checksum(buf); - int retry_cnt = 5; - int i; - char obuf[1000]; - - if (debug_serial) { - warning("WRITE: $%s*%02X\r\n",buf, osum); - } - - retry: - - i = sprintf(obuf, "$%s*%02X\r\n",buf, osum); - termwrite(obuf, i); - if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ack) { - magrxstate = mrs_awaiting_ack; - mag_readmsg(trkdata); - if (last_rx_csum != osum) { - if (debug_serial) { - warning("COMM ERROR: Expected %02x, got %02x", - osum, last_rx_csum); - } - if (retry_cnt--) - goto retry; - else { - mag_handoff(); - fatal(MYNAME - ": Too many communication errors.\n"); - } - } - } -} + unsigned int osum = mag_checksum(buf); + int retry_cnt = 5; + int i; + char obuf[1000]; + + if (debug_serial) { + warning("WRITE: $%s*%02X\r\n",buf, osum); + } + +retry: + + i = sprintf(obuf, "$%s*%02X\r\n",buf, osum); + termwrite(obuf, i); + if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ack) { + magrxstate = mrs_awaiting_ack; + mag_readmsg(trkdata); + if (last_rx_csum != osum) { + if (debug_serial) { + warning("COMM ERROR: Expected %02x, got %02x", + osum, last_rx_csum); + } + if (retry_cnt--) { + goto retry; + } else { + mag_handoff(); + fatal(MYNAME + ": Too many communication errors.\n"); + } + } + } +} static void mag_writeack(int osum) { - char obuf[200]; - char nbuf[200]; - int i; - unsigned int nsum; - - if (is_file) { - return; - } - - i = sprintf(nbuf, "PMGNCSM,%02X", osum); - nsum = mag_checksum(nbuf); - i = sprintf(obuf, "$%s*%02X\r\n",nbuf, nsum); - - if (debug_serial) { - warning("ACK WRITE: %s",obuf); - } - /* - * Don't call mag_writemsg here so we don't get into ack feedback - * loops. - */ - termwrite(obuf, i); + char obuf[200]; + char nbuf[200]; + int i; + unsigned int nsum; + + if (is_file) { + return; + } + + i = sprintf(nbuf, "PMGNCSM,%02X", osum); + nsum = mag_checksum(nbuf); + i = sprintf(obuf, "$%s*%02X\r\n",nbuf, nsum); + + if (debug_serial) { + warning("ACK WRITE: %s",obuf); + } + /* + * Don't call mag_writemsg here so we don't get into ack feedback + * loops. + */ + termwrite(obuf, i); } static void mag_handon(void) { - if (!is_file) { - mag_writemsg("PMGNCMD,HANDON"); - } - magrxstate = mrs_handon; - + if (!is_file) { + mag_writemsg("PMGNCMD,HANDON"); + } + magrxstate = mrs_handon; + } static void mag_handoff(void) { - if (!is_file) { - mag_writemsg("PMGNCMD,HANDOFF"); - } - magrxstate = mrs_handoff; + if (!is_file) { + mag_writemsg("PMGNCMD,HANDOFF"); + } + magrxstate = mrs_handoff; } void -mag_verparse(char *ibuf) +mag_verparse(char* ibuf) { - int prodid = mm_unknown; - char version[1024]; - pid_to_model_t *pp = pid_to_model; - - got_version = 1; - sscanf(ibuf,"$PMGNVER,%d,%[^,]", &prodid, version); - - for (pp = pid_to_model; pp->model != mm_unknown; pp++) { - if (pp->pid == prodid) { - break; - } - } - - if (prodid == 37) { - broken_sportrak = 1; - } - - switch (pp->model) { - case mm_gps315320: - case mm_map410: - icon_mapping = gps315_icon_table; - setshort_length(mkshort_handle, 6); - setshort_mustupper(mkshort_handle, 1); - mag_cleanse = m315_cleanse; - break; - case mm_map330: - case mm_meridian: - case mm_sportrak: - icon_mapping = map330_icon_table; - setshort_length(mkshort_handle, wpt_len); - setshort_mustupper(mkshort_handle, 0); - mag_cleanse = m330_cleanse; - break; - default: - fatal(MYNAME ": Unknown receiver type %d, model version '%s'.\n", prodid, version); - } + int prodid = mm_unknown; + char version[1024]; + pid_to_model_t* pp = pid_to_model; + + got_version = 1; + sscanf(ibuf,"$PMGNVER,%d,%[^,]", &prodid, version); + + for (pp = pid_to_model; pp->model != mm_unknown; pp++) { + if (pp->pid == prodid) { + break; + } + } + + if (prodid == 37) { + broken_sportrak = 1; + } + + switch (pp->model) { + case mm_gps315320: + case mm_map410: + icon_mapping = gps315_icon_table; + setshort_length(mkshort_handle, 6); + setshort_mustupper(mkshort_handle, 1); + mag_cleanse = m315_cleanse; + break; + case mm_map330: + case mm_meridian: + case mm_sportrak: + icon_mapping = map330_icon_table; + setshort_length(mkshort_handle, wpt_len); + setshort_mustupper(mkshort_handle, 0); + mag_cleanse = m330_cleanse; + break; + default: + fatal(MYNAME ": Unknown receiver type %d, model version '%s'.\n", prodid, version); + } } #define IS_TKN(x) (strncmp(ibuf,x, sizeof(x)-1) == 0) @@ -401,194 +412,197 @@ mag_verparse(char *ibuf) static void mag_readmsg(gpsdata_type objective) { - char ibuf[512]; /* oliskoli: corrupted data (I've seen descr with a lot + char ibuf[512]; /* oliskoli: corrupted data (I've seen descr with a lot of escaped FFFFFFFF) may need more size */ - int isz; - unsigned int isum; - char *isump; - char *gr; - int retrycnt = 20; + int isz; + unsigned int isum; + char* isump; + char* gr; + int retrycnt = 20; retry: - gr = termread(ibuf, sizeof(ibuf)); - - if (!gr) { - if (!got_version) { - /* - * The 315 can take up to six seconds to respond to - * a VERSION command. Since this is on startup, - * we'll be fairly persistent in retrying. - */ - if (retrycnt--) { - goto retry; - } else { - fatal(MYNAME ": No data received from GPS.\n"); - } - } else { - if (is_file) { - found_done = 1; - } - return; - } - } - - /* If column zero isn't a dollar sign, it's not for us */ - if (ibuf[0] != '$') { - fatal(MYNAME ": line doesn't start with '$'.\n"); - } - - - isz = strlen(ibuf); - - if (isz < 5) { - if (debug_serial) - warning( "SHORT READ %d\n", isz); - return; - } - mag_error = 0; - while (!isprint(ibuf[isz])) - isz--; - isump = &ibuf[isz-1]; - isum = strtoul(isump, NULL,16); - if (isum != mag_pchecksum(&ibuf[1], isz-3)) { - if (debug_serial) - warning( "RXERR %02x/%02x: '%s'\n", isum, mag_pchecksum(&ibuf[1],isz-5), ibuf); - /* Special case receive errors early on. */ - if (!got_version) { - fatal(MYNAME ": bad communication. Check bit rate.\n"); - } - } - if (debug_serial) { - warning( "READ: %s\n", ibuf); - } - if (IS_TKN("$PMGNCSM,")) { - last_rx_csum = strtoul(&ibuf[9], NULL, 16); - magrxstate = mrs_handon; - return; - } - if (strncmp(ibuf, "$PMGNWPL,", 7) == 0) { - waypoint *wpt = mag_wptparse(ibuf); - waypoint_read_count++; - if (global_opts.verbose_status) { - waypt_status_disp(waypoint_read_count, - waypoint_read_count); - } - - if (extension_hint) { - if (extension_hint == WPTDATAMASK) { - waypt_add(wpt); - } else if (extension_hint == RTEDATAMASK) { - ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); - } - } else { - switch (objective) { - case wptdata: - waypt_add(wpt); - break; - case rtedata: - ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); - break; - default: - break; - } - } - } - if (strncmp(ibuf, "$PMGNTRK,", 7) == 0) { - waypoint *wpt = mag_trkparse(ibuf); - /* - * Allow lazy allocation of track head. - */ - if (trk_head == NULL) { - /* These tracks don't have names, so derive one - * from input filename. - */ - char *e; - const char *s = get_filename(curfname); - - trk_head = route_head_alloc(); - - /* Whack trailing extension if present. */ - trk_head->rte_name = xstrdup(s); - e = strrchr(trk_head->rte_name, '.'); - if (e) { - *e = '\0'; - } - - track_add_head(trk_head); - } - - track_add_wpt(trk_head, wpt); - } - if (strncmp(ibuf, "$PMGNRTE,", 7) == 0) { - mag_rteparse(ibuf); - } - if (IS_TKN("$PMGNVER,")) { - mag_verparse(ibuf); - } - mag_error = 0; - if (!ignore_unable && IS_TKN("$PMGNCMD,UNABLE")) { - warning( "Unable to send\n"); - found_done = 1; - mag_error = 1; - ignore_unable = 0; - return; - } - if (IS_TKN("$PMGNCMD,END") || (is_file && (gbfeof(magfile_h)))) { - found_done = 1; - return; - } - - if (magrxstate != mrs_handoff) { - mag_writeack(isum); - } + gr = termread(ibuf, sizeof(ibuf)); + + if (!gr) { + if (!got_version) { + /* + * The 315 can take up to six seconds to respond to + * a VERSION command. Since this is on startup, + * we'll be fairly persistent in retrying. + */ + if (retrycnt--) { + goto retry; + } else { + fatal(MYNAME ": No data received from GPS.\n"); + } + } else { + if (is_file) { + found_done = 1; + } + return; + } + } + + /* If column zero isn't a dollar sign, it's not for us */ + if (ibuf[0] != '$') { + fatal(MYNAME ": line doesn't start with '$'.\n"); + } + + + isz = strlen(ibuf); + + if (isz < 5) { + if (debug_serial) { + warning("SHORT READ %d\n", isz); + } + return; + } + mag_error = 0; + while (!isprint(ibuf[isz])) { + isz--; + } + isump = &ibuf[isz-1]; + isum = strtoul(isump, NULL,16); + if (isum != mag_pchecksum(&ibuf[1], isz-3)) { + if (debug_serial) { + warning("RXERR %02x/%02x: '%s'\n", isum, mag_pchecksum(&ibuf[1],isz-5), ibuf); + } + /* Special case receive errors early on. */ + if (!got_version) { + fatal(MYNAME ": bad communication. Check bit rate.\n"); + } + } + if (debug_serial) { + warning("READ: %s\n", ibuf); + } + if (IS_TKN("$PMGNCSM,")) { + last_rx_csum = strtoul(&ibuf[9], NULL, 16); + magrxstate = mrs_handon; + return; + } + if (strncmp(ibuf, "$PMGNWPL,", 7) == 0) { + waypoint* wpt = mag_wptparse(ibuf); + waypoint_read_count++; + if (global_opts.verbose_status) { + waypt_status_disp(waypoint_read_count, + waypoint_read_count); + } + + if (extension_hint) { + if (extension_hint == WPTDATAMASK) { + waypt_add(wpt); + } else if (extension_hint == RTEDATAMASK) { + ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); + } + } else { + switch (objective) { + case wptdata: + waypt_add(wpt); + break; + case rtedata: + ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); + break; + default: + break; + } + } + } + if (strncmp(ibuf, "$PMGNTRK,", 7) == 0) { + waypoint* wpt = mag_trkparse(ibuf); + /* + * Allow lazy allocation of track head. + */ + if (trk_head == NULL) { + /* These tracks don't have names, so derive one + * from input filename. + */ + char* e; + const char* s = get_filename(curfname); + + trk_head = route_head_alloc(); + + /* Whack trailing extension if present. */ + trk_head->rte_name = xstrdup(s); + e = strrchr(trk_head->rte_name, '.'); + if (e) { + *e = '\0'; + } + + track_add_head(trk_head); + } + + track_add_wpt(trk_head, wpt); + } + if (strncmp(ibuf, "$PMGNRTE,", 7) == 0) { + mag_rteparse(ibuf); + } + if (IS_TKN("$PMGNVER,")) { + mag_verparse(ibuf); + } + mag_error = 0; + if (!ignore_unable && IS_TKN("$PMGNCMD,UNABLE")) { + warning("Unable to send\n"); + found_done = 1; + mag_error = 1; + ignore_unable = 0; + return; + } + if (IS_TKN("$PMGNCMD,END") || (is_file && (gbfeof(magfile_h)))) { + found_done = 1; + return; + } + + if (magrxstate != mrs_handoff) { + mag_writeack(isum); + } } -static void *serial_handle = NULL; +static void* serial_handle = NULL; -static int -terminit(const char *portname, int create_ok) +static int +terminit(const char* portname, int create_ok) { - if (gbser_is_serial(portname)) { - if (serial_handle = gbser_init(portname), NULL != serial_handle) { - int rc; - if (rc = gbser_set_port(serial_handle, bitrate, 8, 0, 1), gbser_OK != rc) { - fatal(MYNAME ": Can't configure port\n"); - } - } - is_file = 0; - if (serial_handle == NULL) { - fatal(MYNAME ": Could not open serial port %s\n", portname); - } - return 1; - } else { - /* Does this check for an error? */ - magfile_h = gbfopen(portname, create_ok ? "w+b" : "rb", MYNAME); - is_file = 1; - icon_mapping = map330_icon_table; - mag_cleanse = m330_cleanse; - got_version = 1; - return 0; - } + if (gbser_is_serial(portname)) { + if (serial_handle = gbser_init(portname), NULL != serial_handle) { + int rc; + if (rc = gbser_set_port(serial_handle, bitrate, 8, 0, 1), gbser_OK != rc) { + fatal(MYNAME ": Can't configure port\n"); + } + } + is_file = 0; + if (serial_handle == NULL) { + fatal(MYNAME ": Could not open serial port %s\n", portname); + } + return 1; + } else { + /* Does this check for an error? */ + magfile_h = gbfopen(portname, create_ok ? "w+b" : "rb", MYNAME); + is_file = 1; + icon_mapping = map330_icon_table; + mag_cleanse = m330_cleanse; + got_version = 1; + return 0; + } } -static char *termread(char *ibuf, int size) +static char* termread(char* ibuf, int size) { - if (is_file) { - return gbfgets(ibuf, size, magfile_h); - } else { - int rc; - rc = gbser_read_line(serial_handle, ibuf, size, 2000, 0x0a, 0x0d); - if (rc != gbser_OK) { - fatal(MYNAME ": Read error\n"); - } - return ibuf; - } + if (is_file) { + return gbfgets(ibuf, size, magfile_h); + } else { + int rc; + rc = gbser_read_line(serial_handle, ibuf, size, 2000, 0x0a, 0x0d); + if (rc != gbser_OK) { + fatal(MYNAME ": Read error\n"); + } + return ibuf; + } } /* Though not documented in the protocol spec, if the unit itself - * wants to create a field containing a comma, it will encode it + * wants to create a field containing a comma, it will encode it * as 2C. We extrapolate that any 2 digit hex encoding may - * be valid. We don't do this in termread() since we need to do it + * be valid. We don't do this in termread() since we need to do it * after the scanf. This means we have to do it field-by-field * basis. * @@ -597,62 +611,62 @@ static char *termread(char *ibuf, int size) */ static void -mag_dequote(char *ibuf) +mag_dequote(char* ibuf) { - char *esc = NULL; - - while ((esc = strchr (ibuf, 0x1b))) { - int nremains = strlen(esc); - if (nremains >= 3) { - static const char hex[16] = "0123456789ABCDEF"; - char *c1 = strchr(hex, esc[1]); - char *c2 = strchr(hex, esc[2]); - if (c1 && c2) { - int escv = (c1 - hex) * 16 + (c2 - hex); - if (escv == 255) { /* corrupted data */ - char *tmp = esc + 1; - while (*tmp == 'F') tmp++; - memmove(esc, tmp, strlen(tmp) + 1); - } - else { - *esc++ = (isprint(escv)) ? escv : '$'; - /* buffers overlap */ - memmove(esc, esc+2, nremains - 2); - } - } - } - else { - *esc = '\0'; /* trim corrupted data, + char* esc = NULL; + + while ((esc = strchr(ibuf, 0x1b))) { + int nremains = strlen(esc); + if (nremains >= 3) { + static const char hex[17] = "0123456789ABCDEF"; + char* c1 = strchr(hex, esc[1]); + char* c2 = strchr(hex, esc[2]); + if (c1 && c2) { + int escv = (c1 - hex) * 16 + (c2 - hex); + if (escv == 255) { /* corrupted data */ + char* tmp = esc + 1; + while (*tmp == 'F') { + tmp++; + } + memmove(esc, tmp, strlen(tmp) + 1); + } else { + *esc++ = (isprint(escv)) ? escv : '$'; + /* buffers overlap */ + memmove(esc, esc+2, nremains - 2); + } + } + } else { + *esc = '\0'; /* trim corrupted data, otherwise we get an endless loop */ - } - } + } + } } -static void -termwrite(char *obuf, int size) +static void +termwrite(char* obuf, int size) { - if (is_file) { - size_t nw; - if (nw = gbfwrite(obuf, 1, size, magfile_h), nw < (size_t) size) { - fatal(MYNAME ": Write error"); - } - } else { - int rc; - if (rc = gbser_write(serial_handle, obuf, size), rc < 0) { - fatal(MYNAME ": Write error"); - } - } + if (is_file) { + size_t nw; + if (nw = gbfwrite(obuf, 1, size, magfile_h), nw < (size_t) size) { + fatal(MYNAME ": Write error"); + } + } else { + int rc; + if (rc = gbser_write(serial_handle, obuf, size), rc < 0) { + fatal(MYNAME ": Write error"); + } + } } -static void termdeinit() +static void termdeinit() { - if (is_file) { - gbfclose(magfile_h); - magfile_h = NULL; - } else { - gbser_deinit(serial_handle); - serial_handle = NULL; - } + if (is_file) { + gbfclose(magfile_h); + magfile_h = NULL; + } else { + gbser_deinit(serial_handle); + serial_handle = NULL; + } } /* @@ -660,215 +674,247 @@ static void termdeinit() */ static arglist_t mag_sargs[] = { - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, - ARG_NOMINMAX }, - {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", - "200", ARGTYPE_INT, ARG_NOMINMAX }, - {"baud", &bs, "Numeric value of bitrate (baud=4800)", "4800", - ARGTYPE_INT, ARG_NOMINMAX }, - {"noack", &noack, "Suppress use of handshaking in name of speed", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - ARG_TERMINATOR + { + "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + "maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", + "200", ARGTYPE_INT, ARG_NOMINMAX + }, + { + "baud", &bs, "Numeric value of bitrate (baud=4800)", "4800", + ARGTYPE_INT, ARG_NOMINMAX + }, + { + "noack", &noack, "Suppress use of handshaking in name of speed", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + ARG_TERMINATOR }; static arglist_t mag_fargs[] = { - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, - ARG_NOMINMAX }, - {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", - NULL, ARGTYPE_INT, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + "maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", + NULL, ARGTYPE_INT, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -/* +/* * The part of the serial init that's common to read and write. */ static void -mag_serial_init_common(const char *portname) +mag_serial_init_common(const char* portname) { - time_t now, later; - - if (is_file) { - return; - } - - mag_handoff(); - if (!noack && !suppress_ack) - mag_handon(); - - now = current_time(); - /* - * The 315 can take up to 4.25 seconds to respond to initialization - * commands. Time out on the side of caution. - */ - later = now + 6; - got_version = 0; - mag_writemsg("PMGNCMD,VERSION"); - - while (!got_version) { - mag_readmsg(trkdata); - if (current_time() > later) { - fatal(MYNAME ": No acknowledgment from GPS on %s\n", - portname); - } - } - - if ((icon_mapping != gps315_icon_table)) { - /* - * The 315 can't handle this command, so we set a global - * to ignore the NAK on it. - */ - ignore_unable = 1; - mag_writemsg("PMGNCMD,NMEAOFF"); - ignore_unable = 0; - } - - if (nukewpt) { - /* The unit will send us an "end" message upon completion */ - mag_writemsg("PMGNCMD,DELETE,WAYPOINT"); - mag_readmsg(trkdata); - if (!found_done) { - fatal(MYNAME ": Unexpected response to waypoint delete command.\n"); - } - found_done = 0; - } + time_t now, later; + + if (is_file) { + return; + } + + mag_handoff(); + if (!noack && !suppress_ack) { + mag_handon(); + } + + now = current_time(); + /* + * The 315 can take up to 4.25 seconds to respond to initialization + * commands. Time out on the side of caution. + */ + later = now + 6; + got_version = 0; + mag_writemsg("PMGNCMD,VERSION"); + + while (!got_version) { + mag_readmsg(trkdata); + if (current_time() > later) { + fatal(MYNAME ": No acknowledgment from GPS on %s\n", + portname); + } + } + + if ((icon_mapping != gps315_icon_table)) { + /* + * The 315 can't handle this command, so we set a global + * to ignore the NAK on it. + */ + ignore_unable = 1; + mag_writemsg("PMGNCMD,NMEAOFF"); + ignore_unable = 0; + } + + if (nukewpt) { + /* The unit will send us an "end" message upon completion */ + mag_writemsg("PMGNCMD,DELETE,WAYPOINT"); + mag_readmsg(trkdata); + if (!found_done) { + fatal(MYNAME ": Unexpected response to waypoint delete command.\n"); + } + found_done = 0; + } } static void -mag_rd_init_common(const char *portname) +mag_rd_init_common(const char* portname) { - char *ext; - waypoint_read_count = 0; - - if (bs) { - bitrate=atoi(bs); - } - - if (!mkshort_handle) { - mkshort_handle = mkshort_new_handle(); - } - - terminit(portname, 0); - mag_serial_init_common(portname); - - QUEUE_INIT(&rte_wpt_tmp); - - /* find the location of the tail of the path name, - * make a copy of it, then lop off the file extension - */ - - curfname = get_filename(portname); - - /* - * I'd rather not derive behaviour from filenames but since - * we can't otherwise tell if we should put a WPT on the route - * queue or the WPT queue in the presence of (-w -r -t) we - * divine a hint from the filename extension when we can. - */ - ext = strrchr(curfname, '.'); - if (ext) { - ext++; - if (0 == case_ignore_strcmp(ext, "upt")) { - extension_hint = WPTDATAMASK; - } else if (0 == case_ignore_strcmp(ext, "log")) { - extension_hint = TRKDATAMASK; - } else if (0 == case_ignore_strcmp(ext, "rte")) { - extension_hint = RTEDATAMASK; - } - } - - return; + char* ext; + waypoint_read_count = 0; + // For Explorist GC, intercept the device access and redirect to GPX. + // We actually do the rd_init() inside read as we may have multiple + // files that we have to read. + if (0 == strcmp(portname, "usb:")) { + const char** dlist = os_get_magellan_mountpoints(); + explorist_info = explorist_ini_get(dlist); + if (explorist_info) { + char* vec_opts = NULL; + gpx_vec = find_vec("gpx", &vec_opts); + } + return; + } + + if (bs) { + bitrate=atoi(bs); + } + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + + terminit(portname, 0); + mag_serial_init_common(portname); + + QUEUE_INIT(&rte_wpt_tmp); + + /* find the location of the tail of the path name, + * make a copy of it, then lop off the file extension + */ + + curfname = get_filename(portname); + + /* + * I'd rather not derive behaviour from filenames but since + * we can't otherwise tell if we should put a WPT on the route + * queue or the WPT queue in the presence of (-w -r -t) we + * divine a hint from the filename extension when we can. + */ + ext = strrchr(curfname, '.'); + if (ext) { + ext++; + if (0 == case_ignore_strcmp(ext, "upt")) { + extension_hint = WPTDATAMASK; + } else if (0 == case_ignore_strcmp(ext, "log")) { + extension_hint = TRKDATAMASK; + } else if (0 == case_ignore_strcmp(ext, "rte")) { + extension_hint = RTEDATAMASK; + } + } + + return; } static void -mag_rd_init(const char *portname) +mag_rd_init(const char* portname) { - explorist = 0; - suppress_ack = 1; - mag_rd_init_common(portname); + explorist = 0; + suppress_ack = 1; + mag_rd_init_common(portname); } static void -magX_rd_init(const char *portname) +magX_rd_init(const char* portname) { - explorist = 1; - mag_rd_init_common(portname); + explorist = 1; + mag_rd_init_common(portname); } static void -mag_wr_init_common(const char *portname) +mag_wr_init_common(const char* portname) { - suppress_ack = 0; - if (bs) { - bitrate=atoi(bs); - } + suppress_ack = 0; + if (bs) { + bitrate=atoi(bs); + } - if (waypt_count() > 500) { - fatal(MYNAME ": Meridian/Explorist does not support more than 500 waypoints in one file. Only\n200 waypoints may have comments.\nDecrease the number of waypoints sent.\n"); - } + if (waypt_count() > 500) { + fatal(MYNAME ": Meridian/Explorist does not support more than 500 waypoints in one file. Only\n200 waypoints may have comments.\nDecrease the number of waypoints sent.\n"); + } - if (cmts) { - wptcmtcnt_max = atoi(cmts); - } else { - wptcmtcnt_max = MAXCMTCT ; - } + if (cmts) { + wptcmtcnt_max = atoi(cmts); + } else { + wptcmtcnt_max = MAXCMTCT ; + } - if (!mkshort_handle) { - mkshort_handle = mkshort_new_handle(); - } + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } - terminit(portname, 1); - mag_serial_init_common(portname); + terminit(portname, 1); + mag_serial_init_common(portname); - QUEUE_INIT(&rte_wpt_tmp); + QUEUE_INIT(&rte_wpt_tmp); } /* * Entry point for extended (explorist) points. */ static void -magX_wr_init(const char *portname) +magX_wr_init(const char* portname) { - wpt_len = 20; - explorist = 1; - mag_wr_init_common(portname); - setshort_length(mkshort_handle, wpt_len); - setshort_whitespace_ok(mkshort_handle, 1); + wpt_len = 20; + explorist = 1; + mag_wr_init_common(portname); + setshort_length(mkshort_handle, wpt_len); + setshort_whitespace_ok(mkshort_handle, 1); } static void -mag_wr_init(const char *portname) +mag_wr_init(const char* portname) { - explorist = 0; - wpt_len = 8; - mag_wr_init_common(portname); - /* - * Whitespace is actually legal, but since waypoint name length is - * only 8 bytes, we'll conserve them. - */ - - setshort_whitespace_ok(mkshort_handle, 0); + explorist = 0; + wpt_len = 8; + mag_wr_init_common(portname); + /* + * Whitespace is actually legal, but since waypoint name length is + * only 8 bytes, we'll conserve them. + */ + + setshort_whitespace_ok(mkshort_handle, 0); } static void mag_deinit(void) { - mag_handoff(); - termdeinit(); - if(mkshort_handle) - mkshort_del_handle(&mkshort_handle); - - waypt_flush(&rte_wpt_tmp); - - trk_head = NULL; + if (explorist_info) { + explorist_ini_done(explorist_info); + return; + } + mag_handoff(); + termdeinit(); + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } + + waypt_flush(&rte_wpt_tmp); + + trk_head = NULL; } /* - * I'm tired of arguing with scanf about optional fields . Detokenize + * I'm tired of arguing with scanf about optional fields . Detokenize * an incoming string that may contain empty fields. - * + * * Probably should be cleaned up and moved to common code, but * making it deal with an arbitrary number of fields of arbitrary * size is icky. We don't have to solve the general case here... @@ -876,22 +922,24 @@ mag_deinit(void) static char ifield[20][100]; static -void parse_istring(char *istring) +void parse_istring(char* istring) { - int f = 0; - int n,x; - while (istring[0]) { - char *fp = ifield[f]; - x = sscanf(istring, "%[^,]%n", fp, &n); - f++; - if (x) { - istring += n; - /* IF more in this string, skip delim */ - if (istring[0]) istring++; - } else { - istring ++; - } - } + int f = 0; + int n,x; + while (istring[0]) { + char* fp = ifield[f]; + x = sscanf(istring, "%[^,]%n", fp, &n); + f++; + if (x) { + istring += n; + /* IF more in this string, skip delim */ + if (istring[0]) { + istring++; + } + } else { + istring ++; + } + } } /* @@ -899,64 +947,68 @@ void parse_istring(char *istring) * $PMGNTRK,3605.259,N,08644.389,W,00151,M,201444.61,A,,020302*66 * create and return a populated waypoint. */ -waypoint * -mag_trkparse(char *trkmsg) +waypoint* +mag_trkparse(char* trkmsg) { - double latdeg, lngdeg; - int alt; - char altunits; - char lngdir, latdir; - int dmy; - int hms; - int fracsecs; - struct tm tm; - waypoint *waypt; - - waypt = waypt_new(); - - memset(&tm, 0, sizeof(tm)); - - /* - * As some of the fields are optional, sscanf works badly - * for us. - */ - parse_istring(trkmsg); - latdeg = atof(ifield[1]); - latdir = ifield[2][0]; - lngdeg = atof(ifield[3]); - lngdir = ifield[4][0]; - alt = atof(ifield[5]); - altunits = ifield[6][0]; - sscanf(ifield[7], "%d.%d", &hms, &fracsecs); - /* Field 8 is constant */ - /* Field nine is optional track name */ - dmy = atoi(ifield[10]); - - tm.tm_sec = hms % 100; - hms = hms / 100; - tm.tm_min = hms % 100; - hms = hms / 100; - tm.tm_hour = hms % 100; - - tm.tm_year = 100 + dmy % 100; - dmy = dmy / 100; - tm.tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm.tm_mday = dmy % 100; - - waypt->creation_time = mkgmtime(&tm); - waypt->microseconds = CENTI_TO_MICRO(fracsecs); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - waypt->altitude = alt; - - return waypt; - + double latdeg, lngdeg; + int alt; + char altunits; + char lngdir, latdir; + int dmy; + int hms; + int fracsecs; + struct tm tm; + waypoint* waypt; + + waypt = waypt_new(); + + memset(&tm, 0, sizeof(tm)); + + /* + * As some of the fields are optional, sscanf works badly + * for us. + */ + parse_istring(trkmsg); + latdeg = atof(ifield[1]); + latdir = ifield[2][0]; + lngdeg = atof(ifield[3]); + lngdir = ifield[4][0]; + alt = atof(ifield[5]); + altunits = ifield[6][0]; + sscanf(ifield[7], "%d.%d", &hms, &fracsecs); + /* Field 8 is constant */ + /* Field nine is optional track name */ + dmy = atoi(ifield[10]); + + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + + tm.tm_year = 100 + dmy % 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy % 100; + + waypt->creation_time = mkgmtime(&tm); + waypt->microseconds = CENTI_TO_MICRO(fracsecs); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + + return waypt; + } /* @@ -965,173 +1017,181 @@ mag_trkparse(char *trkmsg) * generate a route. */ void -mag_rteparse(char *rtemsg) +mag_rteparse(char* rtemsg) { - char descr[100]; - int n; - int frags,frag,rtenum; - char xbuf[100],next_stop[100],abuf[100]; - char *currtemsg; - static mag_rte_head *mag_rte_head; - mag_rte_elem *rte_elem; - char *p; - char *rte_name = NULL; - - descr[0] = 0; + char descr[100]; + int n; + int frags,frag,rtenum; + char xbuf[100],next_stop[100],abuf[100]; + char* currtemsg; + static mag_rte_head* mag_rte_head; + mag_rte_elem* rte_elem; + char* p; + char* rte_name = NULL; + + descr[0] = 0; #if 0 - sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", - &frags,&frag,xbuf,&rtenum,&n); + sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", + &frags,&frag,xbuf,&rtenum,&n); #else - sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", - &frags,&frag,xbuf,&rtenum,&n); - - /* Explorist has a route name here */ - if (explorist) { - char *ca, *ce; - - ca = rtemsg + n; - is_fatal(*ca++ != ',', MYNAME ": Incorrectly formatted route line '%s'", rtemsg); - - ce = strchr(ca, ','); - is_fatal(ce == NULL, MYNAME ": Incorrectly formatted route line '%s'", rtemsg); - - if (ca == ce) - xasprintf(&rte_name, "Route%d", rtenum); - else - rte_name = xstrndup(ca, ce - ca); - - n += ((ce - ca) + 1); - } + sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", + &frags,&frag,xbuf,&rtenum,&n); + + /* Explorist has a route name here */ + if (explorist) { + char* ca, *ce; + + ca = rtemsg + n; + is_fatal(*ca++ != ',', MYNAME ": Incorrectly formatted route line '%s'", rtemsg); + + ce = strchr(ca, ','); + is_fatal(ce == NULL, MYNAME ": Incorrectly formatted route line '%s'", rtemsg); + + if (ca == ce) { + xasprintf(&rte_name, "Route%d", rtenum); + } else { + rte_name = xstrndup(ca, ce - ca); + } + + n += ((ce - ca) + 1); + } #endif - /* - * This is the first component of a route. Allocate a new - * queue head. - */ - if (frag == 1) { - mag_rte_head = xcalloc(sizeof (*mag_rte_head),1); - QUEUE_INIT(&mag_rte_head->Q); - mag_rte_head->nelems = frags; - } - - currtemsg = rtemsg + n; - - /* - * The individual line may contain several route elements. - * loop and pick those up. - */ - while (sscanf(currtemsg,",%[^,],%[^,]%n",next_stop, abuf,&n)) { - if ((next_stop[0] == 0) || (next_stop[0] == '*')) { - break; - } - - /* trim CRC from waypoint icon string */ - if ((p = strchr(abuf, '*')) != NULL) - *p = '\0'; - - rte_elem = xcalloc(sizeof (*rte_elem),1); - QUEUE_INIT(&rte_elem->Q); - - rte_elem->wpt_name = xstrdup(next_stop); - rte_elem->wpt_icon = xstrdup(abuf); - - ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); - - /* Sportrak (the non-mapping unit) creates malformed - * RTE sentence with no icon info after the routepoint - * name. So if we saw an "icon" treat that as new - * routepoint. - */ - if (broken_sportrak && abuf[0]) { - rte_elem = xcalloc(sizeof (*rte_elem),1); - QUEUE_INIT(&rte_elem->Q); - rte_elem->wpt_name = xstrdup(abuf); - - ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); - } - - next_stop[0] = 0; - currtemsg += n; - } - - /* - * If this was the last fragment of the route, add it to the - * gpsbabel internal structs now. - */ - if (frag == mag_rte_head->nelems) { - queue *elem, *tmp; - route_head *rte_head; - - rte_head = route_head_alloc(); - route_add_head(rte_head); - rte_head->rte_num = rtenum; - rte_head->rte_name = xstrdup(rte_name); - - /* - * It is quite feasible that we have 200 waypoints, - * 3 of which are used in the route. We'll need to find - * those in the queue for SD routes... - */ - - QUEUE_FOR_EACH(&mag_rte_head->Q, elem, tmp) { - mag_rte_elem *re = (mag_rte_elem *) elem; - waypoint *waypt; - queue *welem, *wtmp; - - /* - * Copy route points from temp wpt queue. - */ - QUEUE_FOR_EACH(&rte_wpt_tmp, welem, wtmp) { - waypt = (waypoint *)welem; - if (strcmp(waypt->shortname, re->wpt_name) == 0) { - waypoint * wpt = waypt_dupe(waypt); - route_add_wpt(rte_head, wpt); - break; - } - } - - dequeue(&re->Q); - xfree(re->wpt_name); - xfree(re->wpt_icon); - xfree(re); - } - xfree(mag_rte_head); - } - if (rte_name) xfree(rte_name); + /* + * This is the first component of a route. Allocate a new + * queue head. + */ + if (frag == 1) { + mag_rte_head = (struct mag_rte_head_*) xcalloc(sizeof(*mag_rte_head),1); + QUEUE_INIT(&mag_rte_head->Q); + mag_rte_head->nelems = frags; + } + + currtemsg = rtemsg + n; + + /* + * The individual line may contain several route elements. + * loop and pick those up. + */ + while (sscanf(currtemsg,",%[^,],%[^,]%n",next_stop, abuf,&n)) { + if ((next_stop[0] == 0) || (next_stop[0] == '*')) { + break; + } + + /* trim CRC from waypoint icon string */ + if ((p = strchr(abuf, '*')) != NULL) { + *p = '\0'; + } + + rte_elem = (mag_rte_elem*) xcalloc(sizeof(*rte_elem),1); + QUEUE_INIT(&rte_elem->Q); + + rte_elem->wpt_name = xstrdup(next_stop); + rte_elem->wpt_icon = xstrdup(abuf); + + ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); + + /* Sportrak (the non-mapping unit) creates malformed + * RTE sentence with no icon info after the routepoint + * name. So if we saw an "icon" treat that as new + * routepoint. + */ + if (broken_sportrak && abuf[0]) { + rte_elem = (mag_rte_elem*) xcalloc(sizeof(*rte_elem),1); + QUEUE_INIT(&rte_elem->Q); + rte_elem->wpt_name = xstrdup(abuf); + + ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); + } + + next_stop[0] = 0; + currtemsg += n; + } + + /* + * If this was the last fragment of the route, add it to the + * gpsbabel internal structs now. + */ + if (frag == mag_rte_head->nelems) { + queue* elem, *tmp; + route_head* rte_head; + + rte_head = route_head_alloc(); + route_add_head(rte_head); + rte_head->rte_num = rtenum; + rte_head->rte_name = xstrdup(rte_name); + + /* + * It is quite feasible that we have 200 waypoints, + * 3 of which are used in the route. We'll need to find + * those in the queue for SD routes... + */ + + QUEUE_FOR_EACH(&mag_rte_head->Q, elem, tmp) { + mag_rte_elem* re = (mag_rte_elem*) elem; + waypoint* waypt; + queue* welem, *wtmp; + + /* + * Copy route points from temp wpt queue. + */ + QUEUE_FOR_EACH(&rte_wpt_tmp, welem, wtmp) { + waypt = (waypoint*)welem; + if (strcmp(waypt->shortname, re->wpt_name) == 0) { + waypoint* wpt = waypt_dupe(waypt); + route_add_wpt(rte_head, wpt); + break; + } + } + + dequeue(&re->Q); + xfree(re->wpt_name); + xfree(re->wpt_icon); + xfree(re); + } + xfree(mag_rte_head); + } + if (rte_name) { + xfree(rte_name); + } } -const char * -mag_find_descr_from_token(const char *token) +const char* +mag_find_descr_from_token(const char* token) { - icon_mapping_t *i = icon_mapping; - - if (icon_mapping == NULL) { - return "unknown"; - } - - for (i = icon_mapping; i->token; i++) { - if (token[0] == 0) break; - if (case_ignore_strcmp(token, i->token) == 0) - return i->icon; - } - return icon_mapping[0].icon; + icon_mapping_t* i = icon_mapping; + + if (icon_mapping == NULL) { + return "unknown"; + } + + for (i = icon_mapping; i->token; i++) { + if (token[0] == 0) { + break; + } + if (case_ignore_strcmp(token, i->token) == 0) { + return i->icon; + } + } + return icon_mapping[0].icon; } -const char * -mag_find_token_from_descr(const char *icon) +const char* +mag_find_token_from_descr(const char* icon) { - icon_mapping_t *i = icon_mapping; - - if (i == NULL || icon == NULL) { - return "a"; - } - - for (i = icon_mapping; i->token; i++) { - if (case_ignore_strcmp(icon, i->icon) == 0) - return i->token; - } - return icon_mapping[0].token; + icon_mapping_t* i = icon_mapping; + + if (i == NULL || icon == NULL) { + return "a"; + } + + for (i = icon_mapping; i->token; i++) { + if (case_ignore_strcmp(icon, i->icon) == 0) { + return i->token; + } + } + return icon_mapping[0].token; } /* @@ -1139,255 +1199,288 @@ mag_find_token_from_descr(const char *icon) * $PMGNWPL,3549.499,N,08650.827,W,0000257,M,HOME,HOME,c*4D * create and return a populated waypoint. */ -static waypoint * -mag_wptparse(char *trkmsg) +static waypoint* +mag_wptparse(char* trkmsg) { - double latdeg, lngdeg; - char latdir; - char lngdir; - int alt; - char altunits; - char shortname[100]; - char descr[256]; - char icon_token[100]; - waypoint *waypt; - char *icons; - char *icone; - char *blah; - int i = 0; - - descr[0] = 0; - icon_token[0] = 0; - - waypt = waypt_new(); - - sscanf(trkmsg,"$PMGNWPL,%lf,%c,%lf,%c,%d,%c,%[^,],%[^,]", - &latdeg,&latdir, - &lngdeg,&lngdir, - &alt,&altunits,shortname,descr); - icone = strrchr(trkmsg, '*'); - icons = strrchr(trkmsg, ',')+1; - - mag_dequote(descr); - - for (blah = icons ; blah < icone; blah++) - icon_token[i++] = *blah; - icon_token[i++] = '\0'; - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - waypt->altitude = alt; - waypt->shortname = xstrdup(shortname); - waypt->description = xstrdup(descr); - waypt->icon_descr = mag_find_descr_from_token(icon_token); - - return waypt; + double latdeg, lngdeg; + char latdir; + char lngdir; + int alt; + char altunits; + char shortname[100]; + char descr[256]; + char icon_token[100]; + waypoint* waypt; + char* icons; + char* icone; + char* blah; + int i = 0; + + descr[0] = 0; + icon_token[0] = 0; + + waypt = waypt_new(); + + sscanf(trkmsg,"$PMGNWPL,%lf,%c,%lf,%c,%d,%c,%[^,],%[^,]", + &latdeg,&latdir, + &lngdeg,&lngdir, + &alt,&altunits,shortname,descr); + icone = strrchr(trkmsg, '*'); + icons = strrchr(trkmsg, ',')+1; + + mag_dequote(descr); + + for (blah = icons ; blah < icone; blah++) { + icon_token[i++] = *blah; + } + icon_token[i++] = '\0'; + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + waypt->shortname = xstrdup(shortname); + waypt->description = xstrdup(descr); + waypt->icon_descr = mag_find_descr_from_token(icon_token); + + return waypt; } static void mag_read(void) { - found_done = 0; - if (global_opts.masked_objective & TRKDATAMASK) { - magrxstate = mrs_handoff; - if (!is_file) - mag_writemsg("PMGNCMD,TRACK,2"); - - while (!found_done) { - mag_readmsg(trkdata); - } - } - - found_done = 0; - if (global_opts.masked_objective & WPTDATAMASK) { - magrxstate = mrs_handoff; - if (!is_file) - mag_writemsg("PMGNCMD,WAYPOINT"); - - while (!found_done) { - mag_readmsg(wptdata); - } - } - - found_done = 0; - if (global_opts.masked_objective & RTEDATAMASK) { - magrxstate = mrs_handoff; - if (!is_file) { - /* - * serial routes require waypoint & routes - * messages commands. - */ - mag_writemsg("PMGNCMD,WAYPOINT"); - - while (!found_done) { - mag_readmsg(rtedata); - } - - mag_writemsg("PMGNCMD,ROUTE"); - - found_done = 0; - while (!found_done) { - mag_readmsg(rtedata); - } - } else { - /* - * SD routes are a stream of PMGNWPL and - * PMGNRTE messages, in that order. - */ - while (!found_done) { - mag_readmsg(rtedata); - } - } - } + if (gpx_vec) { + char** f = os_gpx_files(explorist_info->track_path); + while (f && *f) { + gpx_vec->rd_init(*f); + gpx_vec->read(); + f++; + } + + f = os_gpx_files(explorist_info->waypoint_path); + while (f && *f) { + gpx_vec->rd_init(*f); + gpx_vec->read(); + f++; + } +#if 0 + f = os_gpx_files(explorist_info->geo_path); + while (f && *f) { + gpx_vec->rd_init(*f); + gpx_vec->read(); + f++; + } +#endif + return; + } + + found_done = 0; + if (global_opts.masked_objective & TRKDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) { + mag_writemsg("PMGNCMD,TRACK,2"); + } + + while (!found_done) { + mag_readmsg(trkdata); + } + } + + found_done = 0; + if (global_opts.masked_objective & WPTDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) { + mag_writemsg("PMGNCMD,WAYPOINT"); + } + + while (!found_done) { + mag_readmsg(wptdata); + } + } + + found_done = 0; + if (global_opts.masked_objective & RTEDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) { + /* + * serial routes require waypoint & routes + * messages commands. + */ + mag_writemsg("PMGNCMD,WAYPOINT"); + + while (!found_done) { + mag_readmsg(rtedata); + } + + mag_writemsg("PMGNCMD,ROUTE"); + + found_done = 0; + while (!found_done) { + mag_readmsg(rtedata); + } + } else { + /* + * SD routes are a stream of PMGNWPL and + * PMGNRTE messages, in that order. + */ + while (!found_done) { + mag_readmsg(rtedata); + } + } + } } static void -mag_waypt_pr(const waypoint *waypointp) +mag_waypt_pr(const waypoint* waypointp) { - double lon, lat; - double ilon, ilat; - int lon_deg, lat_deg; - char obuf[200]; - char ofmtdesc[200]; - const char *icon_token=NULL; - char *owpt; - char *odesc; - char *isrc = NULL; - - ilat = waypointp->latitude; - ilon = waypointp->longitude; - - lon = fabs(ilon); - lat = fabs(ilat); - - lon_deg = lon; - lat_deg = lat; - - lon = (lon - lon_deg) * 60.0; - lat = (lat - lat_deg) * 60.0; - - lon = (lon_deg * 100.0 + lon); - lat = (lat_deg * 100.0 + lat); - - if (deficon) { - icon_token = mag_find_token_from_descr(deficon); - } else { - icon_token = mag_find_token_from_descr(waypointp->icon_descr); - } - - if (get_cache_icon(waypointp)) { - icon_token = mag_find_token_from_descr(get_cache_icon(waypointp)); - } - - isrc = waypointp->notes ? waypointp->notes : waypointp->description; - owpt = global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, waypointp) : waypointp->shortname; - odesc = isrc ? isrc : ""; - owpt = mag_cleanse(owpt); - - if (global_opts.smart_icons && - waypointp->gc_data->diff && waypointp->gc_data->terr) { - sprintf(ofmtdesc, "%d/%d %s", waypointp->gc_data->diff, - waypointp->gc_data->terr, odesc); - odesc = mag_cleanse(ofmtdesc); - } else { - odesc = mag_cleanse(odesc); - } - - /* - * For the benefit of DirectRoute (which uses waypoint comments - * to deliver turn-by-turn popups for street routing) allow a - * cap on the comments delivered so we leave space for it to route. - */ - if (odesc && /* !is_file && */ (wptcmtcnt++ >= wptcmtcnt_max)) - odesc[0] = 0; - - sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.0f,M,%-.*s,%-.46s,%s", - lat, ilat < 0 ? 'S' : 'N', - lon, ilon < 0 ? 'W' : 'E', - waypointp->altitude == unknown_alt ? - 0 : waypointp->altitude, - wpt_len, - owpt, - odesc, - icon_token); - mag_writemsg(obuf); - xfree(owpt); - xfree(odesc); - - if (!is_file) { - if (mag_error) { - warning( "Protocol error Writing '%s'\n", obuf); - } - } + double lon, lat; + double ilon, ilat; + int lon_deg, lat_deg; + char obuf[200]; + char ofmtdesc[200]; + const char* icon_token=NULL; + char* owpt; + char* odesc; + char* isrc = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + if (deficon) { + icon_token = mag_find_token_from_descr(deficon); + } else { + icon_token = mag_find_token_from_descr(waypointp->icon_descr); + } + + if (get_cache_icon(waypointp)) { + icon_token = mag_find_token_from_descr(get_cache_icon(waypointp)); + } + + isrc = waypointp->notes ? waypointp->notes : waypointp->description; + owpt = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, waypointp) : waypointp->shortname; + odesc = isrc ? isrc : (char*)""; + owpt = mag_cleanse(owpt); + + if (global_opts.smart_icons && + waypointp->gc_data->diff && waypointp->gc_data->terr) { + sprintf(ofmtdesc, "%d/%d %s", waypointp->gc_data->diff, + waypointp->gc_data->terr, odesc); + odesc = mag_cleanse(ofmtdesc); + } else { + odesc = mag_cleanse(odesc); + } + + /* + * For the benefit of DirectRoute (which uses waypoint comments + * to deliver turn-by-turn popups for street routing) allow a + * cap on the comments delivered so we leave space for it to route. + */ + if (odesc && /* !is_file && */ (wptcmtcnt++ >= wptcmtcnt_max)) { + odesc[0] = 0; + } + + sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.0f,M,%-.*s,%-.46s,%s", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude, + wpt_len, + owpt, + odesc, + icon_token); + mag_writemsg(obuf); + xfree(owpt); + xfree(odesc); + + if (!is_file) { + if (mag_error) { + warning("Protocol error Writing '%s'\n", obuf); + } + } } static -void mag_track_nop(const route_head *rte) +void mag_track_nop(const route_head* rte) { - return; + return; } static -void mag_track_disp(const waypoint *waypointp) +void mag_track_disp(const waypoint* waypointp) { - double ilon, ilat; - double lon, lat; - int lon_deg, lat_deg; - char obuf[200]; - int hms=0; - int fracsec=0; - int date=0; - struct tm *tm = NULL; - - ilat = waypointp->latitude; - ilon = waypointp->longitude; - tm = NULL; - if (waypointp->creation_time) { - tm = gmtime(&waypointp->creation_time); - if ( tm ) { - hms = tm->tm_hour * 10000 + tm->tm_min * 100 + - tm->tm_sec; - date = tm->tm_mday * 10000 + tm->tm_mon * 100 + - tm->tm_year; - fracsec = MICRO_TO_CENTI(waypointp->microseconds); - } - } - if (!tm) { - date = 0; - fracsec = 0; - } - - lon = fabs(ilon); - lat = fabs(ilat); - - lon_deg = lon; - lat_deg = lat; - - lon = (lon - lon_deg) * 60.0; - lat = (lat - lat_deg) * 60.0; - - lon = (lon_deg * 100.0 + lon); - lat = (lat_deg * 100.0 + lat); - - sprintf(obuf,"PMGNTRK,%4.3f,%c,%09.3f,%c,%05.0f,%c,%06d.%02d,A,,%06d", - lat, ilat < 0 ? 'S' : 'N', - lon, ilon < 0 ? 'W' : 'E', - waypointp->altitude == unknown_alt ? - 0 : waypointp->altitude, - 'M',hms,fracsec,date); - mag_writemsg(obuf); + double ilon, ilat; + double lon, lat; + int lon_deg, lat_deg; + char obuf[200]; + int hms=0; + int fracsec=0; + int date=0; + struct tm* tm = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + tm = NULL; + if (waypointp->creation_time) { + tm = gmtime(&waypointp->creation_time); + if (tm) { + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + + tm->tm_sec; + date = tm->tm_mday * 10000 + tm->tm_mon * 100 + + tm->tm_year; + fracsec = MICRO_TO_CENTI(waypointp->microseconds); + } + } + if (!tm) { + date = 0; + fracsec = 0; + } + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + sprintf(obuf,"PMGNTRK,%4.3f,%c,%09.3f,%c,%05.0f,%c,%06d.%02d,A,,%06d", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude, + 'M',hms,fracsec,date); + mag_writemsg(obuf); } static void mag_track_pr() { - track_disp_all(mag_track_nop, mag_track_nop, mag_track_disp); + track_disp_all(mag_track_nop, mag_track_nop, mag_track_disp); } /* @@ -1398,88 +1491,90 @@ Meridian SD card and serial (at least) writes in pairs: $PMGNRTE,4,1,c,1,HOME,c,I49X73,a*15 ... $PMGNRTE,4,4,c,1,RON273,a,MYCF93,a*7B - + The spec also says that some units don't like single-legged pairs, and to replace the 2nd name with "<<>>", but I haven't seen one of those. */ static void -mag_route_trl(const route_head * rte) +mag_route_trl(const route_head* rte) { - queue *elem, *tmp; - waypoint *waypointp; - char obuff[256]; - char buff1[64], buff2[64]; - char *pbuff, *owpt; - const char * icon_token; - int i, numlines, thisline; - - /* count waypoints for this route */ - i = rte->rte_waypt_ct; - - /* number of output PMGNRTE messages at 2 points per line */ - numlines = (i / 2) + (i % 2); - - /* increment the route counter. */ - route_out_count++; - - thisline = i = 0; - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - waypointp = (waypoint *) elem; - i++; - - if (deficon) - icon_token = mag_find_token_from_descr(deficon); - else - icon_token = mag_find_token_from_descr(waypointp->icon_descr); - - if (i == 1) - pbuff = buff1; - else - pbuff = buff2; - - owpt = waypointp->shortname; - if (strlen(owpt) > sizeof(buff1) - 3) { - owpt[sizeof(buff1) - 3] = 0; - } - owpt = mag_cleanse(owpt); - - sprintf(pbuff, "%s,%s", owpt, icon_token); - - xfree(owpt); - - if ((tmp == &rte->waypoint_list) || ((i % 2) == 0)) { - char expbuf[1024]; - thisline++; - expbuf[0] = 0; - if (explorist) { - snprintf(expbuf, sizeof(expbuf), "%s,", - rte->rte_name ? rte->rte_name : ""); - } - sprintf(obuff, "PMGNRTE,%d,%d,c,%d,%s%s,%s", - numlines, thisline, - rte->rte_num ? rte->rte_num : route_out_count, - expbuf, - buff1, buff2); - - mag_writemsg(obuff); - buff1[0] = '\0'; - buff2[0] = '\0'; - i = 0; - } - } + queue* elem, *tmp; + waypoint* waypointp; + char obuff[256]; + char buff1[64], buff2[64]; + char* pbuff, *owpt; + const char* icon_token; + int i, numlines, thisline; + + /* count waypoints for this route */ + i = rte->rte_waypt_ct; + + /* number of output PMGNRTE messages at 2 points per line */ + numlines = (i / 2) + (i % 2); + + /* increment the route counter. */ + route_out_count++; + + thisline = i = 0; + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + waypointp = (waypoint*) elem; + i++; + + if (deficon) { + icon_token = mag_find_token_from_descr(deficon); + } else { + icon_token = mag_find_token_from_descr(waypointp->icon_descr); + } + + if (i == 1) { + pbuff = buff1; + } else { + pbuff = buff2; + } + + owpt = waypointp->shortname; + if (strlen(owpt) > sizeof(buff1) - 3) { + owpt[sizeof(buff1) - 3] = 0; + } + owpt = mag_cleanse(owpt); + + sprintf(pbuff, "%s,%s", owpt, icon_token); + + xfree(owpt); + + if ((tmp == &rte->waypoint_list) || ((i % 2) == 0)) { + char expbuf[1024]; + thisline++; + expbuf[0] = 0; + if (explorist) { + snprintf(expbuf, sizeof(expbuf), "%s,", + rte->rte_name ? rte->rte_name : ""); + } + sprintf(obuff, "PMGNRTE,%d,%d,c,%d,%s%s,%s", + numlines, thisline, + rte->rte_num ? rte->rte_num : route_out_count, + expbuf, + buff1, buff2); + + mag_writemsg(obuff); + buff1[0] = '\0'; + buff2[0] = '\0'; + i = 0; + } + } } static void -mag_route_hdr(const route_head *rh) +mag_route_hdr(const route_head* rh) { } static void mag_route_pr() { - route_out_count = 0; - route_disp_all(mag_route_hdr, mag_route_trl, mag_waypt_pr); + route_out_count = 0; + route_disp_all(mag_route_hdr, mag_route_trl, mag_waypt_pr); } @@ -1487,22 +1582,50 @@ static void mag_write(void) { - wptcmtcnt = 0; - - switch (global_opts.objective) - { - case trkdata: - mag_track_pr(); - break; - case wptdata: - waypt_disp_all(mag_waypt_pr); - break; - case rtedata: - mag_route_pr(); - break; - default: - fatal(MYNAME ": Unknown objective.\n"); - } + wptcmtcnt = 0; + + switch (global_opts.objective) { + case trkdata: + mag_track_pr(); + break; + case wptdata: + waypt_disp_all(mag_waypt_pr); + break; + case rtedata: + mag_route_pr(); + break; + default: + fatal(MYNAME ": Unknown objective.\n"); + } +} + +const char** os_get_magellan_mountpoints() +{ +#if __APPLE__ + const char** dlist = (const char**) xcalloc(2, sizeof *dlist); + dlist[0] = xstrdup("/Volumes/Magellan"); + dlist[1] = NULL; + return dlist; +#else + fatal("Not implemented"); +#endif +} + +// My kingdom for container classes and portable tree-walking... +// Returns a pointer to a static vector that's valid until the next call. +static char** +os_gpx_files(const char* dirname) +{ +#if HAVE_GLOB + static glob_t g; + char* path; + xasprintf(&path, "%s/*.gpx", dirname); + glob(path, 0, NULL, &g); + xfree(path); + return g.gl_pathv; +#else + fatal("Not implemented"); +#endif } /* @@ -1510,46 +1633,46 @@ mag_write(void) * for the benefit of GUI wrappers. */ ff_vecs_t mag_svecs = { - ff_type_serial, - FF_CAP_RW_ALL, - mag_rd_init, - mag_wr_init, - mag_deinit, - mag_deinit, - mag_read, - mag_write, - NULL, - mag_sargs, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_serial, + FF_CAP_RW_ALL, + mag_rd_init, + mag_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_sargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; ff_vecs_t mag_fvecs = { - ff_type_file, - FF_CAP_RW_ALL, - mag_rd_init, - mag_wr_init, - mag_deinit, - mag_deinit, - mag_read, - mag_write, - NULL, - mag_fargs, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + mag_rd_init, + mag_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_fargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; /* * Extended (Explorist) entry tables. */ ff_vecs_t magX_fvecs = { - ff_type_file, - FF_CAP_RW_ALL, - magX_rd_init, - magX_wr_init, - mag_deinit, - mag_deinit, - mag_read, - mag_write, - NULL, - mag_fargs, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + magX_rd_init, + magX_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_fargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/main.c b/gpsbabel/main.c index ff3115f24..ce0199ed6 100644 --- a/gpsbabel/main.c +++ b/gpsbabel/main.c @@ -33,690 +33,709 @@ void signal_handler(int sig); typedef struct arg_stack_s { - int argn; - int argc; - char **argv; - struct arg_stack_s *prev; + int argn; + int argc; + char** argv; + struct arg_stack_s* prev; } arg_stack_t; static arg_stack_t -*push_args(arg_stack_t *stack, const int argn, const int argc, char *argv[]) +*push_args(arg_stack_t* stack, const int argn, const int argc, char* argv[]) { - arg_stack_t *res = (arg_stack_t *) xmalloc(sizeof(*res)); - - res->prev = stack; - res->argn = argn; - res->argc = argc; - res->argv = (char **)argv; - - return res; + arg_stack_t* res = (arg_stack_t*) xmalloc(sizeof(*res)); + + res->prev = stack; + res->argn = argn; + res->argc = argc; + res->argv = (char**)argv; + + return res; } static arg_stack_t -*pop_args(arg_stack_t *stack, int *argn, int *argc, char **argv[]) +*pop_args(arg_stack_t* stack, int* argn, int* argc, char** argv[]) { - arg_stack_t *res; - char **argv2 = *argv; - int i; - - if (stack == NULL) fatal("main: Invalid point in time to call 'pop_args'\n"); - - for (i = 0; i < *argc; i++) - xfree(argv2[i]); - xfree(*argv); - - *argn = stack->argn; - *argc = stack->argc; - *argv = stack->argv; - - res = stack->prev; - xfree(stack); - - return res; + arg_stack_t* res; + char** argv2 = *argv; + int i; + + if (stack == NULL) { + fatal("main: Invalid point in time to call 'pop_args'\n"); + } + + for (i = 0; i < *argc; i++) { + xfree(argv2[i]); + } + xfree(*argv); + + *argn = stack->argn; + *argc = stack->argc; + *argv = stack->argv; + + res = stack->prev; + xfree(stack); + + return res; } static void -load_args(const char *filename, int *argc, char **argv[]) +load_args(const char* filename, int* argc, char** argv[]) { - gbfile *fin; - char *str, *line = NULL; - int argc2; - char **argv2; - - fin = gbfopen(filename, "r", "main"); - while ((str = gbfgetstr(fin))) { - str = lrtrim(str); - if ((*str == '\0') || (*str == '#')) continue; - - if (line == NULL) line = xstrdup(str); - else { - char *tmp; - xasprintf(&tmp, "%s %s", line, str); - xfree(line); - line = tmp; - } - } - gbfclose(fin); - - argv2 = (char **) xmalloc(2 * sizeof(*argv2)); - argv2[0] = xstrdup(*argv[0]); - argc2 = 1; - - str = csv_lineparse(line, " ", "\"", 0); - while (str != NULL) { - argv2 = (char **) xrealloc(argv2, (argc2 + 2) * sizeof(*argv2)); - argv2[argc2] = xstrdup(str); - argc2++; - str = csv_lineparse(NULL, " ", "\"", 0); - } - xfree(line); - - argv2[argc2] = NULL; - - *argc = argc2; - *argv = argv2; + gbfile* fin; + char* str, *line = NULL; + int argc2; + char** argv2; + + fin = gbfopen(filename, "r", "main"); + while ((str = gbfgetstr(fin))) { + str = lrtrim(str); + if ((*str == '\0') || (*str == '#')) { + continue; + } + + if (line == NULL) { + line = xstrdup(str); + } else { + char* tmp; + xasprintf(&tmp, "%s %s", line, str); + xfree(line); + line = tmp; + } + } + gbfclose(fin); + + argv2 = (char**) xmalloc(2 * sizeof(*argv2)); + argv2[0] = xstrdup(*argv[0]); + argc2 = 1; + + str = csv_lineparse(line, " ", "\"", 0); + while (str != NULL) { + argv2 = (char**) xrealloc(argv2, (argc2 + 2) * sizeof(*argv2)); + argv2[argc2] = xstrdup(str); + argc2++; + str = csv_lineparse(NULL, " ", "\"", 0); + } + xfree(line); + + argv2[argc2] = NULL; + + *argc = argc2; + *argv = argv2; } static void -usage(const char *pname, int shorter ) +usage(const char* pname, int shorter) { - printf("GPSBabel Version %s. http://www.gpsbabel.org\n\n", - gpsbabel_version ); - printf( -"Usage:\n" -" %s [options] -i INTYPE -f INFILE [filter] -o OUTTYPE -F OUTFILE\n" -" %s [options] -i INTYPE -o OUTTYPE INFILE [filter] OUTFILE\n" -"\n" -" Converts GPS route and waypoint data from one format type to another.\n" -" The input type and filename are specified with the -i INTYPE\n" -" and -f INFILE options. The output type and filename are specified\n" -" with the -o OUTTYPE and -F OUTFILE options.\n" -" If '-' is used for INFILE or OUTFILE, stdin or stdout will be used.\n" -"\n" -" In the second form of the command, INFILE and OUTFILE are the\n" -" first and second positional (non-option) arguments.\n" -"\n" -" INTYPE and OUTTYPE must be one of the supported file types and\n" -" may include options valid for that file type. For example:\n" -" 'gpx', 'gpx,snlen=10' and 'ozi,snlen=10,snwhite=1'\n" -" (without the quotes) are all valid file type specifications.\n" -"\n" -"Options:\n" -" -p Preferences file (gpsbabel.ini)\n" -" -s Synthesize shortnames\n" -" -r Process route information\n" -" -t Process track information\n" -" -T Process realtime tracking information\n" -" -w Process waypoint information [default]\n" -" -b Process command file (batch mode)\n" -" -c Character set for next operation\n" -" -N No smart icons on output\n" -" -x filtername Invoke filter (placed between inputs and output) \n" -" -D level Set debug level [%d]\n" -" -l Print GPSBabel builtin character sets and exit\n" -" -h, -? Print detailed help and exit\n" -" -V Print GPSBabel version and exit\n" -"\n" - , pname - , pname - , global_opts.debug_level - ); - if ( shorter ) { - printf( "\n\n[Press enter]" ); - fgetc(stdin); - } - else { - printf("File Types (-i and -o options):\n"); - disp_vecs(); - printf("\nSupported data filters:\n"); - disp_filter_vecs(); - } + printf("GPSBabel Version %s. http://www.gpsbabel.org\n\n", + gpsbabel_version); + printf( + "Usage:\n" + " %s [options] -i INTYPE -f INFILE [filter] -o OUTTYPE -F OUTFILE\n" + " %s [options] -i INTYPE -o OUTTYPE INFILE [filter] OUTFILE\n" + "\n" + " Converts GPS route and waypoint data from one format type to another.\n" + " The input type and filename are specified with the -i INTYPE\n" + " and -f INFILE options. The output type and filename are specified\n" + " with the -o OUTTYPE and -F OUTFILE options.\n" + " If '-' is used for INFILE or OUTFILE, stdin or stdout will be used.\n" + "\n" + " In the second form of the command, INFILE and OUTFILE are the\n" + " first and second positional (non-option) arguments.\n" + "\n" + " INTYPE and OUTTYPE must be one of the supported file types and\n" + " may include options valid for that file type. For example:\n" + " 'gpx', 'gpx,snlen=10' and 'ozi,snlen=10,snwhite=1'\n" + " (without the quotes) are all valid file type specifications.\n" + "\n" + "Options:\n" + " -p Preferences file (gpsbabel.ini)\n" + " -s Synthesize shortnames\n" + " -r Process route information\n" + " -t Process track information\n" + " -T Process realtime tracking information\n" + " -w Process waypoint information [default]\n" + " -b Process command file (batch mode)\n" + " -c Character set for next operation\n" + " -N No smart icons on output\n" + " -x filtername Invoke filter (placed between inputs and output) \n" + " -D level Set debug level [%d]\n" + " -l Print GPSBabel builtin character sets and exit\n" + " -h, -? Print detailed help and exit\n" + " -V Print GPSBabel version and exit\n" + "\n" + , pname + , pname + , global_opts.debug_level + ); + if (shorter) { + printf("\n\n[Press enter]"); + fgetc(stdin); + } else { + printf("File Types (-i and -o options):\n"); + disp_vecs(); + printf("\nSupported data filters:\n"); + disp_filter_vecs(); + } } -static void -spec_usage( const char *vec ) { - printf( "\n" ); - disp_vec( vec ); - disp_filter_vec ( vec ); - printf( "\n" ); +static void +spec_usage(const char* vec) +{ + printf("\n"); + disp_vec(vec); + disp_filter_vec(vec); + printf("\n"); } static void print_extended_info(void) { - printf( + printf( #if !ZLIB_INHIBITED /* Note polarity inverted here */ - "ZLIB_ENABLED " + "ZLIB_ENABLED " #endif #if FILTERS_ENABLED - "FILTERS_ENABLED " + "FILTERS_ENABLED " #endif #if CSVFMTS_ENABLED - "CSVFMTS_ENABLED " + "CSVFMTS_ENABLED " #endif -#if PDBFMTS_ENABLED - "PDBFMTS_ENABLED " +#if PDBFMTS_ENABLED + "PDBFMTS_ENABLED " #endif -#if SHAPELIB_ENABLED - "SHAPELIB_ENABLED " +#if SHAPELIB_ENABLED + "SHAPELIB_ENABLED " #endif #if HAVE_LIBEXPAT - "HAVE_LIBEXPAT " + "HAVE_LIBEXPAT " #if defined(XML_UNICODE) - "XML_UNICODE " + "XML_UNICODE " #endif #endif -#if defined CET_WANTED - "CET_ENABLED " +#if defined CET_WANTED + "CET_ENABLED " #endif - "\n"); + "\n"); } int -main(int argc, char *argv[]) +main(int argc, char* argv[]) { - int c; - int argn; - ff_vecs_t *ivecs = NULL; - ff_vecs_t *ovecs = NULL; - filter_vecs_t *fvecs = NULL; - char *fname = NULL; - char *ofname = NULL; - char *ivec_opts = NULL; - char *ovec_opts = NULL; - char *fvec_opts = NULL; - int opt_version = 0; - int did_something = 0; - const char *prog_name = argv[0]; /* argv is modified during processing */ - queue *wpt_head_bak, *rte_head_bak, *trk_head_bak; /* #ifdef UTF8_SUPPORT */ - signed int wpt_ct_bak, rte_ct_bak, trk_ct_bak; /* #ifdef UTF8_SUPPORT */ - arg_stack_t *arg_stack = NULL; - - global_opts.objective = wptdata; - global_opts.masked_objective = NOTHINGMASK; /* this makes the default mask behaviour slightly different */ - global_opts.charset = NULL; - global_opts.charset_name = NULL; - global_opts.inifile = NULL; - - gpsbabel_now = time(NULL); /* gpsbabel startup-time */ - gpsbabel_time = current_time(); /* same like gpsbabel_now, but freezed to zero during testo */ - + int c; + int argn; + ff_vecs_t* ivecs = NULL; + ff_vecs_t* ovecs = NULL; + filter_vecs_t* fvecs = NULL; + char* fname = NULL; + char* ofname = NULL; + char* ivec_opts = NULL; + char* ovec_opts = NULL; + char* fvec_opts = NULL; + int opt_version = 0; + int did_something = 0; + const char* prog_name = argv[0]; /* argv is modified during processing */ + queue* wpt_head_bak, *rte_head_bak, *trk_head_bak; /* #ifdef UTF8_SUPPORT */ + signed int wpt_ct_bak, rte_ct_bak, trk_ct_bak; /* #ifdef UTF8_SUPPORT */ + arg_stack_t* arg_stack = NULL; + + global_opts.objective = wptdata; + global_opts.masked_objective = NOTHINGMASK; /* this makes the default mask behaviour slightly different */ + global_opts.charset = NULL; + global_opts.charset_name = NULL; + global_opts.inifile = NULL; + + gpsbabel_now = time(NULL); /* gpsbabel startup-time */ + gpsbabel_time = current_time(); /* same like gpsbabel_now, but freezed to zero during testo */ + #ifdef DEBUG_MEM - debug_mem_open(); - debug_mem_output( "command line: " ); - for ( argn = 1; argn < argc; argn++ ) { - debug_mem_output( "%s ", argv[argn] ); - } - debug_mem_output( "\n" ); + debug_mem_open(); + debug_mem_output("command line: "); + for (argn = 1; argn < argc; argn++) { + debug_mem_output("%s ", argv[argn]); + } + debug_mem_output("\n"); #endif - if (gpsbabel_time != 0) { /* within testo ? */ - global_opts.inifile = inifile_init(NULL, MYNAME); - } - - init_vecs(); - init_filter_vecs(); - cet_register(); - session_init(); - waypt_init(); - route_init(); - - if ( argc < 2 ) { - usage(argv[0],1); - exit(0); - } - - /* - * Open-code getopts since POSIX-impaired OSes don't have one. - */ - argn = 1; - while (argn < argc) { - char *optarg; - - if (argv[argn][0] != '-') { - break; - } - if (argv[argn][1] == '-') { - break; - } - - if (argv[argn][1] == 'V' ) { - printf("\nGPSBabel Version %s\n\n", gpsbabel_version ); - if (argv[argn][2] == 'V') { - print_extended_info(); - } - exit(0); - } - - if (argv[argn][1] == '?' || argv[argn][1] == 'h') { - if ( argn < argc-1 ) { - spec_usage( argv[argn+1] ); - } - else { - usage(argv[0],0); - } - exit(0); - } - - c = argv[argn][1]; - - if (argv[argn][2]) { - opt_version = atoi(&argv[argn][2]); - } - - switch (c) { - case 'c': - optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; - cet_convert_init(optarg, 1); - break; - case 'i': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - ivecs = find_vec(optarg, &ivec_opts); - if (ivecs == NULL) { - fatal ("Input type '%s' not recognized\n", optarg); - } - break; - case 'o': - if (ivecs == NULL) { - warning ("-o appeared before -i. This is probably not what you want to do.\n"); - } - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - ovecs = find_vec(optarg, &ovec_opts); - if (ovecs == NULL) { - fatal ("Output type '%s' not recognized\n", optarg); - } - break; - case 'f': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - fname = optarg; - if (fname == NULL) { - fatal ("No file or device name specified.\n"); - } - if (ivecs == NULL) { - fatal ("No valid input type specified\n"); - } - if (ivecs->rd_init == NULL) { - fatal ("Format does not support reading.\n"); - } - if (global_opts.masked_objective & POSNDATAMASK) { - did_something = 1; - break; - } - /* simulates the default behaviour of waypoints */ - if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; - - cet_convert_init(ivecs->encode, ivecs->fixed_encode); /* init by module vec */ - - start_session(ivecs->name, fname); - ivecs->rd_init(fname); - ivecs->read(); - ivecs->rd_deinit(); - - cet_convert_strings(global_opts.charset, NULL, NULL); - cet_convert_deinit(); - - did_something = 1; - break; - case 'F': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - ofname = optarg; - if (ofname == NULL) { - fatal ("No output file or device name specified.\n"); - } - if (ovecs && (!(global_opts.masked_objective & POSNDATAMASK))) { - /* simulates the default behaviour of waypoints */ - if (doing_nothing) - global_opts.masked_objective |= WPTDATAMASK; - if (ovecs->wr_init == NULL) { - fatal ("Format does not support writing.\n"); - } - - cet_convert_init(ovecs->encode, ovecs->fixed_encode); - - wpt_ct_bak = -1; - rte_ct_bak = -1; - trk_ct_bak = -1; - rte_head_bak = trk_head_bak = NULL; - - ovecs->wr_init(ofname); - - if (global_opts.charset != &cet_cs_vec_utf8) - { - /* - * Push and pop verbose_status so - * we don't get dual progress bars - * when doing characterset - * transformation. - */ - int saved_status = global_opts.verbose_status; - global_opts.verbose_status = 0; - waypt_backup(&wpt_ct_bak, &wpt_head_bak); - route_backup(&rte_ct_bak, &rte_head_bak); - track_backup(&trk_ct_bak, &trk_head_bak); - - cet_convert_strings(NULL, global_opts.charset, NULL); - global_opts.verbose_status = saved_status; - } - - ovecs->write(); - ovecs->wr_deinit(); - - cet_convert_deinit(); - - if (wpt_ct_bak != -1) waypt_restore(wpt_ct_bak, wpt_head_bak); - if (rte_ct_bak != -1) { - route_restore( rte_head_bak); - xfree( rte_head_bak ); - } - if (trk_ct_bak != -1) { - track_restore( trk_head_bak); - xfree( trk_head_bak ); - } - } - break; - case 's': - global_opts.synthesize_shortnames = 1; - break; - case 't': - global_opts.objective = trkdata; - global_opts.masked_objective |= TRKDATAMASK; - break; - case 'w': - global_opts.objective = wptdata; - global_opts.masked_objective |= WPTDATAMASK; - break; - case 'r': - global_opts.objective = rtedata; - global_opts.masked_objective |= RTEDATAMASK; - break; - case 'T': - global_opts.objective = posndata; - global_opts.masked_objective |= POSNDATAMASK; - break; - case 'N': + if (gpsbabel_time != 0) { /* within testo ? */ + global_opts.inifile = inifile_init(NULL, MYNAME); + } + + init_vecs(); + init_filter_vecs(); + cet_register(); + session_init(); + waypt_init(); + route_init(); + + if (argc < 2) { + usage(argv[0],1); + exit(0); + } + + /* + * Open-code getopts since POSIX-impaired OSes don't have one. + */ + argn = 1; + while (argn < argc) { + char* optarg; + + if (argv[argn][0] != '-') { + break; + } + if (argv[argn][1] == '-') { + break; + } + + if (argv[argn][1] == 'V') { + printf("\nGPSBabel Version %s\n\n", gpsbabel_version); + if (argv[argn][2] == 'V') { + print_extended_info(); + } + exit(0); + } + + if (argv[argn][1] == '?' || argv[argn][1] == 'h') { + if (argn < argc-1) { + spec_usage(argv[argn+1]); + } else { + usage(argv[0],0); + } + exit(0); + } + + c = argv[argn][1]; + + if (argv[argn][2]) { + opt_version = atoi(&argv[argn][2]); + } + + switch (c) { + case 'c': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + cet_convert_init(optarg, 1); + break; + case 'i': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ivecs = find_vec(optarg, &ivec_opts); + if (ivecs == NULL) { + fatal("Input type '%s' not recognized\n", optarg); + } + break; + case 'o': + if (ivecs == NULL) { + warning("-o appeared before -i. This is probably not what you want to do.\n"); + } + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ovecs = find_vec(optarg, &ovec_opts); + if (ovecs == NULL) { + fatal("Output type '%s' not recognized\n", optarg); + } + break; + case 'f': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + fname = optarg; + if (fname == NULL) { + fatal("No file or device name specified.\n"); + } + if (ivecs == NULL) { + fatal("No valid input type specified\n"); + } + if (ivecs->rd_init == NULL) { + fatal("Format does not support reading.\n"); + } + if (global_opts.masked_objective & POSNDATAMASK) { + did_something = 1; + break; + } + /* simulates the default behaviour of waypoints */ + if (doing_nothing) { + global_opts.masked_objective |= WPTDATAMASK; + } + + cet_convert_init(ivecs->encode, ivecs->fixed_encode); /* init by module vec */ + + start_session(ivecs->name, fname); + ivecs->rd_init(fname); + ivecs->read(); + ivecs->rd_deinit(); + + cet_convert_strings(global_opts.charset, NULL, NULL); + cet_convert_deinit(); + + did_something = 1; + break; + case 'F': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ofname = optarg; + if (ofname == NULL) { + fatal("No output file or device name specified.\n"); + } + if (ovecs && (!(global_opts.masked_objective & POSNDATAMASK))) { + /* simulates the default behaviour of waypoints */ + if (doing_nothing) { + global_opts.masked_objective |= WPTDATAMASK; + } + if (ovecs->wr_init == NULL) { + fatal("Format does not support writing.\n"); + } + + cet_convert_init(ovecs->encode, ovecs->fixed_encode); + + wpt_ct_bak = -1; + rte_ct_bak = -1; + trk_ct_bak = -1; + rte_head_bak = trk_head_bak = NULL; + + ovecs->wr_init(ofname); + + if (global_opts.charset != &cet_cs_vec_utf8) { + /* + * Push and pop verbose_status so + * we don't get dual progress bars + * when doing characterset + * transformation. + */ + int saved_status = global_opts.verbose_status; + global_opts.verbose_status = 0; + waypt_backup(&wpt_ct_bak, &wpt_head_bak); + route_backup(&rte_ct_bak, &rte_head_bak); + track_backup(&trk_ct_bak, &trk_head_bak); + + cet_convert_strings(NULL, global_opts.charset, NULL); + global_opts.verbose_status = saved_status; + } + + ovecs->write(); + ovecs->wr_deinit(); + + cet_convert_deinit(); + + if (wpt_ct_bak != -1) { + waypt_restore(wpt_ct_bak, wpt_head_bak); + } + if (rte_ct_bak != -1) { + route_restore(rte_head_bak); + xfree(rte_head_bak); + } + if (trk_ct_bak != -1) { + track_restore(trk_head_bak); + xfree(trk_head_bak); + } + } + break; + case 's': + global_opts.synthesize_shortnames = 1; + break; + case 't': + global_opts.objective = trkdata; + global_opts.masked_objective |= TRKDATAMASK; + break; + case 'w': + global_opts.objective = wptdata; + global_opts.masked_objective |= WPTDATAMASK; + break; + case 'r': + global_opts.objective = rtedata; + global_opts.masked_objective |= RTEDATAMASK; + break; + case 'T': + global_opts.objective = posndata; + global_opts.masked_objective |= POSNDATAMASK; + break; + case 'N': #if 0 -/* This option is silently eaten for compatibilty. -N is now the - * default. If you want the old behaviour, -S allows you to individually - * turn them on. The -N option will be removed in 2008. - */ - - switch(argv[argn][2]) { - case 'i': - global_opts.no_smart_icons = 1; - break; - case 'n': - global_opts.no_smart_names = 1; - break; - default: - global_opts.no_smart_names = 1; - global_opts.no_smart_icons = 1; - break; - } + /* This option is silently eaten for compatibilty. -N is now the + * default. If you want the old behaviour, -S allows you to individually + * turn them on. The -N option will be removed in 2008. + */ + + switch (argv[argn][2]) { + case 'i': + global_opts.no_smart_icons = 1; + break; + case 'n': + global_opts.no_smart_names = 1; + break; + default: + global_opts.no_smart_names = 1; + global_opts.no_smart_icons = 1; + break; + } #endif - - break; - case 'S': - switch(argv[argn][2]) { - case 'i': - global_opts.smart_icons = 1; - break; - case 'n': - global_opts.smart_names = 1; - break; - default: - global_opts.smart_icons = 1; - global_opts.smart_names = 1; - break; - } - break; - case 'x': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - fvecs = find_filter_vec(optarg, &fvec_opts); - - if (fvecs) { - if (fvecs->f_init) fvecs->f_init(fvec_opts); - fvecs->f_process(); - if (fvecs->f_deinit) fvecs->f_deinit(); - free_filter_vec(fvecs); - } else { - fatal("Unknown filter '%s'\n",optarg); - } - break; - case 'D': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - global_opts.debug_level = atoi(optarg); - /* - * When debugging, announce version. - */ - if (global_opts.debug_level > 0) { - warning("GPSBabel Version: %s \n", gpsbabel_version ); - } - - break; - /* - * Undocumented '-vs' option for GUI wrappers. - */ - case 'v': - switch(argv[argn][2]) { - case 's': global_opts.verbose_status = 1; break; - case 'S': global_opts.verbose_status = 2; break; - } - break; - - /* - * DOS-derived systems will need to escape - * this as -^^. - */ - case '^': - disp_formats(opt_version); - exit(0); - case '%': - disp_filters(opt_version); - exit(0); - case 'h': - case '?': - usage(argv[0],0); - exit(0); - case 'l': - cet_disp_character_set_names(stdout); - exit(0); - case 'p': - optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; - inifile_done(global_opts.inifile); - if (!optarg || strcmp(optarg, "") == 0) /* from GUI to preserve inconsistent options */ - global_opts.inifile = NULL; - else - global_opts.inifile = inifile_init(optarg, MYNAME); - break; - case 'b': - optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; - arg_stack = push_args(arg_stack, argn, argc, argv); - load_args(optarg, &argc, &argv); - if (argc == 0) - arg_stack = pop_args(arg_stack, &argn, &argc, &argv); - else - argn = 0; - break; - - default: - fatal("Unknown option '%s'.\n", argv[argn]); - break; - } - - if ((argn+1 >= argc) && (arg_stack != NULL)) - arg_stack = pop_args(arg_stack, &argn, &argc, &argv); - argn++; - } - - /* - * Allow input and output files to be specified positionally - * as well. This is the typical command line format. - */ - argc -= argn; - argv += argn; - if (argc > 2) { - fatal ("Extra arguments on command line\n"); - } - else if (argc && ivecs) { - did_something = 1; - /* simulates the default behaviour of waypoints */ - if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; - - cet_convert_init(ivecs->encode, 1); - - start_session(ivecs->name, argv[0]); - if (ivecs->rd_init == NULL) { - fatal ("Format does not support reading.\n"); - } - ivecs->rd_init(argv[0]); - ivecs->read(); - ivecs->rd_deinit(); - - cet_convert_strings(global_opts.charset, NULL, NULL); - cet_convert_deinit(); - - if (argc == 2 && ovecs) - { - cet_convert_init(ovecs->encode, 1); - cet_convert_strings(NULL, global_opts.charset, NULL); - - if (ovecs->wr_init == NULL) { - fatal ("Format does not support writing.\n"); - } - - ovecs->wr_init(argv[1]); - ovecs->write(); - ovecs->wr_deinit(); - - cet_convert_deinit(); - } - } - else if (argc) { - usage(prog_name,0); - exit(0); - } - if (ovecs == NULL) - { - /* - * Push and pop verbose_status so we don't get dual - * progress bars when doing characterset transformation. - */ - int saved_status = global_opts.verbose_status; - global_opts.verbose_status = 0; - cet_convert_init(CET_CHARSET_ASCII, 1); - cet_convert_strings(NULL, global_opts.charset, NULL); - waypt_disp_all(waypt_disp); - global_opts.verbose_status = saved_status; - } - - /* - * This is very unlike the rest of our command sequence. - * If we're doing realtime position tracking, we enforce that - * we're not doing anything else and we just bounce between - * the special "read position" and "write position" vectors - * in our most recent vecs. - */ - if (global_opts.masked_objective & POSNDATAMASK) { - - if (!ivecs) { - fatal("Realtime tracking (-T) requires an input type (-t)i such as Garmin or NMEA.\n"); - } - - if (!ivecs->position_ops.rd_position) { - fatal("Realtime tracking (-T) is not suppored by this input type.\n"); - } - - - if (ivecs->position_ops.rd_init) { - if (!fname) { - fatal("An input file (-f) must be specified.\n"); - } - start_session(ivecs->name, fname); - ivecs->position_ops.rd_init(fname); - } - - if (global_opts.masked_objective & ~POSNDATAMASK) { - fatal("Realtime tracking (-T) is exclusive of other modes.\n"); - } - - if (ovecs) { - if ( !ovecs->position_ops.wr_position ) { - fatal ("This output format does not support output of realtime positioning.\n"); - } - } - - if (signal(SIGINT, signal_handler) == SIG_ERR) { - fatal ("Couldn't install the exit signal handler.\n"); - } - - if (ovecs && ovecs->position_ops.wr_init) { - ovecs->position_ops.wr_init(ofname); - } - - tracking_status.request_terminate = 0; - while (!tracking_status.request_terminate) { - waypoint *wpt; - - wpt = ivecs->position_ops.rd_position(&tracking_status); - - if (tracking_status.request_terminate) { - if (wpt) { - waypt_free(wpt); - } - break; - } - if (wpt) { - if (ovecs) { + + break; + case 'S': + switch (argv[argn][2]) { + case 'i': + global_opts.smart_icons = 1; + break; + case 'n': + global_opts.smart_names = 1; + break; + default: + global_opts.smart_icons = 1; + global_opts.smart_names = 1; + break; + } + break; + case 'x': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + fvecs = find_filter_vec(optarg, &fvec_opts); + + if (fvecs) { + if (fvecs->f_init) { + fvecs->f_init(fvec_opts); + } + fvecs->f_process(); + if (fvecs->f_deinit) { + fvecs->f_deinit(); + } + free_filter_vec(fvecs); + } else { + fatal("Unknown filter '%s'\n",optarg); + } + break; + case 'D': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + global_opts.debug_level = atoi(optarg); + /* + * When debugging, announce version. + */ + if (global_opts.debug_level > 0) { + warning("GPSBabel Version: %s \n", gpsbabel_version); + } + + break; + /* + * Undocumented '-vs' option for GUI wrappers. + */ + case 'v': + switch (argv[argn][2]) { + case 's': + global_opts.verbose_status = 1; + break; + case 'S': + global_opts.verbose_status = 2; + break; + } + break; + + /* + * DOS-derived systems will need to escape + * this as -^^. + */ + case '^': + disp_formats(opt_version); + exit(0); + case '%': + disp_filters(opt_version); + exit(0); + case 'h': + case '?': + usage(argv[0],0); + exit(0); + case 'l': + cet_disp_character_set_names(stdout); + exit(0); + case 'p': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + inifile_done(global_opts.inifile); + if (!optarg || strcmp(optarg, "") == 0) { /* from GUI to preserve inconsistent options */ + global_opts.inifile = NULL; + } else { + global_opts.inifile = inifile_init(optarg, MYNAME); + } + break; + case 'b': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + arg_stack = push_args(arg_stack, argn, argc, argv); + load_args(optarg, &argc, &argv); + if (argc == 0) { + arg_stack = pop_args(arg_stack, &argn, &argc, &argv); + } else { + argn = 0; + } + break; + + default: + fatal("Unknown option '%s'.\n", argv[argn]); + break; + } + + if ((argn+1 >= argc) && (arg_stack != NULL)) { + arg_stack = pop_args(arg_stack, &argn, &argc, &argv); + } + argn++; + } + + /* + * Allow input and output files to be specified positionally + * as well. This is the typical command line format. + */ + argc -= argn; + argv += argn; + if (argc > 2) { + fatal("Extra arguments on command line\n"); + } else if (argc && ivecs) { + did_something = 1; + /* simulates the default behaviour of waypoints */ + if (doing_nothing) { + global_opts.masked_objective |= WPTDATAMASK; + } + + cet_convert_init(ivecs->encode, 1); + + start_session(ivecs->name, argv[0]); + if (ivecs->rd_init == NULL) { + fatal("Format does not support reading.\n"); + } + ivecs->rd_init(argv[0]); + ivecs->read(); + ivecs->rd_deinit(); + + cet_convert_strings(global_opts.charset, NULL, NULL); + cet_convert_deinit(); + + if (argc == 2 && ovecs) { + cet_convert_init(ovecs->encode, 1); + cet_convert_strings(NULL, global_opts.charset, NULL); + + if (ovecs->wr_init == NULL) { + fatal("Format does not support writing.\n"); + } + + ovecs->wr_init(argv[1]); + ovecs->write(); + ovecs->wr_deinit(); + + cet_convert_deinit(); + } + } else if (argc) { + usage(prog_name,0); + exit(0); + } + if (ovecs == NULL) { + /* + * Push and pop verbose_status so we don't get dual + * progress bars when doing characterset transformation. + */ + int saved_status = global_opts.verbose_status; + global_opts.verbose_status = 0; + cet_convert_init(CET_CHARSET_ASCII, 1); + cet_convert_strings(NULL, global_opts.charset, NULL); + waypt_disp_all(waypt_disp); + global_opts.verbose_status = saved_status; + } + + /* + * This is very unlike the rest of our command sequence. + * If we're doing realtime position tracking, we enforce that + * we're not doing anything else and we just bounce between + * the special "read position" and "write position" vectors + * in our most recent vecs. + */ + if (global_opts.masked_objective & POSNDATAMASK) { + + if (!ivecs) { + fatal("Realtime tracking (-T) requires an input type (-t)i such as Garmin or NMEA.\n"); + } + + if (!ivecs->position_ops.rd_position) { + fatal("Realtime tracking (-T) is not suppored by this input type.\n"); + } + + + if (ivecs->position_ops.rd_init) { + if (!fname) { + fatal("An input file (-f) must be specified.\n"); + } + start_session(ivecs->name, fname); + ivecs->position_ops.rd_init(fname); + } + + if (global_opts.masked_objective & ~POSNDATAMASK) { + fatal("Realtime tracking (-T) is exclusive of other modes.\n"); + } + + if (ovecs) { + if (!ovecs->position_ops.wr_position) { + fatal("This output format does not support output of realtime positioning.\n"); + } + } + + if (signal(SIGINT, signal_handler) == SIG_ERR) { + fatal("Couldn't install the exit signal handler.\n"); + } + + if (ovecs && ovecs->position_ops.wr_init) { + ovecs->position_ops.wr_init(ofname); + } + + tracking_status.request_terminate = 0; + while (!tracking_status.request_terminate) { + waypoint* wpt; + + wpt = ivecs->position_ops.rd_position(&tracking_status); + + if (tracking_status.request_terminate) { + if (wpt) { + waypt_free(wpt); + } + break; + } + if (wpt) { + if (ovecs) { // ovecs->position_ops.wr_init(ofname); - ovecs->position_ops.wr_position(wpt); + ovecs->position_ops.wr_position(wpt); // ovecs->position_ops.wr_deinit(); - } else { - /* Just print to screen */ - waypt_disp(wpt); - } - waypt_free(wpt); - } - } - if (ivecs->position_ops.rd_deinit) { - ivecs->position_ops.rd_deinit(); - } - if (ovecs && ovecs->position_ops.wr_deinit) { - ovecs->position_ops.wr_deinit(); - } - exit(0); - } - - - if (!did_something) - fatal ("Nothing to do! Use '%s -h' for command-line options.\n", prog_name); - - cet_deregister(); - waypt_flush_all(); - route_flush_all(); - session_exit(); - exit_vecs(); - exit_filter_vecs(); - inifile_done(global_opts.inifile); + } else { + /* Just print to screen */ + waypt_disp(wpt); + } + waypt_free(wpt); + } + } + if (ivecs->position_ops.rd_deinit) { + ivecs->position_ops.rd_deinit(); + } + if (ovecs && ovecs->position_ops.wr_deinit) { + ovecs->position_ops.wr_deinit(); + } + exit(0); + } + + + if (!did_something) { + fatal("Nothing to do! Use '%s -h' for command-line options.\n", prog_name); + } + + cet_deregister(); + waypt_flush_all(); + route_flush_all(); + session_exit(); + exit_vecs(); + exit_filter_vecs(); + inifile_done(global_opts.inifile); #ifdef DEBUG_MEM - debug_mem_close(); + debug_mem_close(); #endif - exit(0); + exit(0); } void signal_handler(int sig) { - tracking_status.request_terminate = 1; + tracking_status.request_terminate = 1; } diff --git a/gpsbabel/make-an1sym.pl b/gpsbabel/make-an1sym.pl index 276699b2a..1b6f47728 100755 --- a/gpsbabel/make-an1sym.pl +++ b/gpsbabel/make-an1sym.pl @@ -278,7 +278,7 @@ print <<'END'; struct defguid { GUID guid; - char *name; + const char *name; } default_guids[] = { END } diff --git a/gpsbabel/mapasia.c b/gpsbabel/mapasia.c index 58d04bbfe..25ab6c633 100644 --- a/gpsbabel/mapasia.c +++ b/gpsbabel/mapasia.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include #include #include @@ -46,15 +46,15 @@ #define TR7_S_VALID 28 #define TR7_S_FIX 29 -static gbfile *fin, *fout; -static const waypoint *wpt_tmp; -static const route_head *trk_tmp; +static gbfile* fin, *fout; +static const waypoint* wpt_tmp; +static const route_head* trk_tmp; static int course_tmp, speed_tmp; struct tm tmref; static arglist_t tr7_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /******************************************************************************* @@ -62,136 +62,149 @@ arglist_t tr7_args[] = { *******************************************************************************/ static void -tr7_rd_init(const char *fname) +tr7_rd_init(const char* fname) { - fin = gbfopen_le(fname, "rb", MYNAME); - tmref = *gmtime(&gpsbabel_now); - tmref.tm_year += 1900; - tmref.tm_mon += 1; + fin = gbfopen_le(fname, "rb", MYNAME); + tmref = *gmtime(&gpsbabel_now); + tmref.tm_year += 1900; + tmref.tm_mon += 1; } static void tr7_read(void) { - route_head *trk = NULL; - unsigned int magic; - waypoint *prev = NULL; - - magic = gbfgetint32(fin); - if (magic != TR7_TRACK_MAGIC) { - fatal(MYNAME ": Invalid magic number in header (%X, but %X expected)!\n", magic, TR7_TRACK_MAGIC); - } - - while (! gbfeof(fin)) { - unsigned char buff[TR7_S_SIZE]; - double lat, lon; - struct tm tm; - waypoint *wpt; - float speed, course; - - gbfread(buff, 1, sizeof(buff), fin); - - memset(&tm, 0, sizeof(tm)); - - lat = (double)le_read32(&buff[TR7_S_LAT]) / 1000000.0; - lon = (double)le_read32(&buff[TR7_S_LON]) / 1000000.0; - - if ((fabs(lat) > 90) || (fabs(lon) > 180)) { /* that really happens */ - trk = NULL; - continue; - } - - tm.tm_year = le_read16(&buff[TR7_S_YEAR]); - tm.tm_mon = buff[TR7_S_MONTH]; - tm.tm_mday = buff[TR7_S_DAY]; - tm.tm_hour = buff[TR7_S_HOUR]; - tm.tm_min = buff[TR7_S_MIN]; - tm.tm_sec = buff[TR7_S_SEC]; - - if ((tm.tm_mday < 1) || (tm.tm_mday > 31) || - (tm.tm_mon < 1) || (tm.tm_mon > 12) || - (tm.tm_year <= 1970) || - (tm.tm_year > tmref.tm_year+1)) continue; - - speed = KPH_TO_MPS(le_read16(&buff[TR7_S_SPEED])); - course = 360 - le_read16(&buff[TR7_S_COURSE]); - if ((speed < 0) || (course > 360) || (course < 0)) continue; - - wpt = waypt_new(); - - wpt->latitude = lat; - wpt->longitude = lon; - - tm.tm_year -= 1900; - tm.tm_mon -= 1; - wpt->creation_time = mkgmtime(&tm); - - WAYPT_SET(wpt, course, course); - WAYPT_SET(wpt, speed, speed); + route_head* trk = NULL; + unsigned int magic; + waypoint* prev = NULL; + + magic = gbfgetint32(fin); + if (magic != TR7_TRACK_MAGIC) { + fatal(MYNAME ": Invalid magic number in header (%X, but %X expected)!\n", magic, TR7_TRACK_MAGIC); + } + + while (! gbfeof(fin)) { + unsigned char buff[TR7_S_SIZE]; + double lat, lon; + struct tm tm; + waypoint* wpt; + float speed, course; + + gbfread(buff, 1, sizeof(buff), fin); + + memset(&tm, 0, sizeof(tm)); + + lat = (double)le_read32(&buff[TR7_S_LAT]) / 1000000.0; + lon = (double)le_read32(&buff[TR7_S_LON]) / 1000000.0; + + if ((fabs(lat) > 90) || (fabs(lon) > 180)) { /* that really happens */ + trk = NULL; + continue; + } + + tm.tm_year = le_read16(&buff[TR7_S_YEAR]); + tm.tm_mon = buff[TR7_S_MONTH]; + tm.tm_mday = buff[TR7_S_DAY]; + tm.tm_hour = buff[TR7_S_HOUR]; + tm.tm_min = buff[TR7_S_MIN]; + tm.tm_sec = buff[TR7_S_SEC]; + + if ((tm.tm_mday < 1) || (tm.tm_mday > 31) || + (tm.tm_mon < 1) || (tm.tm_mon > 12) || + (tm.tm_year <= 1970) || + (tm.tm_year > tmref.tm_year+1)) { + continue; + } + + speed = KPH_TO_MPS(le_read16(&buff[TR7_S_SPEED])); + course = 360 - le_read16(&buff[TR7_S_COURSE]); + if ((speed < 0) || (course > 360) || (course < 0)) { + continue; + } + + wpt = waypt_new(); + + wpt->latitude = lat; + wpt->longitude = lon; + + tm.tm_year -= 1900; + tm.tm_mon -= 1; + wpt->creation_time = mkgmtime(&tm); + + WAYPT_SET(wpt, course, course); + WAYPT_SET(wpt, speed, speed); #if 0 /* unsure, not validated items */ - wpt->fix = buff[TR7_S_FIX]; - if (buff[TR7_S_VALID] != 'A') { - waypt_free(wpt); - continue; - } + wpt->fix = buff[TR7_S_FIX]; + if (buff[TR7_S_VALID] != 'A') { + waypt_free(wpt); + continue; + } #endif - if (waypt_speed(prev, wpt) > 9999.9) { /* filter out some bad trackpoints */ - waypt_free(wpt); - continue; - } - - if (prev) { /* other track or bad timestamp */ - if (wpt->creation_time && (prev->creation_time > wpt->creation_time)) trk = NULL; - else if (waypt_distance(prev, wpt) > 9999.9) trk = NULL; - } - - if (! trk) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - prev = wpt; - } + if (waypt_speed(prev, wpt) > 9999.9) { /* filter out some bad trackpoints */ + waypt_free(wpt); + continue; + } + + if (prev) { /* other track or bad timestamp */ + if (wpt->creation_time && (prev->creation_time > wpt->creation_time)) { + trk = NULL; + } else if (waypt_distance(prev, wpt) > 9999.9) { + trk = NULL; + } + } + + if (! trk) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + prev = wpt; + } } static void -tr7_check_after_read_head_cb(const route_head *trk) +tr7_check_after_read_head_cb(const route_head* trk) { - trk_tmp = trk; - course_tmp = 0; - speed_tmp = 0; + trk_tmp = trk; + course_tmp = 0; + speed_tmp = 0; } static void -tr7_check_after_read_wpt_cb(const waypoint *wpt) +tr7_check_after_read_wpt_cb(const waypoint* wpt) { - if (wpt->speed != 0) speed_tmp = 1; - if (wpt->course != 360.0) course_tmp = 1; + if (wpt->speed != 0) { + speed_tmp = 1; + } + if (wpt->course != 360.0) { + course_tmp = 1; + } } static void -tr7_check_after_read_trailer_cb(const route_head *trk) +tr7_check_after_read_trailer_cb(const route_head* trk) { - queue *elem, *tmp; - QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - if (speed_tmp == 0) WAYPT_UNSET(wpt, speed); - if (course_tmp == 0) { - WAYPT_UNSET(wpt, course); - wpt->course = 0; - } - } + queue* elem, *tmp; + QUEUE_FOR_EACH((queue*)&trk->waypoint_list, elem, tmp) { + waypoint* wpt = (waypoint*)elem; + if (speed_tmp == 0) { + WAYPT_UNSET(wpt, speed); + } + if (course_tmp == 0) { + WAYPT_UNSET(wpt, course); + wpt->course = 0; + } + } } -static void +static void tr7_rd_deinit(void) { - track_disp_session(curr_session(), - tr7_check_after_read_head_cb, - tr7_check_after_read_trailer_cb, - tr7_check_after_read_wpt_cb); - gbfclose(fin); + track_disp_session(curr_session(), + tr7_check_after_read_head_cb, + tr7_check_after_read_trailer_cb, + tr7_check_after_read_wpt_cb); + gbfclose(fin); } /******************************************************************************* @@ -199,90 +212,104 @@ tr7_rd_deinit(void) *******************************************************************************/ static void -tr7_disp_track_head_cb(const route_head *trk) +tr7_disp_track_head_cb(const route_head* trk) { - wpt_tmp = NULL; + wpt_tmp = NULL; } static void -tr7_disp_waypt_cb(const waypoint *wpt) +tr7_disp_waypt_cb(const waypoint* wpt) { - unsigned char buff[TR7_S_SIZE]; - struct tm tm; - double speed, course; - - memset(buff, 0, sizeof(buff)); - - le_write32(&buff[TR7_S_LON], (int)(wpt->longitude * 1000000.0)); - le_write32(&buff[TR7_S_LAT], (int)(wpt->latitude * 1000000.0)); - - if WAYPT_HAS(wpt, course) course = wpt->course; - else if (wpt_tmp != NULL) course = waypt_course(wpt_tmp, wpt); - else course = -1; - if (course >= 0) le_write16(&buff[TR7_S_COURSE], (int)(360 - course)); - - if (wpt->creation_time) { - tm = *gmtime(&wpt->creation_time); - - le_write16(&buff[TR7_S_YEAR], tm.tm_year + 1900); - buff[TR7_S_MONTH] = tm.tm_mon + 1; - buff[TR7_S_DAY] = tm.tm_mday; - buff[TR7_S_HOUR] = tm.tm_hour; - buff[TR7_S_MIN] = tm.tm_min; - buff[TR7_S_SEC] = tm.tm_sec; - - if WAYPT_HAS(wpt, speed) speed = wpt->speed; - else if (wpt_tmp != NULL) speed = waypt_speed(wpt_tmp, wpt); - else speed = -1; - if (speed >= 0) le_write16(&buff[TR7_S_SPEED], (int)MPS_TO_KPH(speed)); - } - buff[TR7_S_VALID] = 'A'; /* meaning unknown */ + unsigned char buff[TR7_S_SIZE]; + struct tm tm; + double speed, course; + + memset(buff, 0, sizeof(buff)); + + le_write32(&buff[TR7_S_LON], (int)(wpt->longitude * 1000000.0)); + le_write32(&buff[TR7_S_LAT], (int)(wpt->latitude * 1000000.0)); + + if WAYPT_HAS(wpt, course) { + course = wpt->course; + } else if (wpt_tmp != NULL) { + course = waypt_course(wpt_tmp, wpt); + } else { + course = -1; + } + if (course >= 0) { + le_write16(&buff[TR7_S_COURSE], (int)(360 - course)); + } + + if (wpt->creation_time) { + tm = *gmtime(&wpt->creation_time); + + le_write16(&buff[TR7_S_YEAR], tm.tm_year + 1900); + buff[TR7_S_MONTH] = tm.tm_mon + 1; + buff[TR7_S_DAY] = tm.tm_mday; + buff[TR7_S_HOUR] = tm.tm_hour; + buff[TR7_S_MIN] = tm.tm_min; + buff[TR7_S_SEC] = tm.tm_sec; + + if WAYPT_HAS(wpt, speed) { + speed = wpt->speed; + } else if (wpt_tmp != NULL) { + speed = waypt_speed(wpt_tmp, wpt); + } else { + speed = -1; + } + if (speed >= 0) { + le_write16(&buff[TR7_S_SPEED], (int)MPS_TO_KPH(speed)); + } + } + buff[TR7_S_VALID] = 'A'; /* meaning unknown */ #if 0 /* not validated */ - if (wpt->fix != fix_unknown) buff[TR7_S_FIX] = wpt->fix; + if (wpt->fix != fix_unknown) { + buff[TR7_S_FIX] = wpt->fix; + } #endif - gbfwrite(buff, 1, sizeof(buff), fout); - - wpt_tmp = wpt; + gbfwrite(buff, 1, sizeof(buff), fout); + + wpt_tmp = wpt; } static void -tr7_wr_init(const char *fname) +tr7_wr_init(const char* fname) { - fout = gbfopen_le(fname, "wb", MYNAME); - gbfputint32(TR7_TRACK_MAGIC, fout); + fout = gbfopen_le(fname, "wb", MYNAME); + gbfputint32(TR7_TRACK_MAGIC, fout); } static void tr7_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void tr7_write(void) { - track_disp_all(tr7_disp_track_head_cb, NULL, tr7_disp_waypt_cb); + track_disp_all(tr7_disp_track_head_cb, NULL, tr7_disp_waypt_cb); } /**************************************************************************/ ff_vecs_t mapasia_tr7_vecs = { /* we can read and write tracks */ - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - tr7_rd_init, - tr7_wr_init, - tr7_rd_deinit, - tr7_wr_deinit, - tr7_read, - tr7_write, - NULL, - tr7_args, - CET_CHARSET_UTF8, 1 /* FIXED - CET-REVIEW - */ + ff_type_file, + { + ff_cap_none /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + tr7_rd_init, + tr7_wr_init, + tr7_rd_deinit, + tr7_wr_deinit, + tr7_read, + tr7_write, + NULL, + tr7_args, + CET_CHARSET_UTF8, 1 /* FIXED - CET-REVIEW - */ }; diff --git a/gpsbabel/mapopolis.c b/gpsbabel/mapopolis.c index 0e5001c0f..4ff7c7d27 100644 --- a/gpsbabel/mapopolis.c +++ b/gpsbabel/mapopolis.c @@ -33,21 +33,20 @@ #define LATDIV2 (1000000.0/(9*2)) -struct record0 -{ - char unk[6]; - pdb_32 lon1; - pdb_32 lat1; - pdb_32 lon2; - pdb_32 lat2; - pdb_32 lonD; - pdb_32 latD; - char name[31+1]; - char unk2[35]; - char demo; - char unk3[4]; - unsigned char expcode[4]; - /* ... more stuff ... */ +struct record0 { + char unk[6]; + pdb_32 lon1; + pdb_32 lat1; + pdb_32 lon2; + pdb_32 lat2; + pdb_32 lonD; + pdb_32 latD; + char name[31+1]; + char unk2[35]; + char demo; + char unk3[4]; + unsigned char expcode[4]; + /* ... more stuff ... */ }; double Lat1, Lon1; @@ -55,53 +54,53 @@ double Lat2, Lon2; double LatD, LonD; struct record { - char unknown[10]; - pdb_16 unk1; - pdb_16 unk2; - pdb_16 lon1d; - pdb_16 lat1d; - pdb_16 lon2d; - pdb_16 lat2d; + char unknown[10]; + pdb_16 unk1; + pdb_16 unk2; + pdb_16 lon1d; + pdb_16 lat1d; + pdb_16 lon2d; + pdb_16 lat2d; }; -static pdbfile *file_in, *file_out; +static pdbfile* file_in, *file_out; static short_handle mkshort_handle; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void -wr_init(const char *fname) +wr_init(const char* fname) { - file_out = pdb_create(fname, MYNAME); - mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, 20); + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, 20); } static void wr_deinit(void) { - pdb_close(file_out); - mkshort_del_handle(&mkshort_handle); + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); } -convert_rec0(struct record0 *rec0) +convert_rec0(struct record0* rec0) { - Lon1 = be_read32(&rec0->lon1) / LONDIV; - Lat1 = be_read32(&rec0->lat1) / LATDIV; - Lon2 = be_read32(&rec0->lon2) / LONDIV; - Lat2 = be_read32(&rec0->lat2) / LATDIV; - LonD = be_read32(&rec0->lonD) / LONDIV2; - LatD = be_read32(&rec0->latD) / LATDIV2; + Lon1 = be_read32(&rec0->lon1) / LONDIV; + Lat1 = be_read32(&rec0->lat1) / LATDIV; + Lon2 = be_read32(&rec0->lon2) / LONDIV; + Lat2 = be_read32(&rec0->lat2) / LATDIV; + LonD = be_read32(&rec0->lonD) / LONDIV2; + LatD = be_read32(&rec0->latD) / LATDIV2; // printf("%s: %.5f %.5f %.5f %.5f %.5f %.5f\n", // rec0->name, Lat1, Lon1, Lat2, Lon2, LatD, LonD); @@ -113,186 +112,185 @@ convert_rec0(struct record0 *rec0) * * Decode the information field * */ void -decode(char *buf) +decode(char* buf) { - int i; + int i; - for (i = 0; buf[i]; ++i) { - buf[i] = buf[i] ^ ((i % 96) & 0xf); - } + for (i = 0; buf[i]; ++i) { + buf[i] = buf[i] ^ ((i % 96) & 0xf); + } } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; + struct record* rec; + pdbrec_t* pdb_rec; - if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { - fatal(MYNAME ": Not a Magellan Navigator file.\n"); - } + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a Magellan Navigator file.\n"); + } - pdb_rec = file_in->rec_list; - convert_rec0((struct record0*) pdb_rec->data); + pdb_rec = file_in->rec_list; + convert_rec0((struct record0*) pdb_rec->data); // for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) { - for(pdb_rec = pdb_rec->next; pdb_rec; pdb_rec=pdb_rec->next) { - waypoint *wpt_tmp; - char *vdata = 0; - char *edata; - struct tm tm = {0}; - - rec = (struct record *) pdb_rec->data; - edata = (char *) rec + pdb_rec->size; - - for (; vdata < edata; rec = (struct record *) vdata) { - wpt_tmp = waypt_new(); - wpt_tmp->latitude = Lat1 + - be_read16(&rec->lat1d) / LATDIV2; - wpt_tmp->longitude = Lon1 + - be_read16(&rec->lon1d) / LONDIV2; - - vdata = (char *) rec + sizeof(*rec); - wpt_tmp->description = xstrdup(vdata); - vdata += strlen(wpt_tmp->description) + 1 + 6; - - while (*vdata == 0x40) - vdata++; - decode(vdata); - wpt_tmp->notes = xstrdup(vdata); - vdata += strlen(wpt_tmp->notes) + 1; - - waypt_add(wpt_tmp); - } - } + for (pdb_rec = pdb_rec->next; pdb_rec; pdb_rec=pdb_rec->next) { + waypoint* wpt_tmp; + char* vdata = 0; + char* edata; + struct tm tm = {0}; + + rec = (struct record*) pdb_rec->data; + edata = (char*) rec + pdb_rec->size; + + for (; vdata < edata; rec = (struct record*) vdata) { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = Lat1 + + be_read16(&rec->lat1d) / LATDIV2; + wpt_tmp->longitude = Lon1 + + be_read16(&rec->lon1d) / LONDIV2; + + vdata = (char*) rec + sizeof(*rec); + wpt_tmp->description = xstrdup(vdata); + vdata += strlen(wpt_tmp->description) + 1 + 6; + + while (*vdata == 0x40) { + vdata++; + } + decode(vdata); + wpt_tmp->notes = xstrdup(vdata); + vdata += strlen(wpt_tmp->notes) + 1; + + waypt_add(wpt_tmp); + } + } } static void -my_writewpt(const waypoint *wpt) +my_writewpt(const waypoint* wpt) { #if 0 - struct record *rec; - static int ct; - struct tm *tm; - char *vdata; - time_t tm_t; - const char *sn = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, wpt->description) : - wpt->shortname; - - rec = xcalloc(sizeof(*rec)+56,1); - - tm = NULL; - if ( wpt->creation_time ) { - tm = gmtime( &wpt->creation_time); - } - if ( !tm ) { - tm_t = current_time(); - tm = gmtime( &tm_t ); - } - - be_write16( &rec->crt_sec, tm->tm_sec ); - be_write16( &rec->crt_min, tm->tm_min ); - be_write16( &rec->crt_hour, tm->tm_hour ); - be_write16( &rec->crt_mday, tm->tm_mday ); - be_write16( &rec->crt_mon, tm->tm_mon + 1 ); - be_write16( &rec->crt_year, tm->tm_mon + 1900 ); - - be_write16( &rec->unknown, 0); - - be_write16( &rec->xx_sec, tm->tm_sec ); - be_write16( &rec->xx_min, tm->tm_min ); - be_write16( &rec->xx_hour, tm->tm_hour ); - be_write16( &rec->xx_mday, tm->tm_mday ); - be_write16( &rec->xx_mon, tm->tm_mon + 1 ); - be_write16( &rec->xx_year, tm->tm_mon + 1900 ); - - be_write16( &rec->unknown2, 0); - - be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); - be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); - be_write32(&rec->elevation, wpt->altitude); - - rec->plot = 0; - rec->unknown3 = 'a'; - - vdata = (char *)rec + sizeof(*rec); - if ( sn ) { - strncpy( vdata, sn, 21 ); - vdata[20] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - if ( wpt->description ) { - strncpy( vdata, wpt->description, 33 ); - vdata[32] = '\0'; - } - else { - vdata[0] = '\0'; - } - vdata += strlen( vdata ) + 1; - vdata[0] = '\0'; - vdata[1] = '\0'; - vdata += 2; - - pdb_write(file_out, 0, rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct record* rec; + static int ct; + struct tm* tm; + char* vdata; + time_t tm_t; + const char* sn = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, wpt->description) : + wpt->shortname; + + rec = xcalloc(sizeof(*rec)+56,1); + + tm = NULL; + if (wpt->creation_time) { + tm = gmtime(&wpt->creation_time); + } + if (!tm) { + tm_t = current_time(); + tm = gmtime(&tm_t); + } + + be_write16(&rec->crt_sec, tm->tm_sec); + be_write16(&rec->crt_min, tm->tm_min); + be_write16(&rec->crt_hour, tm->tm_hour); + be_write16(&rec->crt_mday, tm->tm_mday); + be_write16(&rec->crt_mon, tm->tm_mon + 1); + be_write16(&rec->crt_year, tm->tm_mon + 1900); + + be_write16(&rec->unknown, 0); + + be_write16(&rec->xx_sec, tm->tm_sec); + be_write16(&rec->xx_min, tm->tm_min); + be_write16(&rec->xx_hour, tm->tm_hour); + be_write16(&rec->xx_mday, tm->tm_mday); + be_write16(&rec->xx_mon, tm->tm_mon + 1); + be_write16(&rec->xx_year, tm->tm_mon + 1900); + + be_write16(&rec->unknown2, 0); + + be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); + be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); + be_write32(&rec->elevation, wpt->altitude); + + rec->plot = 0; + rec->unknown3 = 'a'; + + vdata = (char*)rec + sizeof(*rec); + if (sn) { + strncpy(vdata, sn, 21); + vdata[20] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + if (wpt->description) { + strncpy(vdata, wpt->description, 33); + vdata[32] = '\0'; + } else { + vdata[0] = '\0'; + } + vdata += strlen(vdata) + 1; + vdata[0] = '\0'; + vdata[1] = '\0'; + vdata += 2; + + pdb_write(file_out, 0, rec, (char*)vdata - (char*)rec); + + xfree(rec); #endif } static void data_write(void) { - static char *appinfo = - "\0\x01" - "User\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\x01\x02\x03\x04\x05\x06\x07\x08" - "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; - - strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - file_out->appinfo = (void *)appinfo; - file_out->appinfo_len = 276; - - waypt_disp_all(my_writewpt); + static char* appinfo = + "\0\x01" + "User\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; + + strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + file_out->appinfo = (void*)appinfo; + file_out->appinfo_len = 276; + + waypt_disp_all(my_writewpt); } ff_vecs_t mapopolis_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/mapsend.c b/gpsbabel/mapsend.c index a47f5b0cb..407e4694f 100644 --- a/gpsbabel/mapsend.c +++ b/gpsbabel/mapsend.c @@ -25,8 +25,8 @@ #include "mapsend.h" #include "magellan.h" -static gbfile *mapsend_file_in; -static gbfile *mapsend_file_out; +static gbfile* mapsend_file_in; +static gbfile* mapsend_file_out; static short_handle mkshort_handle; static short_handle wpt_handle; @@ -36,517 +36,542 @@ static int trk_version = 30; #define MYNAME "mapsend" -static char *mapsend_opt_trkver = NULL; +static char* mapsend_opt_trkver = NULL; #define MAPSEND_TRKVER_MIN 3 #define MAPSEND_TRKVER_MAX 4 static arglist_t mapsend_args[] = { - {"trkver", &mapsend_opt_trkver, - "MapSend version TRK file to generate (3,4)", - "4", ARGTYPE_INT, "3", "4" }, - ARG_TERMINATOR + { + "trkver", &mapsend_opt_trkver, + "MapSend version TRK file to generate (3,4)", + "4", ARGTYPE_INT, "3", "4" + }, + ARG_TERMINATOR }; static void -mapsend_init_opts(const char isReading) { /* 1=read, 2=write */ - int opt_trkver; - - /* read & write options here */ - - if (isReading) { - /* reading-only options here */ - } else { - /* writing-only options here */ - - // TRK MapSend version - opt_trkver = atoi(mapsend_opt_trkver); - if ((opt_trkver < MAPSEND_TRKVER_MIN) || (opt_trkver > MAPSEND_TRKVER_MAX)) - fatal(MYNAME ": Unsupported MapSend TRK version \"%s\"!\n", mapsend_opt_trkver); - trk_version = opt_trkver * 10; - } +mapsend_init_opts(const char isReading) /* 1=read, 2=write */ +{ + int opt_trkver; + + /* read & write options here */ + + if (isReading) { + /* reading-only options here */ + } else { + /* writing-only options here */ + + // TRK MapSend version + opt_trkver = atoi(mapsend_opt_trkver); + if ((opt_trkver < MAPSEND_TRKVER_MIN) || (opt_trkver > MAPSEND_TRKVER_MAX)) { + fatal(MYNAME ": Unsupported MapSend TRK version \"%s\"!\n", mapsend_opt_trkver); + } + trk_version = opt_trkver * 10; + } } static void -mapsend_rd_init(const char *fname) +mapsend_rd_init(const char* fname) { - mapsend_init_opts(1); - mapsend_file_in = gbfopen_le(fname, "rb", MYNAME); + mapsend_init_opts(1); + mapsend_file_in = gbfopen_le(fname, "rb", MYNAME); } static void mapsend_rd_deinit(void) { - gbfclose(mapsend_file_in); + gbfclose(mapsend_file_in); } static void -mapsend_wr_init(const char *fname) +mapsend_wr_init(const char* fname) { - mapsend_init_opts(0); - mapsend_file_out = gbfopen(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); + mapsend_init_opts(0); + mapsend_file_out = gbfopen(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); - wpt_handle = mkshort_new_handle(); - setshort_whitespace_ok(wpt_handle, 1); - setshort_length(wpt_handle, 8); + wpt_handle = mkshort_new_handle(); + setshort_whitespace_ok(wpt_handle, 1); + setshort_length(wpt_handle, 8); - route_wp_count = 0; + route_wp_count = 0; } static void mapsend_wr_deinit(void) { - gbfclose(mapsend_file_out); - mkshort_del_handle(&mkshort_handle); - mkshort_del_handle(&wpt_handle); + gbfclose(mapsend_file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&wpt_handle); } static void mapsend_wpt_read(void) { - char tbuf[256]; - int wpt_count, rte_count, rte_num; - int wpt_number; - char wpt_icon; - char wpt_status; - waypoint *wpt_tmp; - route_head *rte_head; - - wpt_count = gbfgetint32(mapsend_file_in); - - while (wpt_count--) { - wpt_tmp = waypt_new(); - - wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); - wpt_tmp->description = gbfgetpstr(mapsend_file_in); - - wpt_number = gbfgetint32(mapsend_file_in); - wpt_icon = gbfgetc(mapsend_file_in); - wpt_status = gbfgetc(mapsend_file_in); - - wpt_tmp->altitude = gbfgetdbl(mapsend_file_in); - wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); - wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); - - if (wpt_icon < 26) - sprintf(tbuf, "%c", wpt_icon + 'a'); - else - sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); - wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); - - waypt_add(wpt_tmp); - } - - /* now read the routes... */ - rte_count = gbfgetint32(mapsend_file_in); - - while (rte_count--) { - rte_head = route_head_alloc(); - route_add_head(rte_head); - - /* route name */ - rte_head->rte_name = gbfgetpstr(mapsend_file_in); - - /* route # */ - rte_num = gbfgetint32(mapsend_file_in); - rte_head->rte_num = rte_num; - - /* points this route */ - wpt_count = gbfgetint32(mapsend_file_in); - - while (wpt_count--) { - wpt_tmp = waypt_new(); - - /* waypoint name */ - wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); - - /* waypoint # */ - wpt_number = gbfgetint32(mapsend_file_in); - wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); - wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); - - gbfread(&wpt_icon, 1, sizeof(wpt_icon), mapsend_file_in); - - if (wpt_icon < 26) - sprintf(tbuf, "%c", wpt_icon + 'a'); - else - sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); - wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); - - route_add_wpt(rte_head, wpt_tmp); - } - } + char tbuf[256]; + int wpt_count, rte_count, rte_num; + int wpt_number; + char wpt_icon; + char wpt_status; + waypoint* wpt_tmp; + route_head* rte_head; + + wpt_count = gbfgetint32(mapsend_file_in); + + while (wpt_count--) { + wpt_tmp = waypt_new(); + + wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); + wpt_tmp->description = gbfgetpstr(mapsend_file_in); + + wpt_number = gbfgetint32(mapsend_file_in); + wpt_icon = gbfgetc(mapsend_file_in); + wpt_status = gbfgetc(mapsend_file_in); + + wpt_tmp->altitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + if (wpt_icon < 26) { + sprintf(tbuf, "%c", wpt_icon + 'a'); + } else { + sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); + } + wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); + + waypt_add(wpt_tmp); + } + + /* now read the routes... */ + rte_count = gbfgetint32(mapsend_file_in); + + while (rte_count--) { + rte_head = route_head_alloc(); + route_add_head(rte_head); + + /* route name */ + rte_head->rte_name = gbfgetpstr(mapsend_file_in); + + /* route # */ + rte_num = gbfgetint32(mapsend_file_in); + rte_head->rte_num = rte_num; + + /* points this route */ + wpt_count = gbfgetint32(mapsend_file_in); + + while (wpt_count--) { + wpt_tmp = waypt_new(); + + /* waypoint name */ + wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); + + /* waypoint # */ + wpt_number = gbfgetint32(mapsend_file_in); + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + gbfread(&wpt_icon, 1, sizeof(wpt_icon), mapsend_file_in); + + if (wpt_icon < 26) { + sprintf(tbuf, "%c", wpt_icon + 'a'); + } else { + sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); + } + wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); + + route_add_wpt(rte_head, wpt_tmp); + } + } } static void mapsend_track_read(void) { - unsigned int trk_count; - int valid; - unsigned char centisecs; - route_head *track_head; - waypoint *wpt_tmp; - - track_head = route_head_alloc(); - track_head->rte_name = gbfgetpstr(mapsend_file_in); - track_add_head(track_head); - - trk_count = gbfgetuint32(mapsend_file_in); - - while (trk_count--) { - wpt_tmp = waypt_new(); - - wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); - wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); - - if (mapsend_infile_version < 36) { /* < version 4.0 */ - wpt_tmp->altitude = gbfgetint32(mapsend_file_in); - } else { - wpt_tmp->altitude = gbfgetflt(mapsend_file_in); - } - if (wpt_tmp->altitude < unknown_alt + 1) - wpt_tmp->altitude = unknown_alt; - wpt_tmp->creation_time = gbfgetint32(mapsend_file_in); - valid = gbfgetint32(mapsend_file_in); - - /* centiseconds only in >= version 3.0 */ - if (mapsend_infile_version >= 34) { - gbfread(¢isecs, 1, 1, mapsend_file_in); - } else { - centisecs = 0; - } - wpt_tmp->microseconds = CENTI_TO_MICRO(centisecs); - - track_add_wpt(track_head, wpt_tmp); - } + unsigned int trk_count; + int valid; + unsigned char centisecs; + route_head* track_head; + waypoint* wpt_tmp; + + track_head = route_head_alloc(); + track_head->rte_name = gbfgetpstr(mapsend_file_in); + track_add_head(track_head); + + trk_count = gbfgetuint32(mapsend_file_in); + + while (trk_count--) { + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + if (mapsend_infile_version < 36) { /* < version 4.0 */ + wpt_tmp->altitude = gbfgetint32(mapsend_file_in); + } else { + wpt_tmp->altitude = gbfgetflt(mapsend_file_in); + } + if (wpt_tmp->altitude < unknown_alt + 1) { + wpt_tmp->altitude = unknown_alt; + } + wpt_tmp->creation_time = gbfgetint32(mapsend_file_in); + valid = gbfgetint32(mapsend_file_in); + + /* centiseconds only in >= version 3.0 */ + if (mapsend_infile_version >= 34) { + gbfread(¢isecs, 1, 1, mapsend_file_in); + } else { + centisecs = 0; + } + wpt_tmp->microseconds = CENTI_TO_MICRO(centisecs); + + track_add_wpt(track_head, wpt_tmp); + } } static void mapsend_read(void) { - mapsend_hdr hdr; - int type, len; - char buf[3]; - - /* - * Because of the silly struct packing and the goofy variable-length - * strings, each member has to be read in one at a time. Grrr. - */ - - len = gbfread(&hdr, 1, sizeof(hdr), mapsend_file_in); - is_fatal(len < sizeof(hdr), MYNAME ": No mapsend or empty file!"); - - type = le_read16(&hdr.ms_type); - strncpy(buf, hdr.ms_version, 2); - buf[2] = '\0'; - - mapsend_infile_version = atoi(buf); - - switch(type) { - case ms_type_wpt: - mapsend_wpt_read(); - break; - case ms_type_track: - mapsend_track_read(); - break; - case ms_type_log: - fatal(MYNAME ", GPS logs not supported.\n"); - case ms_type_rgn: - fatal(MYNAME ", GPS regions not supported.\n"); - default: - fatal(MYNAME ", unknown file type %d\n", type); - } + mapsend_hdr hdr; + int type, len; + char buf[3]; + + /* + * Because of the silly struct packing and the goofy variable-length + * strings, each member has to be read in one at a time. Grrr. + */ + + len = gbfread(&hdr, 1, sizeof(hdr), mapsend_file_in); + is_fatal(len < sizeof(hdr), MYNAME ": No mapsend or empty file!"); + + type = le_read16(&hdr.ms_type); + strncpy(buf, hdr.ms_version, 2); + buf[2] = '\0'; + + mapsend_infile_version = atoi(buf); + + switch (type) { + case ms_type_wpt: + mapsend_wpt_read(); + break; + case ms_type_track: + mapsend_track_read(); + break; + case ms_type_log: + fatal(MYNAME ", GPS logs not supported.\n"); + case ms_type_rgn: + fatal(MYNAME ", GPS regions not supported.\n"); + default: + fatal(MYNAME ", unknown file type %d\n", type); + } } static void -mapsend_waypt_pr(const waypoint *waypointp) +mapsend_waypt_pr(const waypoint* waypointp) { - unsigned char c; - double falt; - static int cnt = 0; - const char *iconp = NULL; - const char *sn = global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, waypointp) : - waypointp->shortname; - char *tmp; - - /* - * The format spec doesn't call out the character set of waypoint - * name and description. Empirically, we can see that it's 8859-1, - * but if we create mapsend files containing those, Mapsend becomes - * grumpy uploading the resulting waypoints and being unable to deal - * with the resulting comm errors. - * - * Ironically, our own Magellan serial module strips the "naughty" - * characters, keeping it more in definition with their own serial - * spec. :-) - * - * So we just decompose the utf8 strings to ascii before stuffing - * them into the Mapsend file. - */ - - - tmp = mkshort(wpt_handle, sn); - gbfputpstr(tmp, mapsend_file_out); - if (tmp) xfree(tmp); - - tmp = waypointp->description; - if (tmp) - c = strlen(tmp); - else - c = 0; - - if (c > 30) c = 30; - gbfputc(c, mapsend_file_out); - gbfwrite(tmp, 1, c, mapsend_file_out); - - /* #, icon, status */ - gbfputint32(++cnt, mapsend_file_out); - - if (waypointp->icon_descr) { - iconp = mag_find_token_from_descr(waypointp->icon_descr); - if (1 == strlen(iconp)) { - c = iconp[0] - 'a'; - } else { - c = iconp[1] - 'a' + 26; - } - } else { - c = 0; - } - if (get_cache_icon(waypointp)) { - iconp = mag_find_token_from_descr(get_cache_icon(waypointp)); - if (1 == strlen(iconp)) { - c = iconp[0] - 'a'; - } else { - c = iconp[1] - 'a' + 26; - } - } - - gbfwrite(&c, 1, 1, mapsend_file_out); - gbfputc(1, mapsend_file_out); - - falt = waypointp->altitude; - if (falt == unknown_alt) - falt = 0; - gbfputdbl(falt, mapsend_file_out); - - gbfputdbl(waypointp->longitude, mapsend_file_out); - gbfputdbl(-waypointp->latitude, mapsend_file_out); + unsigned char c; + double falt; + static int cnt = 0; + const char* iconp = NULL; + const char* sn = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, waypointp) : + waypointp->shortname; + char* tmp; + + /* + * The format spec doesn't call out the character set of waypoint + * name and description. Empirically, we can see that it's 8859-1, + * but if we create mapsend files containing those, Mapsend becomes + * grumpy uploading the resulting waypoints and being unable to deal + * with the resulting comm errors. + * + * Ironically, our own Magellan serial module strips the "naughty" + * characters, keeping it more in definition with their own serial + * spec. :-) + * + * So we just decompose the utf8 strings to ascii before stuffing + * them into the Mapsend file. + */ + + + tmp = mkshort(wpt_handle, sn); + gbfputpstr(tmp, mapsend_file_out); + if (tmp) { + xfree(tmp); + } + + tmp = waypointp->description; + if (tmp) { + c = strlen(tmp); + } else { + c = 0; + } + + if (c > 30) { + c = 30; + } + gbfputc(c, mapsend_file_out); + gbfwrite(tmp, 1, c, mapsend_file_out); + + /* #, icon, status */ + gbfputint32(++cnt, mapsend_file_out); + + if (waypointp->icon_descr) { + iconp = mag_find_token_from_descr(waypointp->icon_descr); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } else { + c = 0; + } + if (get_cache_icon(waypointp)) { + iconp = mag_find_token_from_descr(get_cache_icon(waypointp)); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } + + gbfwrite(&c, 1, 1, mapsend_file_out); + gbfputc(1, mapsend_file_out); + + falt = waypointp->altitude; + if (falt == unknown_alt) { + falt = 0; + } + gbfputdbl(falt, mapsend_file_out); + + gbfputdbl(waypointp->longitude, mapsend_file_out); + gbfputdbl(-waypointp->latitude, mapsend_file_out); } -static void -mapsend_route_hdr(const route_head *rte) +static void +mapsend_route_hdr(const route_head* rte) { - char * rname; - - /* route name -- mapsend really seems to want something here.. */ - if (!rte->rte_name) - rname = xstrdup("Route"); - else - rname = xstrdup(rte->rte_name); - gbfputpstr(rname, mapsend_file_out); - - xfree(rname); - - /* route # */ - gbfputint32(rte->rte_num, mapsend_file_out); - - /* # of waypoints to follow... */ - gbfputint32(rte->rte_waypt_ct, mapsend_file_out); + char* rname; + + /* route name -- mapsend really seems to want something here.. */ + if (!rte->rte_name) { + rname = xstrdup("Route"); + } else { + rname = xstrdup(rte->rte_name); + } + gbfputpstr(rname, mapsend_file_out); + + xfree(rname); + + /* route # */ + gbfputint32(rte->rte_num, mapsend_file_out); + + /* # of waypoints to follow... */ + gbfputint32(rte->rte_waypt_ct, mapsend_file_out); } -static void -mapsend_noop(const route_head *wp) +static void +mapsend_noop(const route_head* wp) { - /* no-op */ + /* no-op */ } -static void -mapsend_route_disp(const waypoint *waypointp) +static void +mapsend_route_disp(const waypoint* waypointp) { - unsigned char c; - const char *iconp; - - route_wp_count++; - - /* waypoint name */ - c = waypointp->shortname ? strlen(waypointp->shortname) : 0; - gbfwrite(&c, 1, 1, mapsend_file_out); - gbfwrite(waypointp->shortname, 1, c, mapsend_file_out); - - /* waypoint number */ - gbfputint32(route_wp_count, mapsend_file_out); - - gbfputdbl(waypointp->longitude, mapsend_file_out); - gbfputdbl(-waypointp->latitude, mapsend_file_out); - - if (waypointp->icon_descr) { - iconp = mag_find_token_from_descr(waypointp->icon_descr); - if (1 == strlen(iconp)) { - c = iconp[0] - 'a'; - } else { - c = iconp[1] - 'a' + 26; - } - } else { - c = 0; - } - gbfwrite(&c, 1, 1, mapsend_file_out); + unsigned char c; + const char* iconp; + + route_wp_count++; + + /* waypoint name */ + c = waypointp->shortname ? strlen(waypointp->shortname) : 0; + gbfwrite(&c, 1, 1, mapsend_file_out); + gbfwrite(waypointp->shortname, 1, c, mapsend_file_out); + + /* waypoint number */ + gbfputint32(route_wp_count, mapsend_file_out); + + gbfputdbl(waypointp->longitude, mapsend_file_out); + gbfputdbl(-waypointp->latitude, mapsend_file_out); + + if (waypointp->icon_descr) { + iconp = mag_find_token_from_descr(waypointp->icon_descr); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } else { + c = 0; + } + gbfwrite(&c, 1, 1, mapsend_file_out); } -void mapsend_track_hdr(const route_head * trk) +void mapsend_track_hdr(const route_head* trk) { - /* - * we write mapsend v3.0 tracks as mapsend v2.0 tracks get - * tremendously out of whack time/date wise. - */ - char *verstring = "30"; - queue *elem, *tmp; - char *tname; - int i; - mapsend_hdr hdr = {13, "4D533334 MS", "30", ms_type_track, {0, 0, 0}}; - - switch (trk_version) { - case 20: verstring = "30"; break; - case 30: verstring = "34"; break; - case 40: - /* the signature seems to change with the versions, even though it - * shouldn't have according to the document. MapSend V4 doesn't - * like the old version. - */ - hdr.ms_signature[7] = '6'; - verstring = "36"; - break; - default: fatal("Unknown track version.\n"); break; - } - - hdr.ms_version[0] = verstring[0]; - hdr.ms_version[1] = verstring[1]; - - gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); - - /* track name */ - if (!trk->rte_name) - tname = xstrdup("Track"); - else - tname = xstrdup(trk->rte_name); - gbfputpstr(tname, mapsend_file_out); - - xfree(tname); - - /* total nodes (waypoints) this track */ - i = 0; - QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { - i++; - } - - gbfputint32(i, mapsend_file_out); - + /* + * we write mapsend v3.0 tracks as mapsend v2.0 tracks get + * tremendously out of whack time/date wise. + */ + char* verstring = "30"; + queue* elem, *tmp; + char* tname; + int i; + mapsend_hdr hdr = {13, {'4','D','5','3','3','3','3','4',' ','M','S'}, + {'3','0'}, ms_type_track, {0, 0, 0} + }; + + switch (trk_version) { + case 20: + verstring = "30"; + break; + case 30: + verstring = "34"; + break; + case 40: + /* the signature seems to change with the versions, even though it + * shouldn't have according to the document. MapSend V4 doesn't + * like the old version. + */ + hdr.ms_signature[7] = '6'; + verstring = "36"; + break; + default: + fatal("Unknown track version.\n"); + break; + } + + hdr.ms_version[0] = verstring[0]; + hdr.ms_version[1] = verstring[1]; + + gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); + + /* track name */ + if (!trk->rte_name) { + tname = xstrdup("Track"); + } else { + tname = xstrdup(trk->rte_name); + } + gbfputpstr(tname, mapsend_file_out); + + xfree(tname); + + /* total nodes (waypoints) this track */ + i = 0; + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + i++; + } + + gbfputint32(i, mapsend_file_out); + } -void mapsend_track_disp(const waypoint * wpt) +void mapsend_track_disp(const waypoint* wpt) { - unsigned char c; - int t; - static int last_time; - - /* - * Firmware Ver 4.06 (at least) has a defect when it's set for .01km - * tracking that will sometimes result in timestamps in the track - * going BACKWARDS. When mapsend sees this, it (stupidly) advances - * the date by one, ignoring the date on the TRK lines. This looks - * for time travel and just uses the previous time - it's better to - * be thought to be standing still than to be time-travelling! - * - * This is rumoured (but yet unconfirmed) to be fixed in f/w 5.12. - */ - t = wpt->creation_time; - if (t < last_time) { - t = last_time; - } - - /* x = longitude */ - gbfputdbl(wpt->longitude, mapsend_file_out); - - /* x = latitude */ - gbfputdbl(-wpt->latitude, mapsend_file_out); - - /* altitude - * in V4.0+ this field is a float, it was previously an int - */ - if (trk_version < 40) { - gbfputint32((int) wpt->altitude, mapsend_file_out); - } else { - gbfputflt((float) wpt->altitude, mapsend_file_out); - } - - /* time */ - gbfputint32(t, mapsend_file_out); - last_time = t; - - /* validity */ - gbfputint32(1, mapsend_file_out); - - /* 0 centiseconds */ - if (trk_version >= 30) { - c = MICRO_TO_CENTI(wpt->microseconds); - gbfwrite(&c, 1, 1, mapsend_file_out); - } + unsigned char c; + int t; + static int last_time; + + /* + * Firmware Ver 4.06 (at least) has a defect when it's set for .01km + * tracking that will sometimes result in timestamps in the track + * going BACKWARDS. When mapsend sees this, it (stupidly) advances + * the date by one, ignoring the date on the TRK lines. This looks + * for time travel and just uses the previous time - it's better to + * be thought to be standing still than to be time-travelling! + * + * This is rumoured (but yet unconfirmed) to be fixed in f/w 5.12. + */ + t = wpt->creation_time; + if (t < last_time) { + t = last_time; + } + + /* x = longitude */ + gbfputdbl(wpt->longitude, mapsend_file_out); + + /* x = latitude */ + gbfputdbl(-wpt->latitude, mapsend_file_out); + + /* altitude + * in V4.0+ this field is a float, it was previously an int + */ + if (trk_version < 40) { + gbfputint32((int) wpt->altitude, mapsend_file_out); + } else { + gbfputflt((float) wpt->altitude, mapsend_file_out); + } + + /* time */ + gbfputint32(t, mapsend_file_out); + last_time = t; + + /* validity */ + gbfputint32(1, mapsend_file_out); + + /* 0 centiseconds */ + if (trk_version >= 30) { + c = MICRO_TO_CENTI(wpt->microseconds); + gbfwrite(&c, 1, 1, mapsend_file_out); + } } -void +void mapsend_track_write(void) { - track_disp_all(mapsend_track_hdr, mapsend_noop, mapsend_track_disp); + track_disp_all(mapsend_track_hdr, mapsend_noop, mapsend_track_disp); } static void mapsend_wpt_write(void) { - mapsend_hdr hdr = {13, {"4D533330 MS"}, {"30"}, ms_type_wpt, {0, 0, 0}}; - int n = 0; - int wpt_count = waypt_count(); - - if (global_opts.objective == trkdata) { - mapsend_track_write(); - } else { - gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); - - if (global_opts.objective == wptdata) { - gbfputint32(wpt_count, mapsend_file_out); - waypt_disp_all(mapsend_waypt_pr); - } else - if (global_opts.objective == rtedata) { - - /* # of points - all routes */ - gbfputint32(route_waypt_count(), mapsend_file_out); - - /* write points - all routes */ - route_disp_all(mapsend_noop, mapsend_noop, mapsend_waypt_pr); - } - - n = route_count(); - - gbfputint32(n, mapsend_file_out); - - if (n) - route_disp_all(mapsend_route_hdr, mapsend_noop, mapsend_route_disp); - } + mapsend_hdr hdr = {13, {'4','D','5','3','3','3','3','0',' ','M','S'}, + {'3', '0'}, ms_type_wpt, {0, 0, 0} + }; + int n = 0; + int wpt_count = waypt_count(); + + if (global_opts.objective == trkdata) { + mapsend_track_write(); + } else { + gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); + + if (global_opts.objective == wptdata) { + gbfputint32(wpt_count, mapsend_file_out); + waypt_disp_all(mapsend_waypt_pr); + } else if (global_opts.objective == rtedata) { + + /* # of points - all routes */ + gbfputint32(route_waypt_count(), mapsend_file_out); + + /* write points - all routes */ + route_disp_all(mapsend_noop, mapsend_noop, mapsend_waypt_pr); + } + + n = route_count(); + + gbfputint32(n, mapsend_file_out); + + if (n) { + route_disp_all(mapsend_route_hdr, mapsend_noop, mapsend_route_disp); + } + } } ff_vecs_t mapsend_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - mapsend_rd_init, - mapsend_wr_init, - mapsend_rd_deinit, - mapsend_wr_deinit, - mapsend_read, - mapsend_wpt_write, - NULL, - mapsend_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + mapsend_rd_init, + mapsend_wr_init, + mapsend_rd_deinit, + mapsend_wr_deinit, + mapsend_read, + mapsend_wpt_write, + NULL, + mapsend_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/mapsend.h b/gpsbabel/mapsend.h index 2d1ef9448..193b1832e 100644 --- a/gpsbabel/mapsend.h +++ b/gpsbabel/mapsend.h @@ -20,25 +20,25 @@ * * Information from: * Mapsend File Format Description Revision 1.1, March 6, 2002 from Thales. - * + * * Note this file format was clearly NOT designed for cross-architecture - * portability. In fact, because of the pascal nature of the 'string' - * data type described in that document, it's impractical to describe + * portability. In fact, because of the pascal nature of the 'string' + * data type described in that document, it's impractical to describe * a 'struct waypoint' in C. - * + * */ typedef struct { - char ms_length; - char ms_signature[11]; - char ms_version[2]; - char ms_type; - char _ms_type[3]; + char ms_length; + char ms_signature[11]; + char ms_version[2]; + char ms_type; + char _ms_type[3]; } mapsend_hdr; typedef enum { - ms_type_rgn = 0, - ms_type_wpt = 1, - ms_type_track = 2, - ms_type_log = 3 + ms_type_rgn = 0, + ms_type_wpt = 1, + ms_type_track = 2, + ms_type_log = 3 } ms_type; diff --git a/gpsbabel/mapsource.c b/gpsbabel/mapsource.c index 22f0f23b2..ecea85cad 100644 --- a/gpsbabel/mapsource.c +++ b/gpsbabel/mapsource.c @@ -29,9 +29,9 @@ #include "jeeps/gpsmath.h" #include -static gbfile *mps_file_in; -static gbfile *mps_file_out; -static gbfile *mps_file_temp; +static gbfile* mps_file_in; +static gbfile* mps_file_out; +static gbfile* mps_file_temp; static short_handle mkshort_handle; static int mps_ver_in = 0; @@ -39,10 +39,10 @@ static int mps_ver_out = 0; static int mps_ver_temp = 0; /* Temporary pathname used when merging gpsbabel output with an existing file */ -static char *tempname; -static char *fin_name; +static char* tempname; +static char* fin_name; -static const waypoint *prevRouteWpt; +static const waypoint* prevRouteWpt; /* Private queues of written out waypoints */ static queue written_wpt_head; static queue written_route_wpt_head; @@ -55,7 +55,7 @@ static short_handle read_route_wpt_mkshort_handle; #define MPSDEFAULTWPTCLASS 0 #define MPSHIDDENROUTEWPTCLASS 8 -#define MYNAME "MAPSOURCE" +#define MYNAME "MAPSOURCE" #define ISME 0 #define NOTME 1 @@ -67,73 +67,83 @@ static short_handle read_route_wpt_mkshort_handle; #define MPSDESCBUFFERLEN 4096 -char *snlen = NULL; -char *snwhiteopt = NULL; -char *mpsverout = NULL; -char *mpsmergeouts = NULL; -int mpsmergeout; -char *mpsusedepth = NULL; -char *mpsuseprox = NULL; +static char* snlen = NULL; +static char* snwhiteopt = NULL; +static char* mpsverout = NULL; +static char* mpsmergeouts = NULL; +static int mpsmergeout; +static char* mpsusedepth = NULL; +static char* mpsuseprox = NULL; static arglist_t mps_args[] = { - {"snlen", &snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, - { "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"mpsverout", &mpsverout, - "Version of mapsource file to generate (3,4,5)", NULL, - ARGTYPE_INT, ARG_NOMINMAX }, - {"mpsmergeout", &mpsmergeouts, "Merge output with existing file", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"mpsusedepth", &mpsusedepth, - "Use depth values on output (default is ignore)", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - {"mpsuseprox", &mpsuseprox, - "Use proximity values on output (default is ignore)", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + {"snlen", &snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + { + "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "mpsverout", &mpsverout, + "Version of mapsource file to generate (3,4,5)", NULL, + ARGTYPE_INT, ARG_NOMINMAX + }, + { + "mpsmergeout", &mpsmergeouts, "Merge output with existing file", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "mpsusedepth", &mpsusedepth, + "Use depth values on output (default is ignore)", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "mpsuseprox", &mpsuseprox, + "Use proximity values on output (default is ignore)", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static void -mps_noop(const route_head *wp) +static void +mps_noop(const route_head* wp) { - /* no-op */ + /* no-op */ } void -mps_wpt_q_init(queue *whichQueue) +mps_wpt_q_init(queue* whichQueue) { - QUEUE_INIT(whichQueue); + QUEUE_INIT(whichQueue); } void -mps_wpt_q_deinit(queue *whichQueue) +mps_wpt_q_deinit(queue* whichQueue) { - queue *elem, *tmp; + queue* elem, *tmp; - QUEUE_FOR_EACH(whichQueue, elem, tmp) { - waypoint *q = (waypoint *) dequeue(elem); - waypt_free(q); - } + QUEUE_FOR_EACH(whichQueue, elem, tmp) { + waypoint* q = (waypoint*) dequeue(elem); + waypt_free(q); + } } /* * Find a waypoint that we've already written out * */ -waypoint * -mps_find_wpt_q_by_name(const queue *whichQueue, const char *name) +waypoint* +mps_find_wpt_q_by_name(const queue* whichQueue, const char* name) { - queue *elem, *tmp; - waypoint *waypointp; - - QUEUE_FOR_EACH(whichQueue, elem, tmp) { - waypointp = (waypoint *) elem; - if (0 == strcmp(waypointp->shortname, name)) { - return waypointp; - } - } - return NULL; + queue* elem, *tmp; + waypoint* waypointp; + + QUEUE_FOR_EACH(whichQueue, elem, tmp) { + waypointp = (waypoint*) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + return NULL; } /* @@ -141,151 +151,173 @@ mps_find_wpt_q_by_name(const queue *whichQueue, const char *name) * */ void -mps_wpt_q_add(const queue *whichQueue, const waypoint *wpt) +mps_wpt_q_add(const queue* whichQueue, const waypoint* wpt) { - waypoint *written_wpt = waypt_dupe(wpt); - ENQUEUE_TAIL(whichQueue, &written_wpt->Q); + waypoint* written_wpt = waypt_dupe(wpt); + ENQUEUE_TAIL(whichQueue, &written_wpt->Q); } -static int +static int mps_converted_icon_number(const int icon_num, const int mpsver, garmin_formats_e garmin_format) { - int def_icon = DEFAULTICONVALUE; - - switch (garmin_format) { - case MAPSOURCE: - if (mpsver == 5) return icon_num; - if (mpsver == 4) { - /* Water hydrant */ - if (icon_num == 139) return def_icon; - else return icon_num; - } - else { - /* the Contact icons - V3 doesn't have anything like this */ - if ((icon_num >= 119) && (icon_num <= 138)) return def_icon; - /* the Geocache icons - V3 use the Circle with X */ - if ((icon_num >= 117) && (icon_num <= 118)) return 65; - /* Water hydrant */ - if (icon_num == 139) return def_icon; - return icon_num; - } - - case PCX: - case GARMIN_SERIAL: - if (mpsver == 5) return icon_num; - if (mpsver == 4) { - /* Water hydrant */ - if (icon_num == 8282) return def_icon; - else return icon_num; - } - /* the Contact icons - V3 doesn't have anything like this */ - if ((icon_num >= 8257) && (icon_num <= 8276)) return def_icon; - /* the Geocache icons - V3 use the Circle with X */ - if ((icon_num >= 8255) && (icon_num <= 8256)) return 179; - /* Water hydrant */ - if (icon_num == 8282) return def_icon; - return icon_num; - - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - return def_icon; + int def_icon = DEFAULTICONVALUE; + + switch (garmin_format) { + case MAPSOURCE: + if (mpsver == 5) { + return icon_num; + } + if (mpsver == 4) { + /* Water hydrant */ + if (icon_num == 139) { + return def_icon; + } else { + return icon_num; + } + } else { + /* the Contact icons - V3 doesn't have anything like this */ + if ((icon_num >= 119) && (icon_num <= 138)) { + return def_icon; + } + /* the Geocache icons - V3 use the Circle with X */ + if ((icon_num >= 117) && (icon_num <= 118)) { + return 65; + } + /* Water hydrant */ + if (icon_num == 139) { + return def_icon; + } + return icon_num; + } + + case PCX: + case GARMIN_SERIAL: + if (mpsver == 5) { + return icon_num; + } + if (mpsver == 4) { + /* Water hydrant */ + if (icon_num == 8282) { + return def_icon; + } else { + return icon_num; + } + } + /* the Contact icons - V3 doesn't have anything like this */ + if ((icon_num >= 8257) && (icon_num <= 8276)) { + return def_icon; + } + /* the Geocache icons - V3 use the Circle with X */ + if ((icon_num >= 8255) && (icon_num <= 8256)) { + return 179; + } + /* Water hydrant */ + if (icon_num == 8282) { + return def_icon; + } + return icon_num; + + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + return def_icon; } static void -mps_rd_init(const char *fname) +mps_rd_init(const char* fname) { - mps_file_in = gbfopen_le(fname, "rb", MYNAME); + mps_file_in = gbfopen_le(fname, "rb", MYNAME); - read_route_wpt_mkshort_handle = mkshort_new_handle(); - /* initialise the "private" queue of waypoints read for routes */ - mps_wpt_q_init(&read_route_wpt_head); + read_route_wpt_mkshort_handle = mkshort_new_handle(); + /* initialise the "private" queue of waypoints read for routes */ + mps_wpt_q_init(&read_route_wpt_head); } static void mps_rd_deinit(void) { - gbfclose(mps_file_in); - if ( read_route_wpt_mkshort_handle ) { - mkshort_del_handle( &read_route_wpt_mkshort_handle ); - } - /* flush the "private" queue of waypoints read for routes */ - mps_wpt_q_deinit(&read_route_wpt_head); + gbfclose(mps_file_in); + if (read_route_wpt_mkshort_handle) { + mkshort_del_handle(&read_route_wpt_mkshort_handle); + } + /* flush the "private" queue of waypoints read for routes */ + mps_wpt_q_deinit(&read_route_wpt_head); } static void -mps_wr_init(const char *fname) +mps_wr_init(const char* fname) { - fin_name = xstrdup(fname); - if (mpsmergeouts) { - mpsmergeout = atoi(mpsmergeouts); - } - - if (mpsmergeout) { - mps_file_out = gbfopen_le(fname, "rb", MYNAME); - if (mps_file_out == NULL) { - mpsmergeout = 0; - } - else { - gbfclose(mps_file_out); - srand((unsigned) current_time()); - - for (;;) { - /* create a temporary name based on a random char and the existing name */ - /* then test if it already exists, if so try again with another rand num */ - /* yeah, yeah, so there's probably a library function for this */ - xasprintf(&tempname, "%s.%08x", fname, rand()); - mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); - if (mps_file_temp == NULL) break; - gbfclose(mps_file_temp); - } - rename(fname, tempname); - mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); - } - } - - mps_file_out = gbfopen_le(fname, "wb", MYNAME); - - written_wpt_mkshort_handle = mkshort_new_handle(); - /* initialise the "private" queue of waypoints written */ - mps_wpt_q_init(&written_wpt_head); - mps_wpt_q_init(&written_route_wpt_head); + fin_name = xstrdup(fname); + if (mpsmergeouts) { + mpsmergeout = atoi(mpsmergeouts); + } + + if (mpsmergeout) { + mps_file_out = gbfopen_le(fname, "rb", MYNAME); + if (mps_file_out == NULL) { + mpsmergeout = 0; + } else { + gbfclose(mps_file_out); + srand((unsigned) current_time()); + + for (;;) { + /* create a temporary name based on a random char and the existing name */ + /* then test if it already exists, if so try again with another rand num */ + /* yeah, yeah, so there's probably a library function for this */ + xasprintf(&tempname, "%s.%08x", fname, rand()); + mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); + if (mps_file_temp == NULL) { + break; + } + gbfclose(mps_file_temp); + } + rename(fname, tempname); + mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); + } + } + + mps_file_out = gbfopen_le(fname, "wb", MYNAME); + + written_wpt_mkshort_handle = mkshort_new_handle(); + /* initialise the "private" queue of waypoints written */ + mps_wpt_q_init(&written_wpt_head); + mps_wpt_q_init(&written_route_wpt_head); } static void mps_wr_deinit(void) { - gbfclose(mps_file_out); - - if (mpsmergeout) { - gbfclose(mps_file_temp); - remove(tempname); - xfree(tempname); - } - - if ( written_wpt_mkshort_handle ) { - mkshort_del_handle( &written_wpt_mkshort_handle ); - } - /* flush the "private" queue of waypoints written */ - mps_wpt_q_deinit(&written_wpt_head); - mps_wpt_q_deinit(&written_route_wpt_head); - xfree(fin_name); + gbfclose(mps_file_out); + + if (mpsmergeout) { + gbfclose(mps_file_temp); + remove(tempname); + xfree(tempname); + } + + if (written_wpt_mkshort_handle) { + mkshort_del_handle(&written_wpt_mkshort_handle); + } + /* flush the "private" queue of waypoints written */ + mps_wpt_q_deinit(&written_wpt_head); + mps_wpt_q_deinit(&written_route_wpt_head); + xfree(fin_name); } /* - * get characters until and including terminating NULL from mps_file_in + * get characters until and including terminating NULL from mps_file_in * and write into buf. */ static void -mps_readstr(gbfile *mps_file, char *buf, size_t sz) +mps_readstr(gbfile* mps_file, char* buf, size_t sz) { - int c; - while (sz-- && (c = gbfgetc (mps_file)) != EOF) { - *buf++ = c; - if (c == 0) { - return; - } - } + int c; + while (sz-- && (c = gbfgetc(mps_file)) != EOF) { + *buf++ = c; + if (c == 0) { + return; + } + } } /* @@ -293,95 +325,99 @@ mps_readstr(gbfile *mps_file, char *buf, size_t sz) * MRCB */ static void -mps_fileHeader_r(gbfile *mps_file, int *mps_ver) +mps_fileHeader_r(gbfile* mps_file, int* mps_ver) { - char hdr[100]; - int reclen; - - mps_readstr(mps_file, hdr, sizeof(hdr)); - if ( strcmp( hdr, "MsRcd" )) { - fatal(MYNAME ": This doesn't look like a mapsource file.\n"); - } - /* Read record length of "format details" section */ - reclen = gbfgetint32(mps_file); - /* Read the "format details" in plus the trailing null */ - gbfread( hdr, 3, 1, mps_file); - if (hdr[0] != 'D') { - /* No flag for the "data" section */ - fatal(MYNAME ": This doesn't look like a mapsource file.\n"); - } - if (hdr[1] == 'd') { - *mps_ver = 3; - } - else if ((hdr[1] > 'd') && (hdr[1] <= 'h')) { - *mps_ver = 4; - } - else if ((hdr[1] > 'h') && (hdr[1] <= 'i')) { - *mps_ver = 5; - } - else { - fatal(MYNAME ": Unsuppported version of mapsource file.\n"); - } - /* Skip reliably over the "format details" section */ - gbfseek( mps_file, reclen+1-3, SEEK_CUR); - /* Read record length of "program signature" section */ - reclen = gbfgetint32(mps_file); - /* Skip reliably over the "program signature" section */ - if (reclen >= 0) gbfseek(mps_file, reclen+1, SEEK_CUR); + char hdr[100]; + int reclen; + + mps_readstr(mps_file, hdr, sizeof(hdr)); + if (strcmp(hdr, "MsRcd")) { + fatal(MYNAME ": This doesn't look like a mapsource file.\n"); + } + /* Read record length of "format details" section */ + reclen = gbfgetint32(mps_file); + /* Read the "format details" in plus the trailing null */ + gbfread(hdr, 3, 1, mps_file); + if (hdr[0] != 'D') { + /* No flag for the "data" section */ + fatal(MYNAME ": This doesn't look like a mapsource file.\n"); + } + if (hdr[1] == 'd') { + *mps_ver = 3; + } else if ((hdr[1] > 'd') && (hdr[1] <= 'h')) { + *mps_ver = 4; + } else if ((hdr[1] > 'h') && (hdr[1] <= 'i')) { + *mps_ver = 5; + } else { + fatal(MYNAME ": Unsuppported version of mapsource file.\n"); + } + /* Skip reliably over the "format details" section */ + gbfseek(mps_file, reclen+1-3, SEEK_CUR); + /* Read record length of "program signature" section */ + reclen = gbfgetint32(mps_file); + /* Skip reliably over the "program signature" section */ + if (reclen >= 0) { + gbfseek(mps_file, reclen+1, SEEK_CUR); + } } /* - * write out to file + * write out to file * MRCB */ static void -mps_fileHeader_w(gbfile *mps_file, int mps_ver) +mps_fileHeader_w(gbfile* mps_file, int mps_ver) { - char hdr[100]; - int reclen; - - strcpy (hdr, "MsRc"); - gbfwrite(hdr, 4, 1, mps_file); - - /* Between versions 3 & 5 this value is 'd', but might change in the future */ - strcpy(hdr, "d"); - gbfwrite(hdr, 2, 1, mps_file); /* include trailing NULL char */ - - /* Start of a "Data" section */ - hdr[0] = 'D'; - /* if (mps_ver == 3) */ - hdr[1] = 'd'; /* equates to V3.02 */ - if (mps_ver == 4) hdr[1] = 'g'; /* equates to V4.06 */ - if (mps_ver == 5) hdr[1] = 'i'; /* equates to V5.0 */ - hdr[2] = 0; - - reclen = 2; /* this is 3 byte record */ - gbfputint32(reclen, mps_file); - gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ - - hdr[0] = 'A'; - /* if (mps_ver == 3) */ - hdr[1] = 0x2E; hdr[2] = 0x01; /* equates to V3.02 */ - hdr[3] = 'S'; - hdr[4] = 'Q'; - hdr[5] = 'A'; - hdr[6] = 0; - strcpy(hdr+7,"Oct 20 1999"); - strcpy(hdr+19,"12:50:33"); - if (mps_ver == 4) { - hdr[1] = (char) 0x96; /* equates to V4.06 */ - strcpy(hdr+7,"Oct 22 2001"); - strcpy(hdr+19,"15:45:33"); - } - if (mps_ver == 5) { - hdr[1] = (char) 0xF4; /* equates to V5.0 */ - strcpy(hdr+7,"Jul 3 2003"); - strcpy(hdr+19,"08:35:33"); - } - - reclen = 27; /* pre measured! */ - gbfputint32(reclen, mps_file); - gbfwrite(hdr, 28, 1, mps_file); /* reclen + 1 - can't use this as reclen may be wrongendian now */ + char hdr[100]; + int reclen; + + strcpy(hdr, "MsRc"); + gbfwrite(hdr, 4, 1, mps_file); + + /* Between versions 3 & 5 this value is 'd', but might change in the future */ + strcpy(hdr, "d"); + gbfwrite(hdr, 2, 1, mps_file); /* include trailing NULL char */ + + /* Start of a "Data" section */ + hdr[0] = 'D'; + /* if (mps_ver == 3) */ + hdr[1] = 'd'; /* equates to V3.02 */ + if (mps_ver == 4) { + hdr[1] = 'g'; /* equates to V4.06 */ + } + if (mps_ver == 5) { + hdr[1] = 'i'; /* equates to V5.0 */ + } + hdr[2] = 0; + + reclen = 2; /* this is 3 byte record */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ + + hdr[0] = 'A'; + /* if (mps_ver == 3) */ + hdr[1] = 0x2E; + hdr[2] = 0x01; /* equates to V3.02 */ + hdr[3] = 'S'; + hdr[4] = 'Q'; + hdr[5] = 'A'; + hdr[6] = 0; + strcpy(hdr+7,"Oct 20 1999"); + strcpy(hdr+19,"12:50:33"); + if (mps_ver == 4) { + hdr[1] = (char) 0x96; /* equates to V4.06 */ + strcpy(hdr+7,"Oct 22 2001"); + strcpy(hdr+19,"15:45:33"); + } + if (mps_ver == 5) { + hdr[1] = (char) 0xF4; /* equates to V5.0 */ + strcpy(hdr+7,"Jul 3 2003"); + strcpy(hdr+19,"08:35:33"); + } + + reclen = 27; /* pre measured! */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 28, 1, mps_file); /* reclen + 1 - can't use this as reclen may be wrongendian now */ } /* @@ -389,30 +425,32 @@ mps_fileHeader_w(gbfile *mps_file, int mps_ver) * MRCB */ static void -mps_mapsegment_r(gbfile *mps_file, int mps_ver) +mps_mapsegment_r(gbfile* mps_file, int mps_ver) { - int reclen; + int reclen; #if 0 - /* At the moment we're not doing anything with map segments, but here's the template code as if we were */ - char hdr[100]; - gbfread(&CDid, 4, 1, mps_file); - reclen = le_read32(&CDid); - - gbfread(&CDSegmentid, 4, 1, mps_file); - reclen = le_read32(&CDSegmentid); - - mps_readstr(mps_file, CDName, sizeof(CDName)); - mps_readstr(mps_file, CDSegmentName, sizeof(CDSegmentName)); - mps_readstr(mps_file, CDAreaName, sizeof(CDAreaName)); - - gbfread(hdr, 4, 1, mps_file); /* trailing long value */ -#endif - - gbfseek(mps_file, -5, SEEK_CUR); - reclen = gbfgetint32(mps_file); - if (reclen >= 0) gbfseek( mps_file, reclen+1, SEEK_CUR); - return; + /* At the moment we're not doing anything with map segments, but here's the template code as if we were */ + char hdr[100]; + gbfread(&CDid, 4, 1, mps_file); + reclen = le_read32(&CDid); + + gbfread(&CDSegmentid, 4, 1, mps_file); + reclen = le_read32(&CDSegmentid); + + mps_readstr(mps_file, CDName, sizeof(CDName)); + mps_readstr(mps_file, CDSegmentName, sizeof(CDSegmentName)); + mps_readstr(mps_file, CDAreaName, sizeof(CDAreaName)); + + gbfread(hdr, 4, 1, mps_file); /* trailing long value */ +#endif + + gbfseek(mps_file, -5, SEEK_CUR); + reclen = gbfgetint32(mps_file); + if (reclen >= 0) { + gbfseek(mps_file, reclen+1, SEEK_CUR); + } + return; } @@ -422,22 +460,22 @@ mps_mapsegment_r(gbfile *mps_file, int mps_ver) * MRCB */ static void -mps_mapsetname_r(gbfile *mps_file, int mps_ver) +mps_mapsetname_r(gbfile* mps_file, int mps_ver) { - int reclen; - - /* At the moment we're not doing anything with mapsetnames, but here's the template code as if we were - char hdr[100]; - mps_readstr(mps_file, hdr, sizeof(hdr)); - char mapsetnamename[very large number?]; - strcpy(mapsetnamename,hdr); - char mapsetnameAutonameFlag; - gbfread(&mapsetnameAutonameFlag, 1, 1, mps_file); */ - - gbfseek(mps_file, -5, SEEK_CUR); - reclen = gbfgetint32(mps_file); - gbfseek( mps_file, reclen+1, SEEK_CUR); - return; + int reclen; + + /* At the moment we're not doing anything with mapsetnames, but here's the template code as if we were + char hdr[100]; + mps_readstr(mps_file, hdr, sizeof(hdr)); + char mapsetnamename[very large number?]; + strcpy(mapsetnamename,hdr); + char mapsetnameAutonameFlag; + gbfread(&mapsetnameAutonameFlag, 1, 1, mps_file); */ + + gbfseek(mps_file, -5, SEEK_CUR); + reclen = gbfgetint32(mps_file); + gbfseek(mps_file, reclen+1, SEEK_CUR); + return; } @@ -447,17 +485,17 @@ mps_mapsetname_r(gbfile *mps_file, int mps_ver) * MRCB */ static void -mps_mapsetname_w(gbfile *mps_file, int mps_ver) +mps_mapsetname_w(gbfile* mps_file, int mps_ver) { - char hdr[100]; - int reclen; - - hdr[0] = 'V'; /* mapsetname start of record indicator */ - hdr[1] = 0; /* zero length null terminated string */ - hdr[2] = 1; /* mapsetname autoname flag set to DO autoname */ - reclen = 2; /* three bytes of the V record */ - gbfputint32(reclen, mps_file); - gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ + char hdr[100]; + int reclen; + + hdr[0] = 'V'; /* mapsetname start of record indicator */ + hdr[1] = 0; /* zero length null terminated string */ + hdr[2] = 1; /* mapsetname autoname flag set to DO autoname */ + reclen = 2; /* three bytes of the V record */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ } @@ -466,101 +504,101 @@ mps_mapsetname_w(gbfile *mps_file, int mps_ver) * MRCB */ static void -mps_waypoint_r(gbfile *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpsclass) +mps_waypoint_r(gbfile* mps_file, int mps_ver, waypoint** wpt, unsigned int* mpsclass) { - char tbuf[100]; - char wptname[MPSNAMEBUFFERLEN]; - char *wptdesc = NULL; - char *wptnotes = NULL; - int lat; - int lon; - int icon; - int dynamic; - - waypoint *thisWaypoint = NULL; - double mps_altitude = unknown_alt; - double mps_proximity = unknown_alt; - double mps_depth = unknown_alt; - - thisWaypoint = waypt_new(); - *wpt = thisWaypoint; - - mps_readstr(mps_file, wptname, sizeof(wptname)); - - (*mpsclass) = gbfgetint32(mps_file); /* class */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ - - gbfread(tbuf,17, 1, mps_file); /* subclass data (17) */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfread(tbuf, 5, 1, mps_file); /* additional subclass data (1) & terminator? (4) */ - } - - lat = gbfgetint32(mps_file); - lon = gbfgetint32(mps_file); - - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl(mps_file); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - wptdesc = gbfgetcstr(mps_file); - - if (gbfgetc(mps_file) == 1) { /* proximity validity */ - mps_proximity = gbfgetdbl(mps_file); - } - else { - mps_proximity = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - (void) gbfgetint32(mps_file); /* display flag */ - (void) gbfgetint32(mps_file); /* colour */ - icon = gbfgetint32(mps_file); /* display symbol */ - - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* city */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* state */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /*facility */ - - gbfread(tbuf, 1, 1, mps_file); /* unknown */ - - if (gbfgetc(mps_file) == 1) { /* depth validity */ - mps_depth = gbfgetdbl( mps_file ); - } - else { - mps_depth = unknown_alt; - (void) gbfseek( mps_file, 8, SEEK_CUR ); - } - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfread(tbuf, 6, 1, mps_file); /* unknown */ - wptnotes = gbfgetcstr(mps_file); - } - else { - gbfread(tbuf, 2, 1, mps_file); /* unknown */ - } - - thisWaypoint->shortname = xstrdup(wptname); - thisWaypoint->description = wptdesc; - thisWaypoint->notes = wptnotes; - thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); - thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); - thisWaypoint->altitude = mps_altitude; - if (mps_proximity != unknown_alt) WAYPT_SET(thisWaypoint, proximity, mps_proximity); - if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); - - /* might need to change this to handle version dependent icon handling */ - thisWaypoint->icon_descr = gt_find_desc_from_icon_number(icon, MAPSOURCE, &dynamic); - thisWaypoint->wpt_flags.icon_descr_is_dynamic = dynamic; - - /* The following Now done elsewhere since it can be useful to read in and - perhaps not add to the list */ - /* waypt_add(thisWaypoint); */ - - return; + char tbuf[100]; + char wptname[MPSNAMEBUFFERLEN]; + char* wptdesc = NULL; + char* wptnotes = NULL; + int lat; + int lon; + int icon; + int dynamic; + + waypoint* thisWaypoint = NULL; + double mps_altitude = unknown_alt; + double mps_proximity = unknown_alt; + double mps_depth = unknown_alt; + + thisWaypoint = waypt_new(); + *wpt = thisWaypoint; + + mps_readstr(mps_file, wptname, sizeof(wptname)); + + (*mpsclass) = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + + gbfread(tbuf,17, 1, mps_file); /* subclass data (17) */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 5, 1, mps_file); /* additional subclass data (1) & terminator? (4) */ + } + + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + wptdesc = gbfgetcstr(mps_file); + + if (gbfgetc(mps_file) == 1) { /* proximity validity */ + mps_proximity = gbfgetdbl(mps_file); + } else { + mps_proximity = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + (void) gbfgetint32(mps_file); /* display flag */ + (void) gbfgetint32(mps_file); /* colour */ + icon = gbfgetint32(mps_file); /* display symbol */ + + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* city */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* state */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /*facility */ + + gbfread(tbuf, 1, 1, mps_file); /* unknown */ + + if (gbfgetc(mps_file) == 1) { /* depth validity */ + mps_depth = gbfgetdbl(mps_file); + } else { + mps_depth = unknown_alt; + (void) gbfseek(mps_file, 8, SEEK_CUR); + } + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 6, 1, mps_file); /* unknown */ + wptnotes = gbfgetcstr(mps_file); + } else { + gbfread(tbuf, 2, 1, mps_file); /* unknown */ + } + + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->description = wptdesc; + thisWaypoint->notes = wptnotes; + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + if (mps_proximity != unknown_alt) { + WAYPT_SET(thisWaypoint, proximity, mps_proximity); + } + if (mps_depth != unknown_alt) { + WAYPT_SET(thisWaypoint, depth, mps_depth); + } + + /* might need to change this to handle version dependent icon handling */ + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(icon, MAPSOURCE, &dynamic); + thisWaypoint->wpt_flags.icon_descr_is_dynamic = dynamic; + + /* The following Now done elsewhere since it can be useful to read in and + perhaps not add to the list */ + /* waypt_add(thisWaypoint); */ + + return; } /* @@ -568,136 +606,146 @@ mps_waypoint_r(gbfile *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpsc * MRCB */ static void -mps_waypoint_w(gbfile *mps_file, int mps_ver, const waypoint *wpt, const int isRouteWpt) +mps_waypoint_w(gbfile* mps_file, int mps_ver, const waypoint* wpt, const int isRouteWpt) { - int reclen; - int lat, lon; - int icon; - char *src = ""; /* default to empty string */ - char *ident; - char *ascii_description; - char zbuf[25]; - char ffbuf[25]; - int display = 1; - int colour = 0; /* (unknown colour) black is 1, white is 16 */ - - double mps_altitude = wpt->altitude; - double mps_proximity = (mpsuseprox ? WAYPT_GET(wpt, proximity, unknown_alt) : unknown_alt); - double mps_depth = unknown_alt; - - lat = GPS_Math_Deg_To_Semi(wpt->latitude); - lon = GPS_Math_Deg_To_Semi(wpt->longitude); - if (WAYPT_HAS(wpt, depth) && mpsusedepth) mps_depth = wpt->depth; - - if(wpt->description) src = wpt->description; - if(wpt->notes) src = wpt->notes; - ident = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, src) : - wpt->shortname; - - memset(zbuf, 0, sizeof(zbuf)); - memset(ffbuf, 0xff, sizeof(ffbuf)); - - /* might need to change this to handle version dependent icon handling */ - icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); - - if (get_cache_icon(wpt) /* && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)*/) { - icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); - } - - icon = mps_converted_icon_number(icon, mps_ver, MAPSOURCE); - - /* two NULL (0x0) bytes at end of each string */ - ascii_description = wpt->description ? xstrdup(wpt->description) : xstrdup(""); - reclen = strlen(ident) + strlen(ascii_description) + 2; - if ((mps_ver == 4) || (mps_ver == 5)) { - /* v4.06 & V5.0*/ - reclen += 85; /* "W" (1) + strlen(name) + NULL (1) + class(4) + country(sz) + + int reclen; + int lat, lon; + int icon; + char* src = ""; /* default to empty string */ + char* ident; + char* ascii_description; + char zbuf[25]; + char ffbuf[25]; + int display = 1; + int colour = 0; /* (unknown colour) black is 1, white is 16 */ + + double mps_altitude = wpt->altitude; + double mps_proximity = (mpsuseprox ? WAYPT_GET(wpt, proximity, unknown_alt) : unknown_alt); + double mps_depth = unknown_alt; + + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); + if (WAYPT_HAS(wpt, depth) && mpsusedepth) { + mps_depth = wpt->depth; + } + + if (wpt->description) { + src = wpt->description; + } + if (wpt->notes) { + src = wpt->notes; + } + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + wpt->shortname; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xff, sizeof(ffbuf)); + + /* might need to change this to handle version dependent icon handling */ + icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); + + if (get_cache_icon(wpt) /* && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)*/) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); + } + + icon = mps_converted_icon_number(icon, mps_ver, MAPSOURCE); + + /* two NULL (0x0) bytes at end of each string */ + ascii_description = wpt->description ? xstrdup(wpt->description) : xstrdup(""); + reclen = strlen(ident) + strlen(ascii_description) + 2; + if ((mps_ver == 4) || (mps_ver == 5)) { + /* v4.06 & V5.0*/ + reclen += 85; /* "W" (1) + strlen(name) + NULL (1) + class(4) + country(sz) + subclass(18) + unknown(4) + lat(4) + lon(4) + alt(9) + strlen(desc) - + NULL (1) + prox(9) + display(4) + colour(4) + symbol(4) + city(sz) + + + NULL (1) + prox(9) + display(4) + colour(4) + symbol(4) + city(sz) + state(sz) + facility(sz) + unknown2(1) + depth(9) + unknown3(7) */ - /* -1 as reclen is interpreted from zero meaning a reclength of one */ - if (wpt->notes) reclen += strlen(wpt->notes); - } - else { - /* v3.02 */ - reclen += 75; /* "W" (1) + strlen(name) + NULL (1) + + class(4) + country(sz) + - subclass(17) + lat(4) + lon(4) + alt(9) + strlen(desc) + - NULL (1) + prox(9) + display(4) + - colour(4) + symbol(4) + city(sz) + state(sz) + facility(sz) + + /* -1 as reclen is interpreted from zero meaning a reclength of one */ + if (wpt->notes) { + reclen += strlen(wpt->notes); + } + } else { + /* v3.02 */ + reclen += 75; /* "W" (1) + strlen(name) + NULL (1) + + class(4) + country(sz) + + subclass(17) + lat(4) + lon(4) + alt(9) + strlen(desc) + + NULL (1) + prox(9) + display(4) + + colour(4) + symbol(4) + city(sz) + state(sz) + facility(sz) + unknown2(1) + depth(9) + unknown3(2) */ - /* -1 as reclen is interpreted from zero meaning a reclength of one */ - } - - gbfputint32(reclen, mps_file); - gbfwrite("W", 1, 1, mps_file); - gbfputs(ident, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ - - if (isRouteWpt) zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; - else zbuf[0] = (char)MPSDEFAULTWPTCLASS; - gbfwrite(zbuf, 4, 1, mps_file); /* class */ - - zbuf[0]=0; - gbfwrite(zbuf, 1, 1, mps_file); /* country empty string */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ - gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ - gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ - gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ - } - else { - gbfwrite(zbuf, 8, 1, mps_file); - gbfwrite(ffbuf, 8, 1, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); - } - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - if (mps_altitude == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_altitude, mps_file); - } - if (wpt->description) gbfputs(ascii_description, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination */ - xfree(ascii_description); - ascii_description = NULL; - - if (mps_proximity == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl( mps_proximity, mps_file ); - } - - gbfputint32(display, mps_file); /* Show waypoint w/ name */ - gbfputint32(colour, mps_file); - gbfputint32(icon, mps_file); - - gbfwrite(zbuf, 3, 1, mps_file); /* city, state, facility */ - - gbfwrite(zbuf, 1, 1, mps_file); /* unknown */ - - if (mps_depth == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_depth, mps_file); - } - - gbfwrite(zbuf, 2, 1, mps_file); /* unknown */ - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfwrite(zbuf, 4, 1, mps_file); /* unknown */ - if (wpt->notes) gbfputs(wpt->notes, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); /* string termination */ - } + /* -1 as reclen is interpreted from zero meaning a reclength of one */ + } + + gbfputint32(reclen, mps_file); + gbfwrite("W", 1, 1, mps_file); + gbfputs(ident, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ + + if (isRouteWpt) { + zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; + } else { + zbuf[0] = (char)MPSDEFAULTWPTCLASS; + } + gbfwrite(zbuf, 4, 1, mps_file); /* class */ + + zbuf[0]=0; + gbfwrite(zbuf, 1, 1, mps_file); /* country empty string */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ + gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ + } else { + gbfwrite(zbuf, 8, 1, mps_file); + gbfwrite(ffbuf, 8, 1, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); + } + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + if (wpt->description) { + gbfputs(ascii_description, mps_file); + } + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination */ + xfree(ascii_description); + ascii_description = NULL; + + if (mps_proximity == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_proximity, mps_file); + } + + gbfputint32(display, mps_file); /* Show waypoint w/ name */ + gbfputint32(colour, mps_file); + gbfputint32(icon, mps_file); + + gbfwrite(zbuf, 3, 1, mps_file); /* city, state, facility */ + + gbfwrite(zbuf, 1, 1, mps_file); /* unknown */ + + if (mps_depth == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_depth, mps_file); + } + + gbfwrite(zbuf, 2, 1, mps_file); /* unknown */ + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* unknown */ + if (wpt->notes) { + gbfputs(wpt->notes, mps_file); + } + gbfwrite(zbuf, 1, 1, mps_file); /* string termination */ + } } /* @@ -707,24 +755,25 @@ mps_waypoint_w(gbfile *mps_file, int mps_ver, const waypoint *wpt, const int isR * */ static void -mps_waypoint_w_unique_wrapper(const waypoint *wpt) +mps_waypoint_w_unique_wrapper(const waypoint* wpt) { - waypoint *wptfound = NULL; - - /* Search for this waypoint in the ones already written */ - wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); - /* is the next line necessary? Assumes we know who's called us and in what order */ - if (wptfound == NULL) - wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); - - /* if this waypoint hasn't been written then it is okay to do so */ - if (wptfound == NULL) { - mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); - - /* ensure we record in our "private" queue what has been - written so that we don't write it again */ - mps_wpt_q_add(&written_wpt_head, wpt); - } + waypoint* wptfound = NULL; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + /* is the next line necessary? Assumes we know who's called us and in what order */ + if (wptfound == NULL) { + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + } + + /* if this waypoint hasn't been written then it is okay to do so */ + if (wptfound == NULL) { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + + /* ensure we record in our "private" queue what has been + written so that we don't write it again */ + mps_wpt_q_add(&written_wpt_head, wpt); + } } /* @@ -736,35 +785,36 @@ mps_waypoint_w_unique_wrapper(const waypoint *wpt) * */ static void -mps_route_wpt_w_unique_wrapper(const waypoint *wpt) +mps_route_wpt_w_unique_wrapper(const waypoint* wpt) { - waypoint *wptfound = NULL; - - /* Search for this waypoint in the ones already written */ - wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); - if (wptfound == NULL) - /* so, not a real wpt, so must check route wpts already written as reals */ - wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); - - /* if this waypoint hasn't been written then it is okay to do so - but assume it is only required for the route + waypoint* wptfound = NULL; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + if (wptfound == NULL) + /* so, not a real wpt, so must check route wpts already written as reals */ + { + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + } + + /* if this waypoint hasn't been written then it is okay to do so + but assume it is only required for the route */ - if (wptfound == NULL) { - /* Although we haven't written one out, this might still be a "real" waypoint - If so, we need to write it out now accordingly */ - wptfound = find_waypt_by_name (wpt->shortname); - - if (wptfound == NULL) { - /* well, we tried to find: it wasn't written and isn't a real waypoint */ - mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==1)); - mps_wpt_q_add(&written_route_wpt_head, wpt); - } - else { - mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); - /* Simulated real user waypoint */ - mps_wpt_q_add(&written_wpt_head, wpt); - } - } + if (wptfound == NULL) { + /* Although we haven't written one out, this might still be a "real" waypoint + If so, we need to write it out now accordingly */ + wptfound = find_waypt_by_name(wpt->shortname); + + if (wptfound == NULL) { + /* well, we tried to find: it wasn't written and isn't a real waypoint */ + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==1)); + mps_wpt_q_add(&written_route_wpt_head, wpt); + } else { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + /* Simulated real user waypoint */ + mps_wpt_q_add(&written_wpt_head, wpt); + } + } } #if 0 /* @@ -774,40 +824,40 @@ mps_route_wpt_w_unique_wrapper(const waypoint *wpt) * */ static void -mps_waypoint_w_uniqloc_wrapper(waypoint *wpt) +mps_waypoint_w_uniqloc_wrapper(waypoint* wpt) { - waypoint *wptfound = NULL; - char *newName; - - /* Search for this waypoint in the ones already written */ - wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); - /* is the next line necessary? Assumes we know who's called us and in what order */ - if (wptfound == NULL) - wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); - - if (wptfound != NULL) { - /* check if this is the same waypoint by looking at the lat lon - not ideal, but better then having two same named waypoints - that kills MapSource. If it is the same then don't bother - adding it in. If it isn't, then rename it - */ - if (((wpt->latitude - wptfound->latitude) != 0) || - ((wpt->longitude - wptfound->longitude) != 0)) { - /* Not the same lat lon, so rename and add */ - newName = mkshort(written_wpt_mkshort_handle, wpt->shortname); - wptfound = waypt_dupe(wpt); - xfree(wptfound->shortname); - wptfound->shortname = newName; - mps_waypoint_w(mps_file_out, mps_ver_out, wptfound, (1==0)); - mps_wpt_q_add(&written_wpt_head, wpt); - } - } - else { - mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); - /* ensure we record in out "private" queue what has been - written so that we don't write it again */ - mps_wpt_q_add(&written_wpt_head, wpt); - } + waypoint* wptfound = NULL; + char* newName; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + /* is the next line necessary? Assumes we know who's called us and in what order */ + if (wptfound == NULL) { + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + } + + if (wptfound != NULL) { + /* check if this is the same waypoint by looking at the lat lon + not ideal, but better then having two same named waypoints + that kills MapSource. If it is the same then don't bother + adding it in. If it isn't, then rename it + */ + if (((wpt->latitude - wptfound->latitude) != 0) || + ((wpt->longitude - wptfound->longitude) != 0)) { + /* Not the same lat lon, so rename and add */ + newName = mkshort(written_wpt_mkshort_handle, wpt->shortname); + wptfound = waypt_dupe(wpt); + xfree(wptfound->shortname); + wptfound->shortname = newName; + mps_waypoint_w(mps_file_out, mps_ver_out, wptfound, (1==0)); + mps_wpt_q_add(&written_wpt_head, wpt); + } + } else { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + /* ensure we record in out "private" queue what has been + written so that we don't write it again */ + mps_wpt_q_add(&written_wpt_head, wpt); + } } #endif @@ -816,250 +866,244 @@ mps_waypoint_w_uniqloc_wrapper(waypoint *wpt) * MRCB */ static void -mps_route_r(gbfile *mps_file, int mps_ver, route_head **rte) +mps_route_r(gbfile* mps_file, int mps_ver, route_head** rte) { - char tbuf[100]; - char *rtename; - char wptname[MPSNAMEBUFFERLEN]; - int lat = 0; - int lon = 0; - char rte_autoname; - int interlinkStepCount; - int thisInterlinkStep; - unsigned int mpsclass; - - route_head *rte_head; - int rte_count; - - waypoint *thisWaypoint; - waypoint *tempWpt; - - double mps_altitude = unknown_alt; - double mps_depth = unknown_alt; - - rtename = gbfgetcstr(mps_file); + char tbuf[100]; + char* rtename; + char wptname[MPSNAMEBUFFERLEN]; + int lat = 0; + int lon = 0; + char rte_autoname; + int interlinkStepCount; + int thisInterlinkStep; + unsigned int mpsclass; + + route_head* rte_head; + int rte_count; + + waypoint* thisWaypoint; + waypoint* tempWpt; + + double mps_altitude = unknown_alt; + double mps_depth = unknown_alt; + + rtename = gbfgetcstr(mps_file); #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: reading route %s\n", rtename); + fprintf(stderr, "mps_route_r: reading route %s\n", rtename); #endif - gbfread(&rte_autoname, 1, 1, mps_file); /* autoname flag */ + gbfread(&rte_autoname, 1, 1, mps_file); /* autoname flag */ - gbfread(tbuf, 1, 1, mps_file); /* skip min/max values */ - if (tbuf[0] == 0) { + gbfread(tbuf, 1, 1, mps_file); /* skip min/max values */ + if (tbuf[0] == 0) { - lat = gbfgetint32(mps_file); /* max lat of whole route */ - lon = gbfgetint32(mps_file); /* max lon of whole route */ + lat = gbfgetint32(mps_file); /* max lat of whole route */ + lon = gbfgetint32(mps_file); /* max lon of whole route */ - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl(mps_file); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } - lat = gbfgetint32(mps_file); /* min lat of whole route */ - lon = gbfgetint32(mps_file); /* min lon of whole route */ + lat = gbfgetint32(mps_file); /* min lat of whole route */ + lon = gbfgetint32(mps_file); /* min lon of whole route */ - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl(mps_file); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - } + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + } - rte_count = gbfgetint32(mps_file); /* number of waypoints in route */ + rte_count = gbfgetint32(mps_file); /* number of waypoints in route */ - /* This might be rather presumptuous, but is it valid in any format to have route with no points? */ - /* Let's assume not, so if the route count is zero or less, let's get out of here and allow the */ - /* caller to do any file resync */ - if (rte_count < 0) return; + /* This might be rather presumptuous, but is it valid in any format to have route with no points? */ + /* Let's assume not, so if the route count is zero or less, let's get out of here and allow the */ + /* caller to do any file resync */ + if (rte_count < 0) { + return; + } #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: route contains %d waypoints\n", rte_count); + fprintf(stderr, "mps_route_r: route contains %d waypoints\n", rte_count); #endif - rte_head = route_head_alloc(); - rte_head->rte_name = rtename; - route_add_head(rte_head); - *rte = rte_head; + rte_head = route_head_alloc(); + rte_head->rte_name = rtename; + route_add_head(rte_head); + *rte = rte_head; - rte_count--; /* need to loop round for one less than the number of waypoints */ + rte_count--; /* need to loop round for one less than the number of waypoints */ - while (rte_count--) { + while (rte_count--) { - mps_readstr(mps_file, wptname, sizeof(wptname)); + mps_readstr(mps_file, wptname, sizeof(wptname)); #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: reading route waypoint %s\n", wptname); + fprintf(stderr, "mps_route_r: reading route waypoint %s\n", wptname); #endif - mpsclass = gbfgetint32(mps_file); /* class */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + mpsclass = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfread(tbuf, 22, 1, mps_file); /* subclass data */ + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 22, 1, mps_file); /* subclass data */ - /* This is a bit unpleasant. Routes have a variable length of - data (min 22 bytes) terminated by a zero */ - do { - gbfread(tbuf, 1, 1, mps_file); - } while (tbuf[0]); + /* This is a bit unpleasant. Routes have a variable length of + data (min 22 bytes) terminated by a zero */ + do { + gbfread(tbuf, 1, 1, mps_file); + } while (tbuf[0]); - /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ - gbfread(tbuf, 18, 1, mps_file); - } - else { - gbfread(tbuf, 17, 1, mps_file); /* subclass data */ - gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ - } + /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ + gbfread(tbuf, 18, 1, mps_file); + } else { + gbfread(tbuf, 17, 1, mps_file); /* subclass data */ + gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ + } - /* link details */ - interlinkStepCount = gbfgetint32(mps_file); /* NOT always 2, but will assume > 0 */ + /* link details */ + interlinkStepCount = gbfgetint32(mps_file); /* NOT always 2, but will assume > 0 */ #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: interlink steps are %d\n", interlinkStepCount); + fprintf(stderr, "mps_route_r: interlink steps are %d\n", interlinkStepCount); #endif - /* Basically we're knackered if the step count is less than one since we hard code reading of the */ - /* first, so if there isn't one, we'd lose sync on the file and read junk */ - /* Given we've already done some route head allocation, do we return or do we die? It'd be good */ - /* do some clean up before returning. */ - if (interlinkStepCount < 1) { - /* For RJL - are the following lines correct ? */ - /* route_free(rte_head); - route_del_head(rte_head); */ - return; - } - - /* first end of link */ - lat = gbfgetint32(mps_file); - lon = gbfgetint32(mps_file); - - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl(mps_file); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there - if found. With MapSource, one should consider the real waypoint list as definitive */ - tempWpt = find_waypt_by_name(wptname); - - if (tempWpt != NULL) { - thisWaypoint = waypt_dupe(tempWpt); - } - else { - tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); - - if (tempWpt != NULL) { - thisWaypoint = waypt_dupe(tempWpt); - } - else { - /* should never reach here, but we do need a fallback position */ + /* Basically we're knackered if the step count is less than one since we hard code reading of the */ + /* first, so if there isn't one, we'd lose sync on the file and read junk */ + /* Given we've already done some route head allocation, do we return or do we die? It'd be good */ + /* do some clean up before returning. */ + if (interlinkStepCount < 1) { + /* For RJL - are the following lines correct ? */ + /* route_free(rte_head); + route_del_head(rte_head); */ + return; + } + + /* first end of link */ + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there + if found. With MapSource, one should consider the real waypoint list as definitive */ + tempWpt = find_waypt_by_name(wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } else { + tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } else { + /* should never reach here, but we do need a fallback position */ #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: reached the point we never should\n"); + fprintf(stderr, "mps_route_r: reached the point we never should\n"); #endif - thisWaypoint = waypt_new(); - thisWaypoint->shortname = xstrdup(wptname); - thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); - thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); - thisWaypoint->altitude = mps_altitude; - if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); - } - } - - route_add_wpt(rte_head, thisWaypoint); - - /* take two off the count since we separately read the start and end parts of the link */ - /* MRCB 2004/09/15 - NOPE, sorry, this needs to one, since interlink steps can be > 0 */ - for (thisInterlinkStep = interlinkStepCount - 1; thisInterlinkStep > 0; thisInterlinkStep--) { - /* Could do this by doing a calculation on length of each co-ordinate and just doing one read - but doing it this way makes it easier in the future to make use of this data */ - lat = gbfgetint32(mps_file); - lon = gbfgetint32(mps_file); - - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl( mps_file ); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - } - - gbfread(tbuf, 1, 1, mps_file); /* NULL */ - - gbfread(tbuf, 4, 1, mps_file); /* link max lat */ - gbfread(tbuf, 4, 1, mps_file); /* link max lon */ - gbfread(tbuf, 9, 1, mps_file); /* link max alt validity + alt */ - - gbfread(tbuf, 4, 1, mps_file); /* link min lat */ - gbfread(tbuf, 4, 1, mps_file); /* link min lon */ - gbfread(tbuf, 9, 1, mps_file); /* link min alt validity + alt */ - - } /* while (trk_count--) */ - - /* when the loop is done, there's still one waypoint to read with a small trailer */ - /* all we want is the waypoint name; lat, lon and alt are already set from above */ - mps_readstr(mps_file, wptname, sizeof(wptname)); + thisWaypoint = waypt_new(); + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + if (mps_depth != unknown_alt) { + WAYPT_SET(thisWaypoint, depth, mps_depth); + } + } + } + + route_add_wpt(rte_head, thisWaypoint); + + /* take two off the count since we separately read the start and end parts of the link */ + /* MRCB 2004/09/15 - NOPE, sorry, this needs to one, since interlink steps can be > 0 */ + for (thisInterlinkStep = interlinkStepCount - 1; thisInterlinkStep > 0; thisInterlinkStep--) { + /* Could do this by doing a calculation on length of each co-ordinate and just doing one read + but doing it this way makes it easier in the future to make use of this data */ + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + } + + gbfread(tbuf, 1, 1, mps_file); /* NULL */ + + gbfread(tbuf, 4, 1, mps_file); /* link max lat */ + gbfread(tbuf, 4, 1, mps_file); /* link max lon */ + gbfread(tbuf, 9, 1, mps_file); /* link max alt validity + alt */ + + gbfread(tbuf, 4, 1, mps_file); /* link min lat */ + gbfread(tbuf, 4, 1, mps_file); /* link min lon */ + gbfread(tbuf, 9, 1, mps_file); /* link min alt validity + alt */ + + } /* while (trk_count--) */ + + /* when the loop is done, there's still one waypoint to read with a small trailer */ + /* all we want is the waypoint name; lat, lon and alt are already set from above */ + mps_readstr(mps_file, wptname, sizeof(wptname)); #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: reading final route waypoint %s\n", wptname); + fprintf(stderr, "mps_route_r: reading final route waypoint %s\n", wptname); #endif - mpsclass = gbfgetint32(mps_file); /* class */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfread(tbuf, 22, 1, mps_file); /* subclass data */ - - /* This is a bit unpleasant. Routes have a variable length of - data (min 22 bytes) terminated by a zero */ - do { - gbfread(tbuf, 1, 1, mps_file); - } while (tbuf[0]); - - /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ - gbfread(tbuf, 18, 1, mps_file); - } - else { - gbfread(tbuf, 17, 1, mps_file); /* subclass data */ - gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ - } - - gbfread(tbuf, 5, 1, mps_file); /* 5 byte trailer */ - /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there - if found because there is more info held in a real waypoint than in its route counterpart, - e.g. the display symbol (aka icon) - */ - tempWpt = find_waypt_by_name(wptname); - - if (tempWpt != NULL) { - thisWaypoint = waypt_dupe(tempWpt); - } - else { - tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); - - if (tempWpt != NULL) { - thisWaypoint = waypt_dupe(tempWpt); - } - else { - /* should never reach here, but we do need a fallback position */ - thisWaypoint = waypt_new(); - thisWaypoint->shortname = xstrdup(wptname); - thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); - thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); - thisWaypoint->altitude = mps_altitude; - } - } - - route_add_wpt(rte_head, thisWaypoint); - - return; + mpsclass = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 22, 1, mps_file); /* subclass data */ + + /* This is a bit unpleasant. Routes have a variable length of + data (min 22 bytes) terminated by a zero */ + do { + gbfread(tbuf, 1, 1, mps_file); + } while (tbuf[0]); + + /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ + gbfread(tbuf, 18, 1, mps_file); + } else { + gbfread(tbuf, 17, 1, mps_file); /* subclass data */ + gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ + } + + gbfread(tbuf, 5, 1, mps_file); /* 5 byte trailer */ + /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there + if found because there is more info held in a real waypoint than in its route counterpart, + e.g. the display symbol (aka icon) + */ + tempWpt = find_waypt_by_name(wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } else { + tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } else { + /* should never reach here, but we do need a fallback position */ + thisWaypoint = waypt_new(); + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + } + } + + route_add_wpt(rte_head, thisWaypoint); + + return; } /* @@ -1067,151 +1111,164 @@ mps_route_r(gbfile *mps_file, int mps_ver, route_head **rte) * MRCB */ static void -mps_routehdr_w(gbfile *mps_file, int mps_ver, const route_head *rte) +mps_routehdr_w(gbfile* mps_file, int mps_ver, const route_head* rte) { - unsigned int reclen; - unsigned int rte_datapoints; - int rname_len; - char *rname; - char hdr[20]; - char zbuf[20]; - char *src = ""; - char *ident; - - waypoint *testwpt; - time_t uniqueValue = 0; - int allWptNameLengths; - - double maxlat=-90.0; - double maxlon=-180.0; - double minlat=90.0; - double minlon=180.0; - double maxalt=unknown_alt; - double minalt=unknown_alt; - - int lat; - int lon; - - queue *elem, *tmp; - - prevRouteWpt = NULL; /* clear the stateful flag used to know when the start of route wpts happens */ - - memset(zbuf, 0, sizeof(zbuf)); - - /* total nodes (waypoints) this route */ - rte_datapoints = 0; - allWptNameLengths = 0; - - if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - testwpt = (waypoint *)elem; - if (rte_datapoints == 0) { - uniqueValue = testwpt->creation_time; - } - if (testwpt->latitude > maxlat) maxlat = testwpt->latitude; - if (testwpt->latitude < minlat) minlat = testwpt->latitude; - if (testwpt->longitude > maxlon) maxlon = testwpt->longitude; - if (testwpt->longitude < minlon) minlon = testwpt->longitude; - if (testwpt->altitude != unknown_alt) { - if ((testwpt->altitude > maxalt) || - (maxalt == unknown_alt)) maxalt = testwpt->altitude; - if ((testwpt->altitude < minalt) || - (minalt == unknown_alt)) minalt = testwpt->altitude; - } - - if(testwpt->description) src = testwpt->description; - if(testwpt->notes) src = testwpt->notes; - ident = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, src) : - testwpt->shortname; - allWptNameLengths += strlen(ident) + 1; - - rte_datapoints++; - } - - if (uniqueValue == 0) { - uniqueValue = current_time(); - } - - /* route name */ - if (!rte->rte_name) { - sprintf(hdr, "Route%04x", (unsigned) uniqueValue); - rname = xstrdup(hdr); - } - else - rname = xstrdup(rte->rte_name); - - rname_len = strlen(rname); - reclen = rname_len + 42; /* "T" (1) + strlen(tname) + NULL (1) + autoname flag (2) + + unsigned int reclen; + unsigned int rte_datapoints; + int rname_len; + char* rname; + char hdr[20]; + char zbuf[20]; + char* src = ""; + char* ident; + + waypoint* testwpt; + time_t uniqueValue = 0; + int allWptNameLengths; + + double maxlat=-90.0; + double maxlon=-180.0; + double minlat=90.0; + double minlon=180.0; + double maxalt=unknown_alt; + double minalt=-unknown_alt; + + int lat; + int lon; + + queue* elem, *tmp; + + prevRouteWpt = NULL; /* clear the stateful flag used to know when the start of route wpts happens */ + + memset(zbuf, 0, sizeof(zbuf)); + + /* total nodes (waypoints) this route */ + rte_datapoints = 0; + allWptNameLengths = 0; + + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + testwpt = (waypoint*)elem; + if (rte_datapoints == 0) { + uniqueValue = testwpt->creation_time; + } + if (testwpt->latitude > maxlat) { + maxlat = testwpt->latitude; + } + if (testwpt->latitude < minlat) { + minlat = testwpt->latitude; + } + if (testwpt->longitude > maxlon) { + maxlon = testwpt->longitude; + } + if (testwpt->longitude < minlon) { + minlon = testwpt->longitude; + } + if (testwpt->altitude != unknown_alt) { + if ((testwpt->altitude > maxalt) || + (maxalt == unknown_alt)) { + maxalt = testwpt->altitude; + } + if ((testwpt->altitude < minalt) || + (minalt == -unknown_alt)) { + minalt = testwpt->altitude; + } + } + + if (testwpt->description) { + src = testwpt->description; + } + if (testwpt->notes) { + src = testwpt->notes; + } + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + testwpt->shortname; + allWptNameLengths += strlen(ident) + 1; + + rte_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* route name */ + if (!rte->rte_name) { + sprintf(hdr, "Route%04x", (unsigned) uniqueValue); + rname = xstrdup(hdr); + } else { + rname = xstrdup(rte->rte_name); + } + + rname_len = strlen(rname); + reclen = rname_len + 42; /* "T" (1) + strlen(tname) + NULL (1) + autoname flag (2) + route lat lon max (2x4) + route max alt (9) + route lat lon min (2x4) + route min alt (9) + num route datapoints value (4) */ - - /* V3 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + - subclass (17) + unknown (18) */ - /* V4,5 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + - subclass (18) + unknown (4) + unknown (19) */ - /* V* - each route link: 0x00000002 (4) + end 1 lat (4) + end 1 lon (4) + end 1 alt (9) + - end 2 lat (4) + end 2 lon (4) + end 2 alt (9) + NULL (1) + - link max lat (4) + link max lon (4) + link max alt (9) + - link min lat (4) + link min lon (4) + link min alt (9) */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - reclen += allWptNameLengths + rte_datapoints * 46 + - (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ - } - else { - reclen += allWptNameLengths + rte_datapoints * 40 + - (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ - } - - gbfputint32(reclen, mps_file); - gbfputc('R', mps_file); - gbfwrite(rname, 1, rname_len, mps_file); - - xfree(rname); - - hdr[0] = 0; /* NULL of string termination */ - hdr[1] = 0; /* don't autoname */ - hdr[2] = 0; /* MSB of don't autoname */ - gbfwrite(hdr, 3, 1, mps_file); /* NULL string terminator + route autoname flag */ - - lat = GPS_Math_Deg_To_Semi(maxlat); - lon = GPS_Math_Deg_To_Semi(maxlon); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - if (maxalt == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(maxalt, mps_file); - } - - lat = GPS_Math_Deg_To_Semi(minlat); - lon = GPS_Math_Deg_To_Semi(minlon); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - if (minalt == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(minalt, mps_file); - } - - gbfputint32(rte_datapoints, mps_file); - } + + /* V3 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + + subclass (17) + unknown (18) */ + /* V4,5 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + + subclass (18) + unknown (4) + unknown (19) */ + /* V* - each route link: 0x00000002 (4) + end 1 lat (4) + end 1 lon (4) + end 1 alt (9) + + end 2 lat (4) + end 2 lon (4) + end 2 alt (9) + NULL (1) + + link max lat (4) + link max lon (4) + link max alt (9) + + link min lat (4) + link min lon (4) + link min alt (9) */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + reclen += allWptNameLengths + rte_datapoints * 46 + + (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ + } else { + reclen += allWptNameLengths + rte_datapoints * 40 + + (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ + } + + gbfputint32(reclen, mps_file); + gbfputc('R', mps_file); + gbfwrite(rname, 1, rname_len, mps_file); + + xfree(rname); + + hdr[0] = 0; /* NULL of string termination */ + hdr[1] = 0; /* don't autoname */ + hdr[2] = 0; /* MSB of don't autoname */ + gbfwrite(hdr, 3, 1, mps_file); /* NULL string terminator + route autoname flag */ + + lat = GPS_Math_Deg_To_Semi(maxlat); + lon = GPS_Math_Deg_To_Semi(maxlon); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (maxalt == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(maxalt, mps_file); + } + + lat = GPS_Math_Deg_To_Semi(minlat); + lon = GPS_Math_Deg_To_Semi(minlon); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (minalt == -unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(minalt, mps_file); + } + + gbfputint32(rte_datapoints, mps_file); + } } static void -mps_routehdr_w_wrapper(const route_head *rte) +mps_routehdr_w_wrapper(const route_head* rte) { - mps_routehdr_w(mps_file_out, mps_ver_out, rte); + mps_routehdr_w(mps_file_out, mps_ver_out, rte); } @@ -1220,166 +1277,174 @@ mps_routehdr_w_wrapper(const route_head *rte) * MRCB */ static void -mps_routedatapoint_w(gbfile *mps_file, int mps_ver, const waypoint *rtewpt) +mps_routedatapoint_w(gbfile* mps_file, int mps_ver, const waypoint* rtewpt) { - int lat; - int lon; - char zbuf[20]; - char ffbuf[20]; - char *src = ""; - char *ident; - int reclen; - - int maxlat; - int maxlon; - int minlat; - int minlon; - double maxalt=unknown_alt; - double minalt=unknown_alt; - - double mps_altitude; - waypoint *wptfound; - - memset(zbuf, 0, sizeof(zbuf)); - memset(ffbuf, 0xff, sizeof(ffbuf)); - - if (prevRouteWpt != NULL) { - /* output the route link details */ - reclen = 2; - gbfputint32(reclen, mps_file); - - /* output end point 1 */ - lat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); - lon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - mps_altitude = prevRouteWpt->altitude; - if (mps_altitude == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_altitude, mps_file ); - } - - /* output end point 2 */ - lat = GPS_Math_Deg_To_Semi(rtewpt->latitude); - lon = GPS_Math_Deg_To_Semi(rtewpt->longitude); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - mps_altitude = rtewpt->altitude; - if (mps_altitude == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_altitude, mps_file); - } - - if (rtewpt->latitude > prevRouteWpt->latitude) { - maxlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); - minlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); - } - else { - minlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); - maxlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); - } - - if (rtewpt->longitude > prevRouteWpt->longitude) { - maxlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); - minlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); - } - else { - minlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); - maxlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); - } - - if (rtewpt->altitude != unknown_alt) maxalt = rtewpt->altitude; - if (rtewpt->altitude != unknown_alt) minalt = rtewpt->altitude; - if (prevRouteWpt->altitude != unknown_alt) { - if ((prevRouteWpt->altitude > maxalt) || - (maxalt == unknown_alt)) maxalt = prevRouteWpt->altitude; - if ((prevRouteWpt->altitude < minalt) || - (minalt == unknown_alt)) minalt = prevRouteWpt->altitude; - } - - gbfwrite (zbuf, 1, 1, mps_file); - - /* output max coords of the link */ - gbfputint32(maxlat, mps_file); - gbfputint32(maxlon, mps_file); - - if (maxalt == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(maxalt, mps_file); - } - - /* output min coords of the link */ - gbfputint32(minlat, mps_file); - gbfputint32(minlon, mps_file); - - if (minalt == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(minalt, mps_file ); - } - - } - - if(rtewpt->description) src = rtewpt->description; - if(rtewpt->notes) src = rtewpt->notes; - ident = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, src) : - rtewpt->shortname; - - gbfputs(ident, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ - - wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, ident); - if (wptfound != NULL) zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; - else zbuf[0] = (char)MPSDEFAULTWPTCLASS; - gbfwrite(zbuf, 4, 1, mps_file); /* class */ - - zbuf[0]=0; - gbfwrite(zbuf, 1, 1, mps_file); /* country - i.e. empty string */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ - gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ - gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ - gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ - - gbfwrite(zbuf, 1, 1, mps_file); - gbfputc(3, mps_file); - gbfwrite(zbuf, 17, 1, mps_file); - } - else { - gbfwrite(zbuf, 8, 1, mps_file); /* subclass part 1 */ - gbfwrite(ffbuf, 8, 1, mps_file); /* subclass part 2 */ - gbfwrite(zbuf, 1, 1, mps_file); /* subclass part 3 */ - - /* unknown */ - gbfwrite(zbuf, 1, 1, mps_file); - gbfputc(3, mps_file); - gbfwrite(zbuf, 16, 1, mps_file); - } - - prevRouteWpt = rtewpt; + int lat; + int lon; + char zbuf[20]; + char ffbuf[20]; + char* src = ""; + char* ident; + int reclen; + + int maxlat; + int maxlon; + int minlat; + int minlon; + double maxalt=unknown_alt; + double minalt=-unknown_alt; + + double mps_altitude; + waypoint* wptfound; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xff, sizeof(ffbuf)); + + if (prevRouteWpt != NULL) { + /* output the route link details */ + reclen = 2; + gbfputint32(reclen, mps_file); + + /* output end point 1 */ + lat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + lon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + mps_altitude = prevRouteWpt->altitude; + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + + /* output end point 2 */ + lat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + lon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + mps_altitude = rtewpt->altitude; + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + + if (rtewpt->latitude > prevRouteWpt->latitude) { + maxlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + minlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + } else { + minlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + maxlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + } + + if (rtewpt->longitude > prevRouteWpt->longitude) { + maxlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + minlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + } else { + minlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + maxlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + } + + if (rtewpt->altitude != unknown_alt) { + maxalt = rtewpt->altitude; + } + if (rtewpt->altitude != unknown_alt) { + minalt = rtewpt->altitude; + } + if (prevRouteWpt->altitude != unknown_alt) { + if ((prevRouteWpt->altitude > maxalt) || + (maxalt == unknown_alt)) { + maxalt = prevRouteWpt->altitude; + } + if ((prevRouteWpt->altitude < minalt) || + (minalt == -unknown_alt)) { + minalt = prevRouteWpt->altitude; + } + } + + gbfwrite(zbuf, 1, 1, mps_file); + + /* output max coords of the link */ + gbfputint32(maxlat, mps_file); + gbfputint32(maxlon, mps_file); + + if (maxalt == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(maxalt, mps_file); + } + + /* output min coords of the link */ + gbfputint32(minlat, mps_file); + gbfputint32(minlon, mps_file); + + if (minalt == -unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(minalt, mps_file); + } + + } + + if (rtewpt->description) { + src = rtewpt->description; + } + if (rtewpt->notes) { + src = rtewpt->notes; + } + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + rtewpt->shortname; + + gbfputs(ident, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ + + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, ident); + if (wptfound != NULL) { + zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; + } else { + zbuf[0] = (char)MPSDEFAULTWPTCLASS; + } + gbfwrite(zbuf, 4, 1, mps_file); /* class */ + + zbuf[0]=0; + gbfwrite(zbuf, 1, 1, mps_file); /* country - i.e. empty string */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ + gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ + + gbfwrite(zbuf, 1, 1, mps_file); + gbfputc(3, mps_file); + gbfwrite(zbuf, 17, 1, mps_file); + } else { + gbfwrite(zbuf, 8, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 8, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 1, 1, mps_file); /* subclass part 3 */ + + /* unknown */ + gbfwrite(zbuf, 1, 1, mps_file); + gbfputc(3, mps_file); + gbfwrite(zbuf, 16, 1, mps_file); + } + + prevRouteWpt = rtewpt; } static void -mps_routedatapoint_w_wrapper(const waypoint *rte) +mps_routedatapoint_w_wrapper(const waypoint* rte) { - mps_routedatapoint_w(mps_file_out, mps_ver_out, rte); + mps_routedatapoint_w(mps_file_out, mps_ver_out, rte); } @@ -1388,23 +1453,23 @@ mps_routedatapoint_w_wrapper(const waypoint *rte) * MRCB */ static void -mps_routetrlr_w(gbfile *mps_file, int mps_ver, const route_head *rte) +mps_routetrlr_w(gbfile* mps_file, int mps_ver, const route_head* rte) { - char hdr[2]; - int value = 0; + char hdr[2]; + int value = 0; - hdr[0] = 1; + hdr[0] = 1; - if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ - gbfwrite(&value, 4, 1, mps_file); - gbfwrite(hdr, 1, 1, mps_file); - } + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + gbfwrite(&value, 4, 1, mps_file); + gbfwrite(hdr, 1, 1, mps_file); + } } - + static void -mps_routetrlr_w_wrapper(const route_head *rte) +mps_routetrlr_w_wrapper(const route_head* rte) { - mps_routetrlr_w(mps_file_out, mps_ver_out, rte); + mps_routetrlr_w(mps_file_out, mps_ver_out, rte); } @@ -1413,84 +1478,85 @@ mps_routetrlr_w_wrapper(const route_head *rte) * MRCB */ static void -mps_track_r(gbfile *mps_file, int mps_ver, route_head **trk) +mps_track_r(gbfile* mps_file, int mps_ver, route_head** trk) { - char *trkname; - int lat; - int lon; + char* trkname; + int lat; + int lon; - int dateTime = 0; - route_head *track_head; - int trk_count; + int dateTime = 0; + route_head* track_head; + int trk_count; - waypoint *thisWaypoint; - double mps_altitude = unknown_alt; - double mps_depth = unknown_alt; + waypoint* thisWaypoint; + double mps_altitude = unknown_alt; + double mps_depth = unknown_alt; - trkname = gbfgetcstr(mps_file); + trkname = gbfgetcstr(mps_file); #ifdef MPS_DEBUG - fprintf(stderr, "mps_track_r: reading track %s\n", trkname); + fprintf(stderr, "mps_track_r: reading track %s\n", trkname); #endif - (void) gbfgetc(mps_file); /* display flag */ - (void) gbfgetint32(mps_file); /* colour */ + (void) gbfgetc(mps_file); /* display flag */ + (void) gbfgetint32(mps_file); /* colour */ - trk_count = gbfgetint32(mps_file); /* number of datapoints in tracklog */ + trk_count = gbfgetint32(mps_file); /* number of datapoints in tracklog */ - /* I don't know, but perhaps it's valid to have a track with no waypoints */ - /* Seems dumb, but truth is stranger than fiction. Of course, it could be */ - /* that there are more than MAXINT / 2 waypoints, yeah sure */ - /* Allow the caller the perform the file resync caused by bombing out early */ - if (trk_count < 0) return; + /* I don't know, but perhaps it's valid to have a track with no waypoints */ + /* Seems dumb, but truth is stranger than fiction. Of course, it could be */ + /* that there are more than MAXINT / 2 waypoints, yeah sure */ + /* Allow the caller the perform the file resync caused by bombing out early */ + if (trk_count < 0) { + return; + } #ifdef MPS_DEBUG - fprintf(stderr, "mps_track_r: there are %d track waypoints %d\n", trk_count); + fprintf(stderr, "mps_track_r: there are %d track waypoints %d\n", trk_count); #endif - track_head = route_head_alloc(); - track_head->rte_name = trkname; - track_add_head(track_head); - *trk = track_head; - - while (trk_count--) { - - lat = gbfgetint32(mps_file); - lon = gbfgetint32(mps_file); - - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl( mps_file ); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - if (gbfgetc(mps_file) == 1) { /* date/time validity */ - dateTime = gbfgetint32(mps_file); - } - else { - (void) gbfgetint32(mps_file); - } - - if (gbfgetc(mps_file) == 1) { /* depth validity */ - mps_depth = gbfgetdbl(mps_file ); - } - else { - mps_depth = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - thisWaypoint = waypt_new(); - thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); - thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); - thisWaypoint->creation_time = dateTime; - thisWaypoint->microseconds = 0; - thisWaypoint->altitude = mps_altitude; - if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); - track_add_wpt(track_head, thisWaypoint); - - } /* while (trk_count--) */ - - return; + track_head = route_head_alloc(); + track_head->rte_name = trkname; + track_add_head(track_head); + *trk = track_head; + + while (trk_count--) { + + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + if (gbfgetc(mps_file) == 1) { /* date/time validity */ + dateTime = gbfgetint32(mps_file); + } else { + (void) gbfgetint32(mps_file); + } + + if (gbfgetc(mps_file) == 1) { /* depth validity */ + mps_depth = gbfgetdbl(mps_file); + } else { + mps_depth = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + thisWaypoint = waypt_new(); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->creation_time = dateTime; + thisWaypoint->microseconds = 0; + thisWaypoint->altitude = mps_altitude; + if (mps_depth != unknown_alt) { + WAYPT_SET(thisWaypoint, depth, mps_depth); + } + track_add_wpt(track_head, thisWaypoint); + + } /* while (trk_count--) */ + + return; } @@ -1499,69 +1565,69 @@ mps_track_r(gbfile *mps_file, int mps_ver, route_head **trk) * MRCB */ static void -mps_trackhdr_w(gbfile *mps_file, int mps_ver, const route_head *trk) +mps_trackhdr_w(gbfile* mps_file, int mps_ver, const route_head* trk) { - unsigned int reclen; - unsigned int trk_datapoints; - unsigned int colour = 0; /* unknown colour */ - int tname_len; - char *tname; - char hdr[20]; - waypoint *testwpt; - time_t uniqueValue = 0; - - queue *elem, *tmp; - - /* total nodes (waypoints) this track */ - trk_datapoints = 0; - if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ - QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { - if (trk_datapoints == 0) { - testwpt = (waypoint *)elem; - uniqueValue = testwpt->creation_time; - } - trk_datapoints++; - } - - if (uniqueValue == 0) { - uniqueValue = current_time(); - } - - /* track name */ - if (!trk->rte_name) { - sprintf(hdr, "Track%04x", (unsigned) uniqueValue); - tname = xstrdup(hdr); - } - else - tname = xstrdup(trk->rte_name); - - tname_len = strlen(tname); - reclen = tname_len + 11; /* "T" (1) + strlen(tname) + NULL (1) + display flag (1) + colour (4) + + unsigned int reclen; + unsigned int trk_datapoints; + unsigned int colour = 0; /* unknown colour */ + int tname_len; + char* tname; + char hdr[20]; + waypoint* testwpt; + time_t uniqueValue = 0; + + queue* elem, *tmp; + + /* total nodes (waypoints) this track */ + trk_datapoints = 0; + if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + if (trk_datapoints == 0) { + testwpt = (waypoint*)elem; + uniqueValue = testwpt->creation_time; + } + trk_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* track name */ + if (!trk->rte_name) { + sprintf(hdr, "Track%04x", (unsigned) uniqueValue); + tname = xstrdup(hdr); + } else { + tname = xstrdup(trk->rte_name); + } + + tname_len = strlen(tname); + reclen = tname_len + 11; /* "T" (1) + strlen(tname) + NULL (1) + display flag (1) + colour (4) + num track datapoints value (4) */ - - reclen += (trk_datapoints * 31) - 1; /* lat (4) + lon (4) + alt (9) + date (5) + depth (9) ;*/ - /* -1 is because reclen starts from 0 which means a length of 1 */ - gbfputint32(reclen, mps_file); - gbfputc('T', mps_file); - gbfwrite(tname, 1, tname_len, mps_file); - xfree(tname); + reclen += (trk_datapoints * 31) - 1; /* lat (4) + lon (4) + alt (9) + date (5) + depth (9) ;*/ + /* -1 is because reclen starts from 0 which means a length of 1 */ + gbfputint32(reclen, mps_file); + gbfputc('T', mps_file); + gbfwrite(tname, 1, tname_len, mps_file); + + xfree(tname); - hdr[0] = 0; - hdr[1] = 1; - gbfwrite(hdr, 2, 1, mps_file); /* NULL string terminator + display flag */ + hdr[0] = 0; + hdr[1] = 1; + gbfwrite(hdr, 2, 1, mps_file); /* NULL string terminator + display flag */ - gbfputint32(colour, mps_file); + gbfputint32(colour, mps_file); - gbfputint32(trk_datapoints, mps_file); - } + gbfputint32(trk_datapoints, mps_file); + } } static void -mps_trackhdr_w_wrapper(const route_head *trk) +mps_trackhdr_w_wrapper(const route_head* trk) { - mps_trackhdr_w(mps_file_out, mps_ver_out, trk); + mps_trackhdr_w(mps_file_out, mps_ver_out, trk); } @@ -1570,451 +1636,465 @@ mps_trackhdr_w_wrapper(const route_head *trk) * MRCB */ static void -mps_trackdatapoint_w(gbfile *mps_file, int mps_ver, const waypoint *wpt) +mps_trackdatapoint_w(gbfile* mps_file, int mps_ver, const waypoint* wpt) { - int lat, lon; - time_t t = wpt->creation_time; - char zbuf[10]; - - double mps_altitude = wpt->altitude; - double mps_depth = unknown_alt; - - lat = GPS_Math_Deg_To_Semi(wpt->latitude); - lon = GPS_Math_Deg_To_Semi(wpt->longitude); - if (WAYPT_HAS(wpt, depth) && mpsusedepth) mps_depth = wpt->depth; - - memset(zbuf, 0, sizeof(zbuf)); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - if (mps_altitude == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_altitude, mps_file); - } - - if (t > 0) { /* a valid time is assumed to > 0 */ - gbfputc(1, mps_file); - gbfputint32(t, mps_file); - } - else { - gbfwrite(zbuf, 5, 1, mps_file); - } - - if (mps_depth == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_depth, mps_file ); - } + int lat, lon; + time_t t = wpt->creation_time; + char zbuf[10]; + + double mps_altitude = wpt->altitude; + double mps_depth = unknown_alt; + + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); + if (WAYPT_HAS(wpt, depth) && mpsusedepth) { + mps_depth = wpt->depth; + } + + memset(zbuf, 0, sizeof(zbuf)); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + + if (t > 0) { /* a valid time is assumed to > 0 */ + gbfputc(1, mps_file); + gbfputint32(t, mps_file); + } else { + gbfwrite(zbuf, 5, 1, mps_file); + } + + if (mps_depth == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_depth, mps_file); + } } static void -mps_trackdatapoint_w_wrapper(const waypoint *wpt) +mps_trackdatapoint_w_wrapper(const waypoint* wpt) { - mps_trackdatapoint_w(mps_file_out, mps_ver_out, wpt); + mps_trackdatapoint_w(mps_file_out, mps_ver_out, wpt); } static void mps_read(void) { - waypoint *wpt; - route_head *rte; - route_head *trk; + waypoint* wpt; + route_head* rte; + route_head* trk; - char recType; - int reclen; - int morework; - unsigned int mpsWptClass; - long mpsFileInPos; + char recType; + int reclen; + int morework; + unsigned int mpsWptClass; + long mpsFileInPos; - mps_ver_in = 0; /* although initialised at declaration, what happens if there are two mapsource + mps_ver_in = 0; /* although initialised at declaration, what happens if there are two mapsource input files? */ - mps_fileHeader_r(mps_file_in, &mps_ver_in); + mps_fileHeader_r(mps_file_in, &mps_ver_in); #ifdef DUMP_ICON_TABLE - printf("static icon_mapping_t garmin_icon_table[] = {\n"); + printf("static icon_mapping_t garmin_icon_table[] = {\n"); #endif - morework = 1; - while (morework && !gbfeof(mps_file_in)) { + morework = 1; + while (morework && !gbfeof(mps_file_in)) { - /* Read record length of next section */ - reclen = gbfgetint32(mps_file_in); + /* Read record length of next section */ + reclen = gbfgetint32(mps_file_in); - if (reclen < 0) fatal (MYNAME ": a record length read from the input file is invalid. \nEither the file is corrupt or unsupported.\n"); + if (reclen < 0) { + fatal(MYNAME ": a record length read from the input file is invalid. \nEither the file is corrupt or unsupported.\n"); + } - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_in); - mpsFileInPos = gbftell(mps_file_in); - switch (recType) { - case 'W': - /* Waypoint record */ - /* With routes, we need the waypoint info that reveals, for example, the symbol type */ - mps_waypoint_r(mps_file_in, mps_ver_in, &wpt, &mpsWptClass); + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_in); + mpsFileInPos = gbftell(mps_file_in); + switch (recType) { + case 'W': + /* Waypoint record */ + /* With routes, we need the waypoint info that reveals, for example, the symbol type */ + mps_waypoint_r(mps_file_in, mps_ver_in, &wpt, &mpsWptClass); #ifdef MPS_DEBUG - fprintf(stderr,"Read a waypoint - %s\n", wpt->shortname); + fprintf(stderr,"Read a waypoint - %s\n", wpt->shortname); #endif - if (gbftell(mps_file_in) != mpsFileInPos + reclen) { - /* should junk this record and not save it since we're out of sync with the file */ - /* Should and how do we warn the user? */ + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ #ifdef MPS_DEBUG - fprintf(stderr,"Lost sync with the file reading waypoint - %s\n", wpt->shortname); + fprintf(stderr,"Lost sync with the file reading waypoint - %s\n", wpt->shortname); #endif - gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); - waypt_free( wpt ); - } - else { - /* only add to the "real" list if a "user" waypoint otherwise add to the private list */ - if (mpsWptClass == MPSDEFAULTWPTCLASS) waypt_add(wpt); - else { - mps_wpt_q_add(&read_route_wpt_head, wpt); - waypt_free( wpt ); - } + gbfseek(mps_file_in, mpsFileInPos + reclen, SEEK_SET); + waypt_free(wpt); + } else { + /* only add to the "real" list if a "user" waypoint otherwise add to the private list */ + if (mpsWptClass == MPSDEFAULTWPTCLASS) { + waypt_add(wpt); + } else { + mps_wpt_q_add(&read_route_wpt_head, wpt); + waypt_free(wpt); + } #ifdef DUMP_ICON_TABLE - printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); + printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); #endif - } - break; - - case 'R': - /* Route record */ - mps_route_r(mps_file_in, mps_ver_in, &rte); - if (gbftell(mps_file_in) != mpsFileInPos + reclen) { - /* should junk this record and not save it since we're out of sync with the file */ - /* Should and how do we warn the user? */ + } + break; + + case 'R': + /* Route record */ + mps_route_r(mps_file_in, mps_ver_in, &rte); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ #ifdef MPS_DEBUG - fprintf(stderr,"Lost sync with the file reading route - %s\n", rte->rte_name); + fprintf(stderr,"Lost sync with the file reading route - %s\n", rte->rte_name); #endif - gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); - } - break; - - case 'T': - /* Track record */ - mps_track_r(mps_file_in, mps_ver_in, &trk); - if (gbftell(mps_file_in) != mpsFileInPos + reclen) { - /* should junk this record and not save it since we're out of sync with the file */ - /* Should and how do we warn the user? */ + gbfseek(mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'T': + /* Track record */ + mps_track_r(mps_file_in, mps_ver_in, &trk); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ #ifdef MPS_DEBUG - fprintf(stderr,"Lost sync with the file reading track - %s\n", trk->rte_name); + fprintf(stderr,"Lost sync with the file reading track - %s\n", trk->rte_name); #endif - gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); - } - break; - - case 'L': - /* Map segment record */ - mps_mapsegment_r(mps_file_in, mps_ver_in); - if (gbftell(mps_file_in) != mpsFileInPos + reclen) { - /* should junk this record and not save it since we're out of sync with the file */ - /* Should and how do we warn the user? */ - gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); - } - break; - - case 'V': - /* Mapset record */ - mps_mapsetname_r(mps_file_in, mps_ver_in); - /* Last record in the file */ - morework = 0; - break; - default: - /* Unknown record type. Skip over it. */ - gbfseek(mps_file_in, reclen, SEEK_CUR); - } - - } /* while (!gbfeof(mps_file_in)) */ + gbfseek(mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'L': + /* Map segment record */ + mps_mapsegment_r(mps_file_in, mps_ver_in); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ + gbfseek(mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'V': + /* Mapset record */ + mps_mapsetname_r(mps_file_in, mps_ver_in); + /* Last record in the file */ + morework = 0; + break; + default: + /* Unknown record type. Skip over it. */ + gbfseek(mps_file_in, reclen, SEEK_CUR); + } + + } /* while (!gbfeof(mps_file_in)) */ #ifdef DUMP_ICON_TABLE - printf("\t{ -1, NULL },\n"); - printf("};\n"); + printf("\t{ -1, NULL },\n"); + printf("};\n"); #endif - return ; + return ; } void mps_write(void) { - int short_length; - waypoint *wpt; - route_head *rte; - route_head *trk; - - char recType; - int reclen; - /* TODO: This kills a compiler warning but I'm not sure it's right */ - int reclen2 = 0; - unsigned int tocopy; - unsigned int block; - - long tempFilePos; - unsigned int mpsWptClass; - - unsigned char copybuf[8192]; - - short_length = atoi(snlen); - - if (mpsmergeout) { - /* need to skip over the merging header and test merge version */ - mps_fileHeader_r(mps_file_temp, &mps_ver_temp); - - if (mpsverout) { - if (mps_ver_temp != atoi(mpsverout)) { - /* Need to clean up after a junk version specified */ - /* close the real output file + renamed original output file */ - /* then delete the "real" file and rename the temporarily renamed file back */ - gbfclose(mps_file_temp); - gbfclose(mps_file_out); - remove(fin_name); - rename(tempname, fin_name); - fatal (MYNAME ": merge source version is %d, requested out version is %d\n", mps_ver_temp, atoi(mpsverout)); - } - } - else { - mpsverout = xmalloc(10); - sprintf(mpsverout,"%d", mps_ver_temp); - } - } - - if (mpsverout) - mps_ver_out = atoi(mpsverout); - else - mps_ver_out = 5; - - mkshort_handle = mkshort_new_handle(); - - setshort_length(mkshort_handle, short_length); - - if (snwhiteopt) - setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); - else - setshort_whitespace_ok(mkshort_handle, 0); - - mps_fileHeader_w(mps_file_out, mps_ver_out); - - /* .mps file order is wpts, rtes, trks then mapsets. If we've not been asked to write - wpts, but we are merging, then read in the waypoints from the original file and - write them out, prior to doing rtes. - */ - /* if ((mpsmergeout) && (global_opts.objective != wptdata)) { */ - if ((mpsmergeout) && (! doing_wpts)) { - while (!gbfeof(mps_file_temp)) { - - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - - if (recType == 'W') { - gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ - gbfwrite(&recType, 1, 1, mps_file_out); - - tempFilePos = gbftell(mps_file_temp); - /* need to read in the waypoint info only because later we may need to check for uniqueness - since we're here because the user didn't request waypoints, this should be acceptable */ - mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); - mps_wpt_q_add(&written_wpt_head, wpt); - waypt_free( wpt ); - /* now return to the start of the waypoint data to do a "clean" copy */ - gbfseek(mps_file_temp, tempFilePos, SEEK_SET); - - /* copy the data using a "reasonably" sized buffer */ - for(tocopy = reclen2; tocopy > 0; tocopy -= block) { - block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); - gbfread(copybuf, block, 1, mps_file_temp); - gbfwrite(copybuf, block, 1, mps_file_out); - } - } - else break; - } /* while (!gbfeof(mps_file_temp)) */ - } /* if (mpsmergeout) */ - - /* irrespective of merging, now write out any waypoints */ - /* if (global_opts.objective == wptdata) { */ - if (doing_wpts) { - - if (mpsmergeout) { - /* since we're processing waypoints, we should read in from whatever version and write out */ - /* in the selected version */ - while (!gbfeof(mps_file_temp)) { - - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - - if (recType == 'W') { - /* need to be careful that we aren't duplicating a wpt defined from elsewhere */ - mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); - if (mpsWptClass == MPSDEFAULTWPTCLASS) waypt_add(wpt);else waypt_free(wpt); - } - else break; - } - } - waypt_disp_all(mps_waypoint_w_unique_wrapper); - } - - /* prior to writing any tracks as requested, if we're doing a merge, read in the rtes - from the original file and then write them out, ready for tracks to follow - */ - - /* if ((mpsmergeout) && (global_opts.objective != rtedata)) { */ - if ((mpsmergeout) && (! doing_rtes)) { - while (!gbfeof(mps_file_temp)) { - - /* this might all fail if the relevant waypoints haven't been written */ - if (recType == 'R') { - gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ - gbfwrite(&recType, 1, 1, mps_file_out); - - /* copy the data using a "reasonably" sized buffer */ - for(tocopy = reclen2; tocopy > 0; tocopy -= block) { - block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); - gbfread(copybuf, block, 1, mps_file_temp); - gbfwrite(copybuf, block, 1, mps_file_out); - } - } - else break; - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - - } /* while (!gbfeof(mps_file_temp)) */ - } /* if (mpsmergeout) */ - - /* routes are next in the wpts, rtes, trks, mapset sequence */ - /* if (global_opts.objective == rtedata) { */ - if (doing_rtes) { - - if (mpsmergeout) { - /* since we're processing routes, we should read in from whatever version and write out */ - /* in the selected version */ - while (!gbfeof(mps_file_temp)) { - - if (recType == 'R') { - mps_route_r(mps_file_temp, mps_ver_temp, &rte); - } - else break; - - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - } - } - /* need to make sure there is a "real" waypoint for each route waypoint - Need to be careful about creating duplicate wpts as MapSource chokes on these - so, if the user requested waypoints to be output too, then write the route - waypoints only if unique in the total list of waypoints ("real" and route derived) - If the user didn't request waypoints to be output, then output the route derived - waypoints without consideration for uniqueness for "real" waypoints that haven't - been output (phew!) - */ - route_disp_all(mps_noop, mps_noop, mps_route_wpt_w_unique_wrapper); - - route_disp_all(mps_routehdr_w_wrapper, mps_routetrlr_w_wrapper, mps_routedatapoint_w_wrapper); - } - - /* If merging but we haven't been requested to write out tracks, then read in tracks from - the original file and write these out prior to any mapset writes later on - */ - /* if ((mpsmergeout) && (global_opts.objective != trkdata)) { */ - if ((mpsmergeout) && (! doing_trks)) { - while (!gbfeof(mps_file_temp)) { - - if (recType == 'T') { - gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ - gbfwrite(&recType, 1, 1, mps_file_out); - - /* copy the data using a "reasonably" sized buffer */ - for(tocopy = reclen2; tocopy > 0; tocopy -= block) { - block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); - gbfread(copybuf, block, 1, mps_file_temp); - gbfwrite(copybuf, block, 1, mps_file_out); - } - } - else break; - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - - } /* while (!gbfeof(mps_file_temp)) */ - } /* if (mpsmergeout) */ - - /* tracks are next in the wpts, rte, trks, mapset sequence in .mps files */ - /* if (global_opts.objective == trkdata) { */ - if (doing_trks) { - if (mpsmergeout) { - /* since we're processing tracks, we should read in from whatever version and write out - in the selected version */ - while (!gbfeof(mps_file_temp)) { - - if (recType == 'T') { - mps_track_r(mps_file_temp, mps_ver_temp, &trk); - } - else break; - - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - } - } - track_disp_all(mps_trackhdr_w_wrapper, mps_noop, mps_trackdatapoint_w_wrapper); - } - - if (mpsmergeout) { - /* should now be reading a either a map segment or a mapset - since we would write out an empty one, - let's use the one from the merge file which may well have decent data in */ - for (;;) { - gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ - gbfwrite(&recType, 1, 1, mps_file_out); - - /* copy the data using a "reasonably" sized buffer */ - for(tocopy = reclen2; tocopy > 0; tocopy -= block) { - block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); - gbfread(copybuf, block, 1, mps_file_temp); - gbfwrite(copybuf, block, 1, mps_file_out); - } - - if (recType != 'V') { - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - } - else break; - } - - } - else mps_mapsetname_w(mps_file_out, mps_ver_out); - - mkshort_del_handle(&mkshort_handle); + int short_length; + waypoint* wpt; + route_head* rte; + route_head* trk; + + char recType; + int reclen; + /* TODO: This kills a compiler warning but I'm not sure it's right */ + int reclen2 = 0; + unsigned int tocopy; + unsigned int block; + + long tempFilePos; + unsigned int mpsWptClass; + + unsigned char copybuf[8192]; + + short_length = atoi(snlen); + + if (mpsmergeout) { + /* need to skip over the merging header and test merge version */ + mps_fileHeader_r(mps_file_temp, &mps_ver_temp); + + if (mpsverout) { + if (mps_ver_temp != atoi(mpsverout)) { + /* Need to clean up after a junk version specified */ + /* close the real output file + renamed original output file */ + /* then delete the "real" file and rename the temporarily renamed file back */ + gbfclose(mps_file_temp); + gbfclose(mps_file_out); + remove(fin_name); + rename(tempname, fin_name); + fatal(MYNAME ": merge source version is %d, requested out version is %d\n", mps_ver_temp, atoi(mpsverout)); + } + } else { + mpsverout = (char*) xmalloc(10); + sprintf(mpsverout,"%d", mps_ver_temp); + } + } + + if (mpsverout) { + mps_ver_out = atoi(mpsverout); + } else { + mps_ver_out = 5; + } + + mkshort_handle = mkshort_new_handle(); + + setshort_length(mkshort_handle, short_length); + + if (snwhiteopt) { + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + } else { + setshort_whitespace_ok(mkshort_handle, 0); + } + + mps_fileHeader_w(mps_file_out, mps_ver_out); + + /* .mps file order is wpts, rtes, trks then mapsets. If we've not been asked to write + wpts, but we are merging, then read in the waypoints from the original file and + write them out, prior to doing rtes. + */ + /* if ((mpsmergeout) && (global_opts.objective != wptdata)) { */ + if ((mpsmergeout) && (! doing_wpts)) { + while (!gbfeof(mps_file_temp)) { + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + if (recType == 'W') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + tempFilePos = gbftell(mps_file_temp); + /* need to read in the waypoint info only because later we may need to check for uniqueness + since we're here because the user didn't request waypoints, this should be acceptable */ + mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); + mps_wpt_q_add(&written_wpt_head, wpt); + waypt_free(wpt); + /* now return to the start of the waypoint data to do a "clean" copy */ + gbfseek(mps_file_temp, tempFilePos, SEEK_SET); + + /* copy the data using a "reasonably" sized buffer */ + for (tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } else { + break; + } + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* irrespective of merging, now write out any waypoints */ + /* if (global_opts.objective == wptdata) { */ + if (doing_wpts) { + + if (mpsmergeout) { + /* since we're processing waypoints, we should read in from whatever version and write out */ + /* in the selected version */ + while (!gbfeof(mps_file_temp)) { + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + if (recType == 'W') { + /* need to be careful that we aren't duplicating a wpt defined from elsewhere */ + mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); + if (mpsWptClass == MPSDEFAULTWPTCLASS) { + waypt_add(wpt); + } else { + waypt_free(wpt); + } + } else { + break; + } + } + } + waypt_disp_all(mps_waypoint_w_unique_wrapper); + } + + /* prior to writing any tracks as requested, if we're doing a merge, read in the rtes + from the original file and then write them out, ready for tracks to follow + */ + + /* if ((mpsmergeout) && (global_opts.objective != rtedata)) { */ + if ((mpsmergeout) && (! doing_rtes)) { + while (!gbfeof(mps_file_temp)) { + + /* this might all fail if the relevant waypoints haven't been written */ + if (recType == 'R') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for (tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } else { + break; + } + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* routes are next in the wpts, rtes, trks, mapset sequence */ + /* if (global_opts.objective == rtedata) { */ + if (doing_rtes) { + + if (mpsmergeout) { + /* since we're processing routes, we should read in from whatever version and write out */ + /* in the selected version */ + while (!gbfeof(mps_file_temp)) { + + if (recType == 'R') { + mps_route_r(mps_file_temp, mps_ver_temp, &rte); + } else { + break; + } + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } + } + /* need to make sure there is a "real" waypoint for each route waypoint + Need to be careful about creating duplicate wpts as MapSource chokes on these + so, if the user requested waypoints to be output too, then write the route + waypoints only if unique in the total list of waypoints ("real" and route derived) + If the user didn't request waypoints to be output, then output the route derived + waypoints without consideration for uniqueness for "real" waypoints that haven't + been output (phew!) + */ + route_disp_all(mps_noop, mps_noop, mps_route_wpt_w_unique_wrapper); + + route_disp_all(mps_routehdr_w_wrapper, mps_routetrlr_w_wrapper, mps_routedatapoint_w_wrapper); + } + + /* If merging but we haven't been requested to write out tracks, then read in tracks from + the original file and write these out prior to any mapset writes later on + */ + /* if ((mpsmergeout) && (global_opts.objective != trkdata)) { */ + if ((mpsmergeout) && (! doing_trks)) { + while (!gbfeof(mps_file_temp)) { + + if (recType == 'T') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for (tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } else { + break; + } + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* tracks are next in the wpts, rte, trks, mapset sequence in .mps files */ + /* if (global_opts.objective == trkdata) { */ + if (doing_trks) { + if (mpsmergeout) { + /* since we're processing tracks, we should read in from whatever version and write out + in the selected version */ + while (!gbfeof(mps_file_temp)) { + + if (recType == 'T') { + mps_track_r(mps_file_temp, mps_ver_temp, &trk); + } else { + break; + } + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } + } + track_disp_all(mps_trackhdr_w_wrapper, mps_noop, mps_trackdatapoint_w_wrapper); + } + + if (mpsmergeout) { + /* should now be reading a either a map segment or a mapset - since we would write out an empty one, + let's use the one from the merge file which may well have decent data in */ + for (;;) { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for (tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + + if (recType != 'V') { + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } else { + break; + } + } + + } else { + mps_mapsetname_w(mps_file_out, mps_ver_out); + } + + mkshort_del_handle(&mkshort_handle); } ff_vecs_t mps_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - mps_rd_init, - mps_wr_init, - mps_rd_deinit, - mps_wr_deinit, - mps_read, - mps_write, - NULL, - mps_args, - CET_CHARSET_MS_ANSI /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + mps_rd_init, + mps_wr_init, + mps_rd_deinit, + mps_wr_deinit, + mps_read, + mps_write, + NULL, + mps_args, + CET_CHARSET_MS_ANSI /* CET-REVIEW */ }; diff --git a/gpsbabel/mingw/include/ddk/hidsdi.h b/gpsbabel/mingw/include/ddk/hidsdi.h old mode 100755 new mode 100644 diff --git a/gpsbabel/mkicondoc.c b/gpsbabel/mkicondoc.c index ac4d30b8f..75557ee29 100644 --- a/gpsbabel/mkicondoc.c +++ b/gpsbabel/mkicondoc.c @@ -10,58 +10,58 @@ tbl_ent(int n, ...) { - int i; - char *t; - va_list args; - va_start(args, n); + int i; + char* t; + va_list args; + va_start(args, n); #if 0 - for (i = 0; i < n; i++) { - t = va_arg(args, char *); -printf("%s%s", i > 0 ? "," : "", t); - - } + for (i = 0; i < n; i++) { + t = va_arg(args, char*); + printf("%s%s", i > 0 ? "," : "", t); + + } #else - t = va_arg(args, char*); - printf("%s", t); + t = va_arg(args, char*); + printf("%s", t); #endif -printf("\n"); - va_end(args); - - + printf("\n"); + va_end(args); + + } #include "garmin_tables.c" -sort_garmin(const void *a, const void *b) +sort_garmin(const void* a, const void* b) { - const icon_mapping_t *ap = a; - const icon_mapping_t *bp = b; - return (case_ignore_strcmp((ap)->icon, (bp)->icon)); + const icon_mapping_t* ap = a; + const icon_mapping_t* bp = b; + return (case_ignore_strcmp((ap)->icon, (bp)->icon)); } garmin() { - icon_mapping_t *i; - int n = 0; - char pbuf[100]; - char mbuf[100]; + icon_mapping_t* i; + int n = 0; + char pbuf[100]; + char mbuf[100]; - for (i = garmin_icon_table; i->icon; i++) { - n++; - } + for (i = garmin_icon_table; i->icon; i++) { + n++; + } - qsort(garmin_icon_table, - n, - sizeof(garmin_icon_table[0]), - sort_garmin); + qsort(garmin_icon_table, + n, + sizeof(garmin_icon_table[0]), + sort_garmin); - for (i = garmin_icon_table; i->icon; i++) { - snprintf(pbuf, sizeof(pbuf), "%d", i->pcxsymnum); - snprintf(mbuf, sizeof(mbuf), "%d", i->mpssymnum); - tbl_ent(3, i->icon, pbuf, mbuf); - } + for (i = garmin_icon_table; i->icon; i++) { + snprintf(pbuf, sizeof(pbuf), "%d", i->pcxsymnum); + snprintf(mbuf, sizeof(mbuf), "%d", i->mpssymnum); + tbl_ent(3, i->icon, pbuf, mbuf); + } } main() { - garmin(); + garmin(); } diff --git a/gpsbabel/mkshort.c b/gpsbabel/mkshort.c index 33b1cb9d5..20ed57548 100644 --- a/gpsbabel/mkshort.c +++ b/gpsbabel/mkshort.c @@ -32,211 +32,199 @@ static const char vowels[] = "aeiouAEIOU"; #define DEFAULT_TARGET_LEN 8 -static const char *DEFAULT_BADCHARS = "\"$.,'!-"; +static const char* DEFAULT_BADCHARS = "\"$.,'!-"; /* - * Hash table tunings. The reality is that our hash doesn't have to be + * Hash table tunings. The reality is that our hash doesn't have to be * terribly complex; our strings are short (typically 8-20 bytes) and the * string hash mixes things up enough that strcmp can generally bail on the - * first byte or two for a mismatch. + * first byte or two for a mismatch. */ #define PRIME 37 typedef struct { - unsigned int target_len; - char *badchars; - char *goodchars; - char *defname; - queue namelist[PRIME]; - - /* Various internal flags at end to allow alignment flexibility. */ - unsigned int mustupper:1; - unsigned int whitespaceok:1; - unsigned int repeating_whitespaceok:1; - unsigned int must_uniq:1; - unsigned int is_utf8:1; -} mkshort_handle; - -typedef struct { - queue list; - char *orig_shortname; - int conflictctr; + queue list; + char* orig_shortname; + int conflictctr; } uniq_shortname; static struct replacements { - const char *orig; - const char *replacement; + const char* orig; + const char* replacement; } replacements[] = { - {"zero", "0"}, - {"one", "1"}, - {"two", "2"}, - {"three", "3"}, - {"four", "4"}, - {"five", "5"}, - {"six", "6"}, - {"seven", "7"}, - {"eight", "8"}, - {"nine", "9"}, - {NULL, NULL} + {"zero", "0"}, + {"one", "1"}, + {"two", "2"}, + {"three", "3"}, + {"four", "4"}, + {"five", "5"}, + {"six", "6"}, + {"seven", "7"}, + {"eight", "8"}, + {"nine", "9"}, + {NULL, NULL} }; -/* +/* * We hash all strings as upper case. */ -unsigned int hash_string(const char *key) +unsigned int hash_string(const char* key) { - unsigned int hash = 0; - while (*key) { - hash = ((hash<<5) ^ (hash>>27)) ^ toupper(*key++); - } - hash = hash % PRIME; - return hash; + unsigned int hash = 0; + while (*key) { + hash = ((hash<<5) ^ (hash>>27)) ^ toupper(*key++); + } + hash = hash % PRIME; + return hash; } -void * +short_handle #ifdef DEBUG_MEM MKSHORT_NEW_HANDLE(DEBUG_PARAMS) #else mkshort_new_handle() #endif { - int i; - mkshort_handle *h = (mkshort_handle *) xxcalloc(sizeof *h, 1, file, line); + int i; + mkshort_handle_imp* h = (mkshort_handle_imp*) xxcalloc(sizeof *h, 1, file, line); - for (i = 0; i < PRIME; i++) - QUEUE_INIT(&h->namelist[i]); + for (i = 0; i < PRIME; i++) { + QUEUE_INIT(&h->namelist[i]); + } - h->whitespaceok = 1; - h->badchars = xstrdup(DEFAULT_BADCHARS); - h->target_len = DEFAULT_TARGET_LEN; - h->must_uniq = 1; - h->defname = xstrdup("WPT"); - h->is_utf8 = (global_opts.charset == &cet_cs_vec_utf8); + h->whitespaceok = 1; + h->badchars = xstrdup(DEFAULT_BADCHARS); + h->target_len = DEFAULT_TARGET_LEN; + h->must_uniq = 1; + h->defname = xstrdup("WPT"); + h->is_utf8 = (global_opts.charset == &cet_cs_vec_utf8); - return h; + return h; } -static -uniq_shortname * -is_unique(mkshort_handle *h, char *name) +static +uniq_shortname* +is_unique(mkshort_handle_imp* h, char* name) { - queue *e, *t; - int hash; - - hash = hash_string(name); - QUEUE_FOR_EACH(&h->namelist[hash], e, t) { - uniq_shortname *z = (uniq_shortname *) e; - if (0 == case_ignore_strcmp(z->orig_shortname, name)) { - return z; - } - } - return (uniq_shortname *) NULL; + queue* e, *t; + int hash; + + hash = hash_string(name); + QUEUE_FOR_EACH(&h->namelist[hash], e, t) { + uniq_shortname* z = (uniq_shortname*) e; + if (0 == case_ignore_strcmp(z->orig_shortname, name)) { + return z; + } + } + return (uniq_shortname*) NULL; } static void -add_to_hashlist(mkshort_handle *h, char *name) +add_to_hashlist(mkshort_handle_imp* h, char* name) { - int hash = hash_string(name); - uniq_shortname *s = (uniq_shortname*) xcalloc(1, sizeof (uniq_shortname)); + int hash = hash_string(name); + uniq_shortname* s = (uniq_shortname*) xcalloc(1, sizeof(uniq_shortname)); - s->orig_shortname = xstrdup(name); - ENQUEUE_TAIL(&h->namelist[hash], &s->list); + s->orig_shortname = xstrdup(name); + ENQUEUE_TAIL(&h->namelist[hash], &s->list); } -char * -mkshort_add_to_list(mkshort_handle *h, char *name) +char* +mkshort_add_to_list(mkshort_handle_imp* h, char* name) { - uniq_shortname *s; + uniq_shortname* s; - while ((s = is_unique(h, name))) { - int dl; - char tbuf[10]; - size_t l = strlen(name); + while ((s = is_unique(h, name))) { + int dl; + char tbuf[10]; + size_t l = strlen(name); - s->conflictctr++; + s->conflictctr++; - dl = sprintf(tbuf, ".%d", s->conflictctr); + dl = sprintf(tbuf, ".%d", s->conflictctr); - if (l + dl < h->target_len) { - name = (char *) xrealloc(name, l + dl + 1); - strcat(name, tbuf); - } - else { - strcpy(&name[l-dl], tbuf); - } - } + if (l + dl < h->target_len) { + name = (char*) xrealloc(name, l + dl + 1); + strcat(name, tbuf); + } else { + strcpy(&name[l-dl], tbuf); + } + } - add_to_hashlist(h, name); - return name; + add_to_hashlist(h, name); + return name; } void -mkshort_del_handle(short_handle *h) +mkshort_del_handle(short_handle* h) { - mkshort_handle *hdr = (mkshort_handle*) *h; - int i; + mkshort_handle_imp* hdr = (mkshort_handle_imp*) *h; + int i; - if (!h || !hdr) - return; + if (!h || !hdr) { + return; + } - for (i = 0; i < PRIME; i++) { - queue *e, *t; - QUEUE_FOR_EACH(&hdr->namelist[i], e, t) { - uniq_shortname *s = (uniq_shortname *) e; + for (i = 0; i < PRIME; i++) { + queue* e, *t; + QUEUE_FOR_EACH(&hdr->namelist[i], e, t) { + uniq_shortname* s = (uniq_shortname*) e; #if 0 - if (global_opts.verbose_status >= 2 && s->conflictctr) { - fprintf(stderr, "%d Output name conflicts: '%s'\n", - s->conflictctr, s->orig_shortname); - } + if (global_opts.verbose_status >= 2 && s->conflictctr) { + fprintf(stderr, "%d Output name conflicts: '%s'\n", + s->conflictctr, s->orig_shortname); + } #endif - dequeue(e); - xfree(s->orig_shortname); - xfree(s); - } - } - /* setshort_badchars(*h, NULL); ! currently setshort_badchars() always allocates something ! */ - if (hdr->badchars != NULL) { - xfree(hdr->badchars); - } - setshort_goodchars(*h, NULL); - if (hdr->defname) { - xfree(hdr->defname); - } - - xfree(hdr); - *h = NULL; + dequeue(e); + xfree(s->orig_shortname); + xfree(s); + } + } + /* setshort_badchars(*h, NULL); ! currently setshort_badchars() always allocates something ! */ + if (hdr->badchars != NULL) { + xfree(hdr->badchars); + } + setshort_goodchars(*h, NULL); + if (hdr->defname) { + xfree(hdr->defname); + } + + xfree(hdr); + *h = NULL; } /* * This is the stuff that makes me ashamed to be a C programmer... */ -static -char * -delete_last_vowel(int start, char *istring, int *replaced) +static +char* +delete_last_vowel(int start, char* istring, int* replaced) { - int l; - - /* - * Basically impelement strrchr. - */ - *replaced = 0; - for (l = strlen(istring); l > start; l--) { - if (strchr(vowels, istring[l-1])) { - char *ostring; - /* If vowel is the first letter of a word, keep it.*/ - if (istring[l-2] == ' ') continue; - ostring = xstrdup(istring); - strncpy(&ostring[l-1], &istring[l], 1+strlen(istring)-l); - ostring[strlen(istring)-1] = 0; - *replaced = 1; - strcpy( istring, ostring ); - xfree(ostring); - break; - } - } - return istring; + int l; + + /* + * Basically impelement strrchr. + */ + *replaced = 0; + for (l = strlen(istring); l > start; l--) { + if (strchr(vowels, istring[l-1])) { + char* ostring; + /* If vowel is the first letter of a word, keep it.*/ + if (istring[l-2] == ' ') { + continue; + } + ostring = xstrdup(istring); + strncpy(&ostring[l-1], &istring[l], 1+strlen(istring)-l); + ostring[strlen(istring)-1] = 0; + *replaced = 1; + strcpy(istring, ostring); + xfree(ostring); + break; + } + } + return istring; } /* @@ -244,24 +232,24 @@ delete_last_vowel(int start, char *istring, int *replaced) * are made only at the end of the string. */ void -replace_constants(char *s) +replace_constants(char* s) { - struct replacements *r; - int origslen = strlen(s); - - for (r = replacements; r->orig; r++) { - int rl = strlen(r->orig); - /* - * If word is in replacement list and preceeded by a - * space, replace it. - */ - if ((origslen - rl > 1) && - (0 == case_ignore_strcmp(r->orig, &s[origslen - rl])) && - (s[origslen - rl - 1] == ' ')) { - strcpy(&s[origslen - rl], r->replacement); - return ; -} - } + struct replacements* r; + int origslen = strlen(s); + + for (r = replacements; r->orig; r++) { + int rl = strlen(r->orig); + /* + * If word is in replacement list and preceeded by a + * space, replace it. + */ + if ((origslen - rl > 1) && + (0 == case_ignore_strcmp(r->orig, &s[origslen - rl])) && + (s[origslen - rl - 1] == ' ')) { + strcpy(&s[origslen - rl], r->replacement); + return ; + } + } } @@ -272,35 +260,35 @@ replace_constants(char *s) void setshort_length(short_handle h, int l) { - mkshort_handle *hdl = (mkshort_handle *) h; - if (l == 0) { - hdl->target_len = DEFAULT_TARGET_LEN; - } else { - hdl->target_len = l; - } + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + if (l == 0) { + hdl->target_len = DEFAULT_TARGET_LEN; + } else { + hdl->target_len = l; + } } /* * Call with L nonzero if whitespace in the generated shortname is wanted. */ - + void setshort_whitespace_ok(short_handle h, int l) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->whitespaceok = l; + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + hdl->whitespaceok = l; } /* - * Call with L nonzero if multiple consecutive whitespace in the + * Call with L nonzero if multiple consecutive whitespace in the * generated shortname is wanted. */ void setshort_repeating_whitespace_ok(short_handle h, int l) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->repeating_whitespaceok = l; + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + hdl->repeating_whitespaceok = l; } /* @@ -308,15 +296,16 @@ setshort_repeating_whitespace_ok(short_handle h, int l) * becuase it was filtered by charsets or null or whatever. */ void -setshort_defname(short_handle h, const char *s) +setshort_defname(short_handle h, const char* s) { - mkshort_handle *hdl = (mkshort_handle *) h; - if (s == NULL) { - fatal("setshort_defname called without a valid name."); - } - if (hdl->defname != NULL) - xfree(hdl->defname); - hdl->defname = xstrdup(s); + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + if (s == NULL) { + fatal("setshort_defname called without a valid name."); + } + if (hdl->defname != NULL) { + xfree(hdl->defname); + } + hdl->defname = xstrdup(s); } /* @@ -325,30 +314,33 @@ setshort_defname(short_handle h, const char *s) * resets to default. */ void -setshort_badchars(short_handle h, const char *s) +setshort_badchars(short_handle h, const char* s) { - mkshort_handle *hdl = (mkshort_handle *) h; + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; - if ((hdl->badchars != NULL)) - xfree(hdl->badchars); - hdl->badchars = xstrdup (s ? s : DEFAULT_BADCHARS); + if ((hdl->badchars != NULL)) { + xfree(hdl->badchars); + } + hdl->badchars = xstrdup(s ? s : DEFAULT_BADCHARS); } /* - * Only characters that appear in *s are "whitelisted" to appear + * Only characters that appear in *s are "whitelisted" to appear * in generated names. */ void -setshort_goodchars(short_handle h, const char *s) +setshort_goodchars(short_handle h, const char* s) { - mkshort_handle *hdl = (mkshort_handle *) h; - - if (hdl->goodchars != NULL) - xfree(hdl->goodchars); - if (s != NULL) - hdl->goodchars = xstrdup(s); - else - hdl->goodchars = NULL; + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + + if (hdl->goodchars != NULL) { + xfree(hdl->goodchars); + } + if (s != NULL) { + hdl->goodchars = xstrdup(s); + } else { + hdl->goodchars = NULL; + } } /* @@ -357,430 +349,436 @@ setshort_goodchars(short_handle h, const char *s) void setshort_mustupper(short_handle h, int i) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->mustupper = i; + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + hdl->mustupper = i; } -/* +/* * Call with i zero if the generated names don't have to be unique. * (By default, they are.) */ void setshort_mustuniq(short_handle h, int i) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->must_uniq = i; + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + hdl->must_uniq = i; } -/* +/* * Declare that actually characters are (or are not) encoded in UTF-8. */ void setshort_is_utf8(short_handle h, const int is_utf8) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->is_utf8 = is_utf8; + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + hdl->is_utf8 = is_utf8; } -char * +char* #ifdef DEBUG_MEM -MKSHORT(short_handle h, const char *istring, DEBUG_PARAMS ) +MKSHORT(short_handle h, const char* istring, DEBUG_PARAMS) #else -mkshort(short_handle h, const char *istring) +mkshort(short_handle h, const char* istring) #endif { - char *ostring; - char *nstring; - char *tstring; - char *cp; - char *np; - int i, l, nlen, replaced; - mkshort_handle *hdl = (mkshort_handle *) h; - - if (hdl->is_utf8) ostring = cet_utf8_strdup(istring); /* clean UTF-8 string */ - else ostring = xxstrdup(istring, file, line); - - /* - * A rather horrible special case hack. - * If the target length is "6" and the source length is "7" and - * the first two characters are "GC", we'll assume it's one of the - * the new seven digit geocache numbers and special case whacking - * the 'G' off the front. - */ - if ((hdl->target_len == 6) && (strlen(ostring) == 7) && - (ostring[0] == 'G') && (ostring[1] == 'C')) { - memmove(&ostring[0], &ostring[1], strlen(ostring)); - } - - /* - * Whack leading "[Tt]he", - */ - if (( strlen(ostring) > hdl->target_len + 4) && - (strncmp(ostring, "The ", 4) == 0 || - strncmp(ostring, "the ", 4) == 0)) { - nstring = xxstrdup(ostring + 4, file, line); - xfree(ostring); - ostring = nstring; - } - - /* Eliminate leading whitespace in all cases */ - while (ostring[0] && isspace(ostring[0])) { - /* If orig string has N bytes, we want to copy N-1 bytes - * of the string itself plus the string terminator (which - * matters if the string consists of nothing but spaces) - */ - memmove(&ostring[0], &ostring[1], strlen(ostring)); - } - - if (!hdl->whitespaceok) { - /* - * Eliminate Whitespace - */ - tstring = xxstrdup(ostring, file, line); - l = strlen (tstring); - cp = ostring; - for (i=0;imustupper) { - for (tstring = ostring; *tstring; tstring++) { - *tstring = toupper(*tstring); - } - } - - /* Before we do any of the vowel or character removal, look for - * constants to replace. - */ - - replace_constants(ostring); - - /* - * Eliminate chars on the blacklist. - */ - tstring = xxstrdup(ostring, file, line); - l = strlen (tstring); - cp = ostring; - for (i=0;ibadchars, tstring[i])) - continue; - if (hdl->goodchars && (!strchr(hdl->goodchars, tstring[i]))) - continue; + char* ostring; + char* nstring; + char* tstring; + char* cp; + char* np; + int i, l, nlen, replaced; + mkshort_handle_imp* hdl = (mkshort_handle_imp*) h; + + if (hdl->is_utf8) { + ostring = cet_utf8_strdup(istring); /* clean UTF-8 string */ + } else { + ostring = xxstrdup(istring, file, line); + } + + /* + * A rather horrible special case hack. + * If the target length is "6" and the source length is "7" and + * the first two characters are "GC", we'll assume it's one of the + * the new seven digit geocache numbers and special case whacking + * the 'G' off the front. + */ + if ((hdl->target_len == 6) && (strlen(ostring) == 7) && + (ostring[0] == 'G') && (ostring[1] == 'C')) { + memmove(&ostring[0], &ostring[1], strlen(ostring)); + } + + /* + * Whack leading "[Tt]he", + */ + if ((strlen(ostring) > hdl->target_len + 4) && + (strncmp(ostring, "The ", 4) == 0 || + strncmp(ostring, "the ", 4) == 0)) { + nstring = xxstrdup(ostring + 4, file, line); + xfree(ostring); + ostring = nstring; + } + + /* Eliminate leading whitespace in all cases */ + while (ostring[0] && isspace(ostring[0])) { + /* If orig string has N bytes, we want to copy N-1 bytes + * of the string itself plus the string terminator (which + * matters if the string consists of nothing but spaces) + */ + memmove(&ostring[0], &ostring[1], strlen(ostring)); + } + + if (!hdl->whitespaceok) { + /* + * Eliminate Whitespace + */ + tstring = xxstrdup(ostring, file, line); + l = strlen(tstring); + cp = ostring; + for (i=0; imustupper) { + for (tstring = ostring; *tstring; tstring++) { + *tstring = toupper(*tstring); + } + } + + /* Before we do any of the vowel or character removal, look for + * constants to replace. + */ + + replace_constants(ostring); + + /* + * Eliminate chars on the blacklist. + */ + tstring = xxstrdup(ostring, file, line); + l = strlen(tstring); + cp = ostring; + for (i=0; ibadchars, tstring[i])) { + continue; + } + if (hdl->goodchars && (!strchr(hdl->goodchars, tstring[i]))) { + continue; + } // FIXME(robertl): we need a way to not return partial UTF-8, but this isn't it. // if (!isascii(tstring[i])) // continue; - *cp++ = tstring[i]; - } - *cp = 0; - xfree(tstring); - - /* - * Eliminate repeated whitespace. This can only shorten the string - * so we do it in place. - */ - if (!hdl->repeating_whitespaceok) { - for (i = 0; i < l-1; i++) { - if (ostring[i] == ' ' && ostring[i+1] == ' ') { - memmove(&ostring[i], &ostring[i+1], l-i); - } - } - } - - /* - * Toss vowels to approach target length, but don't toss them - * if we don't have to. We always keep the leading two letters - * to preserve leading vowels and some semblance of pronouncability. - * - * FIXME: There's a boundary case here where we're too aggressive. - * If the target length is "6" we will shorten "Trolley" to "Trlly", - * when we really don't have to. We should throw away one vowel, not - * both. - */ - - /* - * Delete vowels starting from the end. If it fits, quit stomping - * them. If we run out of string, give up. - * - * Skip this test is our target length is arbitrarily considered - * "long" as it turns out a truncated string of full words is easier - * to read than a full string of vowelless words. - * - * It also helps units with speech synthesis. - */ - if ( hdl->target_len < 15) { - replaced = 1; - } else { - replaced = 0; - } - - while (replaced && strlen(ostring) > hdl->target_len) { - ostring = delete_last_vowel(2, ostring, &replaced); - } - - /* - * Next to last thing, we look for trailing numbers and try to - * preserve those. This ensures that. - * Walk in the Woods 1. - * Walk in the Woods 2. - */ - - np = ostring + strlen(ostring); - while ((np != ostring) && *(np-1) && isdigit(*(np-1) )) { - np--; - } - if (np) { - nlen = strlen(np); - } - - /* - * Now brutally truncate the resulting string, preserve trailing - * numeric data. - * If the numeric component alone is longer than our target string - * length, use only what'll fit. - */ - if (hdl->is_utf8) { - /* ToDo: Keep trailing numeric data as described above! */ - if (cet_utf8_strlen(ostring) > hdl->target_len) { - char *tmp = cet_utf8_strndup(ostring, hdl->target_len); - xfree(ostring); - ostring = tmp; - } - } - else if ((/*i = */strlen(ostring)) > hdl->target_len) { - char *dp = &ostring[hdl->target_len] - strlen(np); - if (dp < ostring) dp = ostring; - memmove(dp, np, strlen(np)); - dp[strlen(np)] = 0; - rtrim(ostring); - } - - /* - * If, after all that, we have an empty string, punt and - * let the must_uniq code handle it. - */ - if (ostring[0] == '\0') { - xfree(ostring); - ostring = xstrdup(hdl->defname); - } - - if (hdl->must_uniq) { - return mkshort_add_to_list(hdl, ostring); - } - return ostring; + *cp++ = tstring[i]; + } + *cp = 0; + xfree(tstring); + + /* + * Eliminate repeated whitespace. This can only shorten the string + * so we do it in place. + */ + if (!hdl->repeating_whitespaceok) { + for (i = 0; i < l-1; i++) { + if (ostring[i] == ' ' && ostring[i+1] == ' ') { + memmove(&ostring[i], &ostring[i+1], l-i); + } + } + } + + /* + * Toss vowels to approach target length, but don't toss them + * if we don't have to. We always keep the leading two letters + * to preserve leading vowels and some semblance of pronouncability. + * + * FIXME: There's a boundary case here where we're too aggressive. + * If the target length is "6" we will shorten "Trolley" to "Trlly", + * when we really don't have to. We should throw away one vowel, not + * both. + */ + + /* + * Delete vowels starting from the end. If it fits, quit stomping + * them. If we run out of string, give up. + * + * Skip this test is our target length is arbitrarily considered + * "long" as it turns out a truncated string of full words is easier + * to read than a full string of vowelless words. + * + * It also helps units with speech synthesis. + */ + if (hdl->target_len < 15) { + replaced = 1; + } else { + replaced = 0; + } + + while (replaced && strlen(ostring) > hdl->target_len) { + ostring = delete_last_vowel(2, ostring, &replaced); + } + + /* + * Next to last thing, we look for trailing numbers and try to + * preserve those. This ensures that. + * Walk in the Woods 1. + * Walk in the Woods 2. + */ + + np = ostring + strlen(ostring); + while ((np != ostring) && *(np-1) && isdigit(*(np-1))) { + np--; + } + if (np) { + nlen = strlen(np); + } + + /* + * Now brutally truncate the resulting string, preserve trailing + * numeric data. + * If the numeric component alone is longer than our target string + * length, use only what'll fit. + */ + if (hdl->is_utf8) { + /* ToDo: Keep trailing numeric data as described above! */ + if (cet_utf8_strlen(ostring) > hdl->target_len) { + char* tmp = cet_utf8_strndup(ostring, hdl->target_len); + xfree(ostring); + ostring = tmp; + } + } else if ((/*i = */strlen(ostring)) > hdl->target_len) { + char* dp = &ostring[hdl->target_len] - strlen(np); + if (dp < ostring) { + dp = ostring; + } + memmove(dp, np, strlen(np)); + dp[strlen(np)] = 0; + rtrim(ostring); + } + + /* + * If, after all that, we have an empty string, punt and + * let the must_uniq code handle it. + */ + if (ostring[0] == '\0') { + xfree(ostring); + ostring = xstrdup(hdl->defname); + } + + if (hdl->must_uniq) { + return mkshort_add_to_list(hdl, ostring); + } + return ostring; } /* * As above, but arg list is a waypoint so we can centralize * the code that considers the alternate sources. */ -char * -mkshort_from_wpt(short_handle h, const waypoint *wpt) +char* +mkshort_from_wpt(short_handle h, const waypoint* wpt) { - /* This probably came from a Groundspeak Pocket Query - * so use the 'cache name' instead of the description field - * which contains placer name, diff, terr, and generally way - * more stuff than should be in any one field... - */ - if (wpt->gc_data->diff && wpt->gc_data->terr && - wpt->notes && wpt->notes[0]) { - return mkshort(h, wpt->notes); - } - - if (wpt->description) { - return mkshort(h, wpt->description); - } - - if (wpt->notes) { - return mkshort(h, wpt->notes); - } - - /* Should probably never actually happen... */ - /* O.K.: But this can happen (waypoints transformed from trackpoints )! */ - /* Now we return every time a valid entity." */ - - return mkshort(h, wpt->shortname); + /* This probably came from a Groundspeak Pocket Query + * so use the 'cache name' instead of the description field + * which contains placer name, diff, terr, and generally way + * more stuff than should be in any one field... + */ + if (wpt->gc_data->diff && wpt->gc_data->terr && + wpt->notes && wpt->notes[0]) { + return mkshort(h, wpt->notes); + } + + if (wpt->description) { + return mkshort(h, wpt->description); + } + + if (wpt->notes) { + return mkshort(h, wpt->notes); + } + + /* Should probably never actually happen... */ + /* O.K.: But this can happen (waypoints transformed from trackpoints )! */ + /* Now we return every time a valid entity." */ + + return mkshort(h, wpt->shortname); } #if 0 -char *foo[] = { -"VwthPst# 3700.706N 08627.588W 0000000m View the Past #2 ", -"PilotRoc 3655.270N 08717.173W 0000000m Pilot Rock by CacheAdvance ", -"MrCycsNg 3652.407N 08728.890W 0000000m Mr. Cayces Neighborhood by Ca", -"SOLDIER 3640.691N 08726.660W 0000000m SOLDIER’S TRIBUTE ", -"ZOOMZOOM 3636.659N 08721.793W 0000000m ZOOM ZOOM ZOOM by Feros Family", -"SOCLOSEB 3636.494N 08722.086W 0000000m SO CLOSE BUT YET by Kyle of Fe", -"InSrchfS 3636.363N 08636.363W 0000000m In Search of Steam by BigHank ", -"RdBlngSp 3632.119N 08550.956W 0000000m Red Boiling Springs by Firedog", -"HelngWtr 3631.729N 08550.481W 0000000m Healing Waters by FiredogPotte", -"AHHtheVi 3629.020N 08533.891W 0000000m ogPotter ", -"LstCrkCc 3628.167N 08801.656W 0000000m Lost Creek Cache by Paul Kathy", -"DlvrncTr 3626.412N 08729.249W 0000000m Deliverance Train by Team Skay", -"FrQrtrRn 3438.502N 08646.926W 0000000m Four Quarter Rendezvous by Zay", -"Jstlttlc 3620.647N 08814.298W 0000000m Just a little cache by Paul Ka", -"BrryPtch 3618.786N 08616.344W 0000000m Berry Patch Cache by White Dog", -"AStrllDw 3342.752N 08630.829W 0000000m A Stroll Down Memory Lane by t", -"QunfTnns 3606.413N 08651.962W 0000000m Queen of Tennessee by A182pilo", -"GoneFish 3618.199N 08655.171W 0000000m Gone Fishin' by White Dog Pack", -"GrnwysFn 3610.942N 08642.061W 0000000m Greenways Fence by Ukulele And", -"AStnsThr 3611.240N 08638.324W 0000000m A Stone's Throw by Murrcat & S", -"Nashvlls 3617.112N 08642.359W 0000000m Nashville's Zoo by White Dog P", -"BltzMcr4 3517.127N 08622.211W 0000000m Blitz Micro Number 4 by IHTFP ", -"NkdnthWn 3437.145N 08651.693W 0000000m Naked in the Wind by Zaybex ", -"ANcPlctR 3603.389N 08654.418W 0000000m A Nice Place to Rest by JoGPS ", -"welcomtT 3638.155N 08720.130W 0000000m welcome to TN by Raf of the se", -"welcomtK 3638.956N 08721.011W 0000000m welcome to KY by raf of the se", -"BltzMcr5 3506.191N 08634.277W 0000000m Blitz Micro Number 5 by IHTFP ", -"JmsFmlyG 3615.887N 08649.846W 0000000m James Family Grocery by White ", -"seekngrf 3629.262N 08742.333W 0000000m seekeing refuge by raf of the ", -"SecrtFll 3614.927N 08534.180W 0000000m Secret Falls ", -"ApstlcTh 3613.870N 08645.108W 0000000m Apostolic Thistle Walk by Jame", -"WllIllBD 3609.258N 08637.268W 0000000m Well....I'll Be \"Dammed\" byi", -"BettysBt 3608.857N 08550.564W 0000000m Betty's Booty by White Dog Pac", -"SmthngSm 3439.748N 08643.522W 0000000m Something Smells Fishy by Zayb", -"RckyRd(C 3605.315N 08549.326W 0000000m Rocky Road (Center Hill Lake) ", -"Brdwtchr 3436.605N 08651.243W 0000000m Birdwatcher's Dream by Zaybex ", -"JcksnsHl 3605.185N 08619.439W 0000000m Jackson's Halls by White Dog P", -"FrgttnP2 3509.599N 08633.282W 0000000m Forgotten Park 2 by mdawg & mu", -"SOLDIERS 3640.691N 08726.660W 0000000m SOLDIERS TRIBUTE by Feros Fami", -"EndofRop 3433.820N 08650.460W 0000000m End of Rope by Big Rock ", -"VwthPst1 3659.263N 08627.114W 0000000m View the Past #1 by wkgraham ", -"VwthPst2 3700.706N 08627.588W 0000000m View the Past #2 by wkgraham ", -"Trash#8 3603.102N 08655.144W 0000000m Cache In Trash Out # 8 ", -"SlwwwwCc 3602.543N 08535.953W 0000000m Sloowwww Cache by Tntcacher ", -"Leavttbv 3602.514N 08638.686W 0000000m Leave it to beaver by A182pilo", -"WhrrthHr 3436.594N 08654.759W 0000000m Where are the Horses? by Zaybe", -"ButtonCc 3433.401N 08645.294W 0000000m Button Cache by Zaybex ", -"MrcsLbrr 3436.842N 08655.972W 0000000m Marco's Library by Marco ", -"Octopus 3526.743N 08534.757W 0000000m Octopus by White Dog Pack ", -"WtrFllsV 3544.140N 08527.861W 0000000m Water Falls Valley by Cave Rat", -"DeddrpPn 3448.126N 08719.696W 0000000m Dead-drop Pink by Marco ", -"JWhlrRvr 3448.157N 08719.914W 0000000m Joe Wheeler River Walk by Marc", -"CvSprngs 3432.797N 08651.084W 0000000m Cave Springs Cache by Marco.. ", -"CnyFrkOv 3550.876N 08518.446W 0000000m Fork Overlook ", -"SheepsCa 3550.527N 08519.480W 0000000m Sheep's Cave ", -"VrgnFlls 3550.308N 08519.904W 0000000m Virgin Falls Cache ", -"ShrtctVr 3550.170N 08519.590W 0000000m Shortcut Virtual ", -"KlylFlls 3549.105N 08539.814W 0000000m Klaylee Falls Cache by pattytr", -"FshngfrB 3548.923N 08538.558W 0000000m BADGER by M&Mk ", -"TpfthHll 3548.808N 08601.722W 0000000m Top of the Hill Pet Cache by M", -"TwnFllsC 3548.560N 08537.996W 0000000m Twin Falls Cache by SLCREW a", -"WtchsCst 3548.197N 08537.673W 0000000m Witch's Castle Keys by SLCREW ", -"ThatCave 3544.901N 08522.854W 0000000m That Cave by JaDan150 and AprJ", -"BssltwnW 3541.174N 08801.489W 0000000m Busseltown Wildlife Refuge by ", -"Riverfrn 3540.968N 08546.995W 0000000m Riverfront by SLCREW and M&M", -"Basement 3540.086N 08521.304W 0000000m The Basement ", -"EfflTwrC 3617.132N 08818.371W 0000000m Eiffel Tower Cache by Dick Wan", -"KeyholeC 3544.562N 08524.098W 0000000m Keyhole Cave by Cave Rat ", -"(MC^2)Mn 3444.990N 08630.218W 0000000m (MC^2) Monte Sano Cuts Cache b", -"WildctCc 3636.823N 08808.087W 0000000m Wildcat Cache by The Storm ", -"NAlbm/Tn 3444.365N 08632.688W 0000000m N. Alabama / Tennessee Valley ", -"CalebsCa 3444.215N 08633.103W 0000000m Caleb's Cave by Papaw and Cale", -"MntSnPrs 3444.201N 08632.591W 0000000m Monte Sano Preserve by Evan & ", -"FltRckFl 3444.475N 08629.958W 0000000m Flat Rock Falls Cache by Jason", -"PanormCc 3443.961N 08631.638W 0000000m The Panorama Cache by IHTFP an", -"TnnssScv 3602.861N 08652.751W 0000000m Tennessee Scavenger Hunt Cache", -"Geocache 3435.209N 08655.968W 0000000m Geocache by Papaw & Caleb ", -"Skellig 3444.100N 08656.566W 0000000m Skellig by Zaybex ", -"Deceptio 3433.450N 08655.711W 0000000m Deception by Papaw and Caleb ", -"AwlknthD 3433.310N 08655.635W 0000000m A walk in the Desert by Papa", -"MiniMsQs 3558.934N 08650.674W 0000000m Mini Me's Quest by CrotalusRex", -"BakrsBlf 3541.891N 08717.300W 0000000m Bakers Bluff by Flower Child &", -"GoFlyAKi 3435.664N 08659.267W 0000000m Go Fly A Kite by Marco.. ", -"FlntCrkA 3432.028N 08656.806W 0000000m Flint Creek Adventure by Marco", -"HonordMn 3534.680N 08612.557W 0000000m Honored Mount by Southpaw ", -"SafariZo 3440.697N 08700.774W 0000000m Safari Zone by Zaybex ", -"JckDnlsC 3517.077N 08622.260W 0000000m Jack Daniels Cache by Rmearse ", -"FrgttnPr 3509.599N 08633.282W 0000000m Forgotten Park by mdawg & muff", -"DntOvrlk 3513.326N 08616.031W 0000000m Dont Overlook Me Cache ", -"ArYStmpd 3513.039N 08615.110W 0000000m Are You Stumped Yet? cache ", -"CchtthBn 3512.532N 08614.691W 0000000m Cache at the Bend ", -"Thtsnkng 3609.009N 08530.314W 0000000m That sinking feeling by Tntcac", -"GamersCc 3449.136N 08635.836W 0000000m mer's Cache by avoral ", -"CchMIfYC 3452.455N 08620.648W 0000000m Cache Me If You Can! by Glen H", -"SavageVs 3526.915N 08535.136W 0000000m Savage Vista by White Dog Pack", -"PrtrnG15 3555.479N 08653.274W 0000000m Praetorian Guards Hail Caesar #15!", -"WtrlnAmp 3443.722N 08632.535W 0000000m Waterline Amphitheater by Fath", -"BysLttlC 3447.569N 08638.448W 0000000m Boys' Little Cache by Zaybex ", -"DrgnsBrt 3443.779N 08635.188W 0000000m Dragon's Breath by Zaybex ", -"CryBbyHl 3430.733N 08657.362W 0000000m Cry Baby Hollow Cache by La Pa", -"Parmer 3606.218N 08651.590W 0000000m Parmer by A182pilot & Family ", -"JnnfrndJ 3438.141N 08632.991W 0000000m Jennifer and Jonathans Cliff C", -"ALDRIDGE 3435.305N 08632.868W 0000000m ALDRIDGE CREEK LOTTA LOOT!! by", -"RcktCtyS 3440.032N 08631.352W 0000000m Rocket City Stash by David Upt", -"TrgcAccd 3608.561N 08648.381W 0000000m Tragic Accident by Campaholics", -"FALLENTR 3439.210N 08631.104W 0000000m FALLEN TREE 4 MILE POST by zac", -"TrshOt15 3558.964N 08646.064W 0000000m Cache In Trash Out # 15 by Jo", -"TrshOt13 3602.214N 08650.428W 0000000m Cache In Trash Out #13 by JoGP", -"PrcysDrp 3604.312N 08653.465W 0000000m Percys Dripping Springs by KLi", -"TrshOt14 3605.292N 08648.560W 0000000m Cache In Trash Out # 14 by JoG", -"PrtrnGr5 3557.621N 08640.278W 0000000m Praetorian Guards Hail Caesar #5!", -"PrtrnGr4 3557.370N 08640.201W 0000000m Praetorian Guards Hail Caesar #4!", -"PrtrnGr3 3557.250N 08640.047W 0000000m Praetorian Guards Hail Caesar #3!", -"GrnMntnC 3439.120N 08631.100W 0000000m Green Mountain Cache by Steve ", -"TrshOt12 3605.330N 08635.817W 0000000m Cache In Trash Out #12 by JoGP", -"BlncngAc 3608.579N 08648.120W 0000000m Balancing Act by Campaholics ", -"DittoCac 3434.652N 08633.310W 0000000m Ditto Cache by mookey ", -"EraserCc 3431.888N 08633.024W 0000000m Eraser Cache by Zaybex ", -"FrMlPstE 3439.440N 08630.180W 0000000m Four Mile Post Extension Cache", -"MllrdFxC 3439.578N 08706.552W 0000000m Mallard-Fox Creek Cache by bam", -"FireCach 3443.908N 08630.318W 0000000m he by Glen Pam Chase M ", -"FlntRvrC 3443.170N 08625.990W 0000000m Flint River Canoe Cache by Ran", -"ArabinCc 3419.104N 08628.765W 0000000m The Arabian Cache by WesNSpace", -"CvrdBrdg 3412.406N 08659.392W 0000000m Covered Bridge Cache by pmarkh", -"MilesTCc 3424.470N 08611.720W 0000000m Miles Too Cache by Rmearse ", -"MbryOvrl 3423.803N 08611.922W 0000000m Mabrey Overlook Me by DDVaughn", -"LwEnfrcm 3423.218N 08612.258W 0000000m Law Enforcement Cache by DDVau", -"GrndDddy 3423.128N 08612.025W 0000000m Grand Daddys Home by Rmearse ", -"BamaCach 3421.459N 08611.686W 0000000m The Bama Cache by DDVaughn & T", -"Canyons 3440.085N 08600.910W 0000000m The Canyons by Aubrey and Josh", -"ADamGodV 3511.677N 08616.587W 0000000m A Dam Good View by mdawg & muf", -"UNDERTHE 3446.918N 08739.790W 0000000m UNDER THE ROCK by RUNNINGWILD ", -"SQUIRREL 3448.712N 08741.681W 0000000m SQUIRREL'S NEST by RUNNINGWILD", -"WlknthPr 3448.273N 08741.844W 0000000m Walk in the Park by Runningwil", -"NetsClue 3448.494N 08741.977W 0000000m Net's Clues by Runningwild Adv", -"NatrlBrd 3405.583N 08736.909W 0000000m Natural Bridge by Southeast Xt", -"TrnglPrk 3341.448N 08640.980W 0000000m Triangle Park Cache by Charles", -"LttlRvrI 3421.855N 08539.597W 0000000m Little River Initiative by spa", -"GimmShlt 3430.087N 08536.834W 0000000m Gimme Shelter by Big Rock & Po", -"GnomeTrs 3433.081N 08535.849W 0000000m Gnome Treasure by Big Rock ", -"FlyingTr 3608.594N 08648.179W 0000000m Flying Torso by Campaholics ", -"CultivtC 3608.582N 08648.064W 0000000m Cultivate a Cure by Campahol" +char* foo[] = { + "VwthPst# 3700.706N 08627.588W 0000000m View the Past #2 ", + "PilotRoc 3655.270N 08717.173W 0000000m Pilot Rock by CacheAdvance ", + "MrCycsNg 3652.407N 08728.890W 0000000m Mr. Cayces Neighborhood by Ca", + "SOLDIER 3640.691N 08726.660W 0000000m SOLDIER’S TRIBUTE ", + "ZOOMZOOM 3636.659N 08721.793W 0000000m ZOOM ZOOM ZOOM by Feros Family", + "SOCLOSEB 3636.494N 08722.086W 0000000m SO CLOSE BUT YET by Kyle of Fe", + "InSrchfS 3636.363N 08636.363W 0000000m In Search of Steam by BigHank ", + "RdBlngSp 3632.119N 08550.956W 0000000m Red Boiling Springs by Firedog", + "HelngWtr 3631.729N 08550.481W 0000000m Healing Waters by FiredogPotte", + "AHHtheVi 3629.020N 08533.891W 0000000m ogPotter ", + "LstCrkCc 3628.167N 08801.656W 0000000m Lost Creek Cache by Paul Kathy", + "DlvrncTr 3626.412N 08729.249W 0000000m Deliverance Train by Team Skay", + "FrQrtrRn 3438.502N 08646.926W 0000000m Four Quarter Rendezvous by Zay", + "Jstlttlc 3620.647N 08814.298W 0000000m Just a little cache by Paul Ka", + "BrryPtch 3618.786N 08616.344W 0000000m Berry Patch Cache by White Dog", + "AStrllDw 3342.752N 08630.829W 0000000m A Stroll Down Memory Lane by t", + "QunfTnns 3606.413N 08651.962W 0000000m Queen of Tennessee by A182pilo", + "GoneFish 3618.199N 08655.171W 0000000m Gone Fishin' by White Dog Pack", + "GrnwysFn 3610.942N 08642.061W 0000000m Greenways Fence by Ukulele And", + "AStnsThr 3611.240N 08638.324W 0000000m A Stone's Throw by Murrcat & S", + "Nashvlls 3617.112N 08642.359W 0000000m Nashville's Zoo by White Dog P", + "BltzMcr4 3517.127N 08622.211W 0000000m Blitz Micro Number 4 by IHTFP ", + "NkdnthWn 3437.145N 08651.693W 0000000m Naked in the Wind by Zaybex ", + "ANcPlctR 3603.389N 08654.418W 0000000m A Nice Place to Rest by JoGPS ", + "welcomtT 3638.155N 08720.130W 0000000m welcome to TN by Raf of the se", + "welcomtK 3638.956N 08721.011W 0000000m welcome to KY by raf of the se", + "BltzMcr5 3506.191N 08634.277W 0000000m Blitz Micro Number 5 by IHTFP ", + "JmsFmlyG 3615.887N 08649.846W 0000000m James Family Grocery by White ", + "seekngrf 3629.262N 08742.333W 0000000m seekeing refuge by raf of the ", + "SecrtFll 3614.927N 08534.180W 0000000m Secret Falls ", + "ApstlcTh 3613.870N 08645.108W 0000000m Apostolic Thistle Walk by Jame", + "WllIllBD 3609.258N 08637.268W 0000000m Well....I'll Be \"Dammed\" byi", + "BettysBt 3608.857N 08550.564W 0000000m Betty's Booty by White Dog Pac", + "SmthngSm 3439.748N 08643.522W 0000000m Something Smells Fishy by Zayb", + "RckyRd(C 3605.315N 08549.326W 0000000m Rocky Road (Center Hill Lake) ", + "Brdwtchr 3436.605N 08651.243W 0000000m Birdwatcher's Dream by Zaybex ", + "JcksnsHl 3605.185N 08619.439W 0000000m Jackson's Halls by White Dog P", + "FrgttnP2 3509.599N 08633.282W 0000000m Forgotten Park 2 by mdawg & mu", + "SOLDIERS 3640.691N 08726.660W 0000000m SOLDIERS TRIBUTE by Feros Fami", + "EndofRop 3433.820N 08650.460W 0000000m End of Rope by Big Rock ", + "VwthPst1 3659.263N 08627.114W 0000000m View the Past #1 by wkgraham ", + "VwthPst2 3700.706N 08627.588W 0000000m View the Past #2 by wkgraham ", + "Trash#8 3603.102N 08655.144W 0000000m Cache In Trash Out # 8 ", + "SlwwwwCc 3602.543N 08535.953W 0000000m Sloowwww Cache by Tntcacher ", + "Leavttbv 3602.514N 08638.686W 0000000m Leave it to beaver by A182pilo", + "WhrrthHr 3436.594N 08654.759W 0000000m Where are the Horses? by Zaybe", + "ButtonCc 3433.401N 08645.294W 0000000m Button Cache by Zaybex ", + "MrcsLbrr 3436.842N 08655.972W 0000000m Marco's Library by Marco ", + "Octopus 3526.743N 08534.757W 0000000m Octopus by White Dog Pack ", + "WtrFllsV 3544.140N 08527.861W 0000000m Water Falls Valley by Cave Rat", + "DeddrpPn 3448.126N 08719.696W 0000000m Dead-drop Pink by Marco ", + "JWhlrRvr 3448.157N 08719.914W 0000000m Joe Wheeler River Walk by Marc", + "CvSprngs 3432.797N 08651.084W 0000000m Cave Springs Cache by Marco.. ", + "CnyFrkOv 3550.876N 08518.446W 0000000m Fork Overlook ", + "SheepsCa 3550.527N 08519.480W 0000000m Sheep's Cave ", + "VrgnFlls 3550.308N 08519.904W 0000000m Virgin Falls Cache ", + "ShrtctVr 3550.170N 08519.590W 0000000m Shortcut Virtual ", + "KlylFlls 3549.105N 08539.814W 0000000m Klaylee Falls Cache by pattytr", + "FshngfrB 3548.923N 08538.558W 0000000m BADGER by M&Mk ", + "TpfthHll 3548.808N 08601.722W 0000000m Top of the Hill Pet Cache by M", + "TwnFllsC 3548.560N 08537.996W 0000000m Twin Falls Cache by SLCREW a", + "WtchsCst 3548.197N 08537.673W 0000000m Witch's Castle Keys by SLCREW ", + "ThatCave 3544.901N 08522.854W 0000000m That Cave by JaDan150 and AprJ", + "BssltwnW 3541.174N 08801.489W 0000000m Busseltown Wildlife Refuge by ", + "Riverfrn 3540.968N 08546.995W 0000000m Riverfront by SLCREW and M&M", + "Basement 3540.086N 08521.304W 0000000m The Basement ", + "EfflTwrC 3617.132N 08818.371W 0000000m Eiffel Tower Cache by Dick Wan", + "KeyholeC 3544.562N 08524.098W 0000000m Keyhole Cave by Cave Rat ", + "(MC^2)Mn 3444.990N 08630.218W 0000000m (MC^2) Monte Sano Cuts Cache b", + "WildctCc 3636.823N 08808.087W 0000000m Wildcat Cache by The Storm ", + "NAlbm/Tn 3444.365N 08632.688W 0000000m N. Alabama / Tennessee Valley ", + "CalebsCa 3444.215N 08633.103W 0000000m Caleb's Cave by Papaw and Cale", + "MntSnPrs 3444.201N 08632.591W 0000000m Monte Sano Preserve by Evan & ", + "FltRckFl 3444.475N 08629.958W 0000000m Flat Rock Falls Cache by Jason", + "PanormCc 3443.961N 08631.638W 0000000m The Panorama Cache by IHTFP an", + "TnnssScv 3602.861N 08652.751W 0000000m Tennessee Scavenger Hunt Cache", + "Geocache 3435.209N 08655.968W 0000000m Geocache by Papaw & Caleb ", + "Skellig 3444.100N 08656.566W 0000000m Skellig by Zaybex ", + "Deceptio 3433.450N 08655.711W 0000000m Deception by Papaw and Caleb ", + "AwlknthD 3433.310N 08655.635W 0000000m A walk in the Desert by Papa", + "MiniMsQs 3558.934N 08650.674W 0000000m Mini Me's Quest by CrotalusRex", + "BakrsBlf 3541.891N 08717.300W 0000000m Bakers Bluff by Flower Child &", + "GoFlyAKi 3435.664N 08659.267W 0000000m Go Fly A Kite by Marco.. ", + "FlntCrkA 3432.028N 08656.806W 0000000m Flint Creek Adventure by Marco", + "HonordMn 3534.680N 08612.557W 0000000m Honored Mount by Southpaw ", + "SafariZo 3440.697N 08700.774W 0000000m Safari Zone by Zaybex ", + "JckDnlsC 3517.077N 08622.260W 0000000m Jack Daniels Cache by Rmearse ", + "FrgttnPr 3509.599N 08633.282W 0000000m Forgotten Park by mdawg & muff", + "DntOvrlk 3513.326N 08616.031W 0000000m Dont Overlook Me Cache ", + "ArYStmpd 3513.039N 08615.110W 0000000m Are You Stumped Yet? cache ", + "CchtthBn 3512.532N 08614.691W 0000000m Cache at the Bend ", + "Thtsnkng 3609.009N 08530.314W 0000000m That sinking feeling by Tntcac", + "GamersCc 3449.136N 08635.836W 0000000m mer's Cache by avoral ", + "CchMIfYC 3452.455N 08620.648W 0000000m Cache Me If You Can! by Glen H", + "SavageVs 3526.915N 08535.136W 0000000m Savage Vista by White Dog Pack", + "PrtrnG15 3555.479N 08653.274W 0000000m Praetorian Guards Hail Caesar #15!", + "WtrlnAmp 3443.722N 08632.535W 0000000m Waterline Amphitheater by Fath", + "BysLttlC 3447.569N 08638.448W 0000000m Boys' Little Cache by Zaybex ", + "DrgnsBrt 3443.779N 08635.188W 0000000m Dragon's Breath by Zaybex ", + "CryBbyHl 3430.733N 08657.362W 0000000m Cry Baby Hollow Cache by La Pa", + "Parmer 3606.218N 08651.590W 0000000m Parmer by A182pilot & Family ", + "JnnfrndJ 3438.141N 08632.991W 0000000m Jennifer and Jonathans Cliff C", + "ALDRIDGE 3435.305N 08632.868W 0000000m ALDRIDGE CREEK LOTTA LOOT!! by", + "RcktCtyS 3440.032N 08631.352W 0000000m Rocket City Stash by David Upt", + "TrgcAccd 3608.561N 08648.381W 0000000m Tragic Accident by Campaholics", + "FALLENTR 3439.210N 08631.104W 0000000m FALLEN TREE 4 MILE POST by zac", + "TrshOt15 3558.964N 08646.064W 0000000m Cache In Trash Out # 15 by Jo", + "TrshOt13 3602.214N 08650.428W 0000000m Cache In Trash Out #13 by JoGP", + "PrcysDrp 3604.312N 08653.465W 0000000m Percys Dripping Springs by KLi", + "TrshOt14 3605.292N 08648.560W 0000000m Cache In Trash Out # 14 by JoG", + "PrtrnGr5 3557.621N 08640.278W 0000000m Praetorian Guards Hail Caesar #5!", + "PrtrnGr4 3557.370N 08640.201W 0000000m Praetorian Guards Hail Caesar #4!", + "PrtrnGr3 3557.250N 08640.047W 0000000m Praetorian Guards Hail Caesar #3!", + "GrnMntnC 3439.120N 08631.100W 0000000m Green Mountain Cache by Steve ", + "TrshOt12 3605.330N 08635.817W 0000000m Cache In Trash Out #12 by JoGP", + "BlncngAc 3608.579N 08648.120W 0000000m Balancing Act by Campaholics ", + "DittoCac 3434.652N 08633.310W 0000000m Ditto Cache by mookey ", + "EraserCc 3431.888N 08633.024W 0000000m Eraser Cache by Zaybex ", + "FrMlPstE 3439.440N 08630.180W 0000000m Four Mile Post Extension Cache", + "MllrdFxC 3439.578N 08706.552W 0000000m Mallard-Fox Creek Cache by bam", + "FireCach 3443.908N 08630.318W 0000000m he by Glen Pam Chase M ", + "FlntRvrC 3443.170N 08625.990W 0000000m Flint River Canoe Cache by Ran", + "ArabinCc 3419.104N 08628.765W 0000000m The Arabian Cache by WesNSpace", + "CvrdBrdg 3412.406N 08659.392W 0000000m Covered Bridge Cache by pmarkh", + "MilesTCc 3424.470N 08611.720W 0000000m Miles Too Cache by Rmearse ", + "MbryOvrl 3423.803N 08611.922W 0000000m Mabrey Overlook Me by DDVaughn", + "LwEnfrcm 3423.218N 08612.258W 0000000m Law Enforcement Cache by DDVau", + "GrndDddy 3423.128N 08612.025W 0000000m Grand Daddys Home by Rmearse ", + "BamaCach 3421.459N 08611.686W 0000000m The Bama Cache by DDVaughn & T", + "Canyons 3440.085N 08600.910W 0000000m The Canyons by Aubrey and Josh", + "ADamGodV 3511.677N 08616.587W 0000000m A Dam Good View by mdawg & muf", + "UNDERTHE 3446.918N 08739.790W 0000000m UNDER THE ROCK by RUNNINGWILD ", + "SQUIRREL 3448.712N 08741.681W 0000000m SQUIRREL'S NEST by RUNNINGWILD", + "WlknthPr 3448.273N 08741.844W 0000000m Walk in the Park by Runningwil", + "NetsClue 3448.494N 08741.977W 0000000m Net's Clues by Runningwild Adv", + "NatrlBrd 3405.583N 08736.909W 0000000m Natural Bridge by Southeast Xt", + "TrnglPrk 3341.448N 08640.980W 0000000m Triangle Park Cache by Charles", + "LttlRvrI 3421.855N 08539.597W 0000000m Little River Initiative by spa", + "GimmShlt 3430.087N 08536.834W 0000000m Gimme Shelter by Big Rock & Po", + "GnomeTrs 3433.081N 08535.849W 0000000m Gnome Treasure by Big Rock ", + "FlyingTr 3608.594N 08648.179W 0000000m Flying Torso by Campaholics ", + "CultivtC 3608.582N 08648.064W 0000000m Cultivate a Cure by Campahol" } ; main() { - char **foop = foo; - int r; - - printf("%s\n", mkshort("The Troll")); - printf("%s\n", mkshort("EFI")); - printf("%s\n", mkshort("the Troll")); - printf("%s\n", mkshort("the Trolley")); - printf("%s\n", mkshort("The Troll Lives Under The Bridge")); - printf("%s\n", mkshort("The \"Troll\" Lives Under $$ The Bridge!")); - printf("%s\n", mkshort("The Trolley Goes Round")); - printf("%s\n", mkshort("Cache In / Trash Out #1")); - printf("%s\n", mkshort("Cache In / Trash Out #2")); - printf("%s\n", mkshort("Cache In / Trash Out #137")); - - while (0 && *foop) { - printf("%s %s\n", mkshort(*foop+39), *foop+39); - foop++; - } - -printf("%s\n", delete_last_vowel(0, "the quick brown foo", &r)); -printf("%s\n", delete_last_vowel(0, "the quick brown fox", &r)); -printf("%s\n", delete_last_vowel(0, "xxx", &r)); -printf("%s\n", delete_last_vowel(0, "ixxx", &r)); -printf("%s\n", delete_last_vowel(0, "aexxx", &r)); - + char** foop = foo; + int r; + + printf("%s\n", mkshort("The Troll")); + printf("%s\n", mkshort("EFI")); + printf("%s\n", mkshort("the Troll")); + printf("%s\n", mkshort("the Trolley")); + printf("%s\n", mkshort("The Troll Lives Under The Bridge")); + printf("%s\n", mkshort("The \"Troll\" Lives Under $$ The Bridge!")); + printf("%s\n", mkshort("The Trolley Goes Round")); + printf("%s\n", mkshort("Cache In / Trash Out #1")); + printf("%s\n", mkshort("Cache In / Trash Out #2")); + printf("%s\n", mkshort("Cache In / Trash Out #137")); + + while (0 && *foop) { + printf("%s %s\n", mkshort(*foop+39), *foop+39); + foop++; + } + + printf("%s\n", delete_last_vowel(0, "the quick brown foo", &r)); + printf("%s\n", delete_last_vowel(0, "the quick brown fox", &r)); + printf("%s\n", delete_last_vowel(0, "xxx", &r)); + printf("%s\n", delete_last_vowel(0, "ixxx", &r)); + printf("%s\n", delete_last_vowel(0, "aexxx", &r)); + } #endif diff --git a/gpsbabel/mmo.c b/gpsbabel/mmo.c index d2ac2f77c..979e3c24c 100644 --- a/gpsbabel/mmo.c +++ b/gpsbabel/mmo.c @@ -19,10 +19,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + /* History: - + 2008/10/18: Initial release 2008/10/19: Don't write empty names Add options 'locked' and 'visible' @@ -35,6 +35,9 @@ 2008/12/12: Fix object release error 2010/09/10: Added read support for version 0x18 (test file created by Memory-Map European Edition, Version 5.4.2, Build 1089). + 2011/10/05: Fixed read support: Track, CurrentPosition, UTF-16 strings + (test file is version 0x18 as written by GPS units running 5.4.4 build 1114). + Strings now written in UTF-16 if necessary. */ #include @@ -52,36 +55,42 @@ // #define MMO_DBG -static char *opt_locked, *opt_visible, *opt_version; +static char* opt_locked, *opt_visible, *opt_version; static arglist_t mmo_args[] = { - { "locked", &opt_locked, "Write items 'locked' [default no]", "0", - ARGTYPE_BOOL, ARG_NOMINMAX }, - { "visible", &opt_visible, "Write items 'visible' [default yes]", "1", - ARGTYPE_BOOL, ARG_NOMINMAX }, - { "ver", &opt_version, "Write files with internal version [n]", NULL, - ARGTYPE_INT, "17", "18" }, - ARG_TERMINATOR + { + "locked", &opt_locked, "Write items 'locked' [default no]", "0", + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "visible", &opt_visible, "Write items 'visible' [default yes]", "1", + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "ver", &opt_version, "Write files with internal version [n]", NULL, + ARGTYPE_INT, "17", "18" + }, + ARG_TERMINATOR }; typedef struct mmo_data_s { - int objid; /* internal object id */ - char *name; - const char *category; /* currently not handled */ - gpsdata_type type; /* type of "data" */ - time_t ctime; - time_t mtime; - int left; /* number of un-readed route points */ - void *data; /* can be a waypoint, a route or a track */ - int refct; - struct mmo_data_s **members; - unsigned char visible:1; - unsigned char locked:1; - unsigned char loaded:1; + int objid; /* internal object id */ + char* name; + const char* category; /* currently not handled */ + gpsdata_type type; /* type of "data" */ + time_t ctime; + time_t mtime; + int left; /* number of un-readed route points */ + void* data; /* can be a waypoint, a route or a track */ + int refct; + struct mmo_data_s** members; + unsigned char visible:1; + unsigned char locked:1; + unsigned char loaded:1; } mmo_data_t; -static gbfile *fin, *fout; +static gbfile* fin, *fout; static int mmo_version; static int mmo_obj_ct; static int mmo_object_id; @@ -94,45 +103,45 @@ static gbuint16 ico_object_id; static gbuint16 pos_object_id; static gbuint16 txt_object_id; static gpsdata_type mmo_datatype; -static route_head *mmo_rte; +static route_head* mmo_rte; -static avltree_t *category_names, *objects, *mmobjects, *category_ids; -static avltree_t *icons; +static avltree_t* category_names, *objects, *mmobjects, *category_ids; +static avltree_t* icons; typedef struct mmo_icon_mapping_s { - const int value; - const char *icon; + const int value; + const char* icon; } mmo_icon_mapping_t; /* standard icons; no bitmaps in file */ static const mmo_icon_mapping_t mmo_icon_value_table[] = { - { 0x00, "Dot" }, - { 0x01, "House" }, - { 0x02, "Fuel" }, - { 0x03, "Car" }, - { 0x04, "Fish" }, - { 0x05, "Boat" }, - { 0x06, "Anchor" }, - { 0x07, "Wreck" }, - { 0x08, "Exit" }, - { 0x09, "Skull" }, - { 0x0A, "Flag" }, - { 0x0B, "Camp" }, - { 0x0C, "Man Overboard" }, - { 0x0D, "Deer" }, - { 0x0E, "First Aid" }, - { 0x0F, "Trackback" }, - { 0x10, "Tiny dot" }, - { 0x11, "Triangle" }, - { 0x12, "Square" }, - { 0x13, "Circle" }, - { 0x14, "Green bouy" }, - { 0x15, "Red bouy" }, - { 0x16, "Yellow bouy" }, - { 0x17, "Geocache" }, - - { -1, NULL } + { 0x00, "Dot" }, + { 0x01, "House" }, + { 0x02, "Fuel" }, + { 0x03, "Car" }, + { 0x04, "Fish" }, + { 0x05, "Boat" }, + { 0x06, "Anchor" }, + { 0x07, "Wreck" }, + { 0x08, "Exit" }, + { 0x09, "Skull" }, + { 0x0A, "Flag" }, + { 0x0B, "Camp" }, + { 0x0C, "Man Overboard" }, + { 0x0D, "Deer" }, + { 0x0E, "First Aid" }, + { 0x0F, "Trackback" }, + { 0x10, "Tiny dot" }, + { 0x11, "Triangle" }, + { 0x12, "Square" }, + { 0x13, "Circle" }, + { 0x14, "Green bouy" }, + { 0x15, "Red bouy" }, + { 0x16, "Yellow bouy" }, + { 0x17, "Geocache" }, + + { -1, NULL } }; static const gbuint32 obj_type_ico = 0x00; @@ -145,14 +154,14 @@ static const gbuint32 obj_type_wpt = 0x3C; #ifdef MMO_DBG static void -dbgprintf(const char *sobj, const char *fmt, ...) +dbgprintf(const char* sobj, const char* fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - printf(MYNAME "-%s: ", sobj); - vprintf(fmt, args); - va_end(args); + printf(MYNAME "-%s: ", sobj); + vprintf(fmt, args); + va_end(args); } # define DBG(args) dbgprintf args @@ -160,749 +169,862 @@ dbgprintf(const char *sobj, const char *fmt, ...) # define DBG(args) do {} while (0) ; #endif -static char * +static char* mmo_readstr(void) { - char *res; - int len; - - len = (unsigned)gbfgetc(fin); - if (len == 0xFF) { - len = gbfgetint16(fin); - if (len < 0) fatal(MYNAME ": Invalid string length (%d)!\n", len); - } - res = xmalloc(len + 1); - res[len] = '\0'; - if (len) { - gbfread(res, len, 1, fin); - if (len != strlen(res)) fatal(MYNAME ": Error in file structure!\n"); - } - - return res; + char* res; + int len; + + len = (unsigned)gbfgetc(fin); + if (len == 0xFF) { + // Next two bytes are either the length (strings longer than 254 chars) + // or FE then FF (which is -2) meaning a UTF-16 string + len = gbfgetint16(fin); + if (len == -2) { + // read the new length (single byte) + // length is number of "characters" not number of bytes + len = (unsigned)gbfgetc(fin); + if (len > 0) { + int ii, jj, ch, resbytes=0; + res = xmalloc(len*2 + 1); // bigger to allow for utf-8 expansion + for (ii=0; ii (int)bufsz) fatal(MYNAME ": Internal error (bufsz too small)!\n"); - - memset(buf, 0xFF, count); - res = gbfread(buf, 1, count, fin); - if (need_all && (res < count)) fatal(MYNAME ": Unexpected end of file!\n"); - - return res; + gbsize_t res; + + if (count > (int)bufsz) { + fatal(MYNAME ": Internal error (bufsz too small)!\n"); + } + + memset(buf, 0xFF, count); + res = gbfread(buf, 1, count, fin); + if (need_all && (res < count)) { + fatal(MYNAME ": Unexpected end of file!\n"); + } + + return res; } #define mmo_fillbuf(a,b,c) mmo_fillbuf2((a),sizeof((a)),(b),(c)) static void -mmo_printbuf(const char *buf, int count, const char *comment) +mmo_printbuf(const char* buf, int count, const char* comment) { #ifdef MMO_DBG - int i; - printf("%s", comment); - for (i = 0; i < count; i++) printf("%02X ", buf[i] & 0xFF); - printf("- "); - for (i = 0; i < count; i++) - if (isprint(buf[i])) printf("%c", buf[i] & 0xFF); - else printf("."); - printf("\n"); - fflush(stdout); + int i; + printf("%s", comment); + for (i = 0; i < count; i++) { + printf("%02X ", buf[i] & 0xFF); + } + printf("- "); + for (i = 0; i < count; i++) + if (isprint(buf[i])) { + printf("%c", buf[i] & 0xFF); + } else { + printf("."); + } + printf("\n"); + fflush(stdout); #endif } /******************************************************************************/ -static mmo_data_t * -mmo_register_object(const int objid, const void *ptr, const gpsdata_type type) +static mmo_data_t* +mmo_register_object(const int objid, const void* ptr, const gpsdata_type type) { - char key[16]; - mmo_data_t *data; - - data = xcalloc(1, sizeof(*data)); - data->data = (void *)ptr; - data->visible = 1; - data->locked = 0; - data->type = type; - data->objid = objid; - - snprintf(key, sizeof(key), "%d", objid); - avltree_insert(objects, key, data); - - return data; + char key[16]; + mmo_data_t* data; + + data = (mmo_data_t*) xcalloc(1, sizeof(*data)); + data->data = (void*)ptr; + data->visible = 1; + data->locked = 0; + data->type = type; + data->objid = objid; + + snprintf(key, sizeof(key), "%d", objid); + avltree_insert(objects, key, data); + + return data; } static int -mmo_get_objid(const void *ptr) +mmo_get_objid(const void* ptr) { - const char *key; - mmo_data_t *data; - - if ((key = avltree_first(objects, (void *)&data))) do { - if (data->data == ptr) { - return atoi(key); - } - } while ((key = avltree_next(objects, key, (void *)&data))); - - return 0; + const char* key; + mmo_data_t* data; + + if ((key = avltree_first(objects, (const void**)&data))) do { + if (data->data == ptr) { + return atoi(key); + } + } while ((key = avltree_next(objects, key, (const void**)&data))); + + return 0; } -static mmo_data_t * +static mmo_data_t* mmo_get_object(const gbuint16 objid) { - char key[16]; - mmo_data_t *data; - - snprintf(key, sizeof(key), "%d", objid | 0x8000); - if (! avltree_find(objects, key, (void *)&data)) { + char key[16]; + mmo_data_t* data; + + snprintf(key, sizeof(key), "%d", objid | 0x8000); + if (! avltree_find(objects, key, (const void**)&data)) { #ifdef MMO_DBG - gbfseek(fin, -2, SEEK_CUR); - int ni, n; - for (ni = 0; (n = gbfgetc(fin)) != EOF; ni++) { - DBG(("mmo_get_object", "%04X %02X %c (%d)\n", - ni, n, n >= 32 && n <= 126 ? (char)n : '.', n)); - } + gbfseek(fin, -2, SEEK_CUR); + int ni, n; + for (ni = 0; (n = gbfgetc(fin)) != EOF; ni++) { + DBG(("mmo_get_object", "%04X %02X %c (%d)\n", + ni, n, n >= 32 && n <= 126 ? (char)n : '.', n)); + } #endif - fatal(MYNAME ": Unregistered object id 0x%04X!\n", objid | 0x8000); - } - - return data; + fatal(MYNAME ": Unregistered object id 0x%04X!\n", objid | 0x8000); + } + + return data; } -static waypoint * -mmo_get_waypt(mmo_data_t *data) +static waypoint* +mmo_get_waypt(mmo_data_t* data) { - data->refct++; - if (data->refct == 1) return (waypoint *)data->data; - else return waypt_dupe((waypoint *)data->data); + data->refct++; + if (data->refct == 1) { + return (waypoint*)data->data; + } else { + return waypt_dupe((waypoint*)data->data); + } } static void -mmo_release_avltree(avltree_t *tree, const int is_object) +mmo_release_avltree(avltree_t* tree, const int is_object) { - const char *key; - char *name; - - if ((key = avltree_first(tree, (void *)&name))) { - do { - if (name == NULL) continue; - if (is_object) { - mmo_data_t *data = (mmo_data_t *)name; - if (data->name) xfree(data->name); - if ((data->type == wptdata) && (data->refct == 0)) - waypt_free((waypoint *)data->data); - } - xfree(name); - } while ((key = avltree_next(tree, key, (void *)&name))); - } - avltree_done(tree); + const char* key; + char* name; + + if ((key = avltree_first(tree, (const void**)&name))) { + do { + if (name == NULL) { + continue; + } + if (is_object) { + mmo_data_t* data = (mmo_data_t*)name; + if (data->name) { + xfree(data->name); + } + if ((data->type == wptdata) && (data->refct == 0)) { + waypt_free((waypoint*)data->data); + } + } + xfree(name); + } while ((key = avltree_next(tree, key, (const void**)&name))); + } + avltree_done(tree); } static void -mmo_register_icon(const int id, const char *name) +mmo_register_icon(const int id, const char* name) { - char key[16]; - - snprintf(key, sizeof(key), "%d", id); - avltree_insert(icons, key, xstrdup(name)); + char key[16]; + + snprintf(key, sizeof(key), "%d", id); + avltree_insert(icons, key, xstrdup(name)); } -static mmo_data_t *mmo_read_object(void); +static mmo_data_t* mmo_read_object(void); static void -mmo_end_of_route(mmo_data_t *data) +mmo_end_of_route(mmo_data_t* data) { #ifdef MMO_DBG - const char *sobj = "CObjRoute"; + const char* sobj = "CObjRoute"; #endif - route_head *rte = data->data; - char buf[7]; - - if (mmo_version >= 0x12) { - mmo_fillbuf(buf, 7, 1); - DBG((sobj, "route data (since 0x12): ")); - mmo_printbuf(buf, 7, ""); - - rte->line_color.bbggrr = le_read32(&buf[0]); - rte->line_color.opacity = 255 - (buf[6] * 51); - DBG((sobj, "color = 0x%06X\n", rte->line_color.bbggrr)); - DBG((sobj, "transparency = %d (-> %d)\n", buf[6], rte->line_color.opacity)); - DBG((sobj, "for \"%s\" \n", data->name)); - } - - if (rte->rte_waypt_ct == 0) { /* don't keep empty routes */ - route_del_head(rte); - data->data = NULL; - } + route_head* rte = (route_head*) data->data; + char buf[7]; + + if (mmo_version >= 0x12) { + mmo_fillbuf(buf, 7, 1); + DBG((sobj, "route data (since 0x12): ")); + mmo_printbuf(buf, 7, ""); + + rte->line_color.bbggrr = le_read32(&buf[0]); + rte->line_color.opacity = 255 - (buf[6] * 51); + DBG((sobj, "color = 0x%06X\n", rte->line_color.bbggrr)); + DBG((sobj, "transparency = %d (-> %d)\n", buf[6], rte->line_color.opacity)); + DBG((sobj, "for \"%s\" \n", data->name)); + } + + if (rte->rte_waypt_ct == 0) { /* don't keep empty routes */ + route_del_head(rte); + data->data = NULL; + } } static void -mmo_read_category(mmo_data_t *data) +mmo_read_category(mmo_data_t* data) { - int marker = gbfgetuint16(fin); - - if (marker & 0x8000) { - mmo_data_t *tmp; - - DBG(("mmo_read_category", "reading category object\n")); - gbfseek(fin, -2, SEEK_CUR); - tmp = mmo_read_object(); - if (data) data->category = tmp->name; - } + int marker = gbfgetuint16(fin); + + if (marker & 0x8000) { + mmo_data_t* tmp; + + DBG(("mmo_read_category", "reading category object\n")); + gbfseek(fin, -2, SEEK_CUR); + tmp = mmo_read_object(); + if (data) { + data->category = tmp->name; + } + } } static void -mmo_read_CObjIcons(mmo_data_t *data) +mmo_read_CObjIcons(mmo_data_t* data) { #ifdef MMO_DBG - const char *sobj = "CObjIcons"; + const char* sobj = "CObjIcons"; #endif - int icon_id; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - if (mmo_version >= 0x18) { - gbuint16 u16; - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - } - gbuint16 u16; - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X\n", u16)); - - while ((icon_id = gbfgetuint32(fin))) { - char *name; - (void) gbfgetuint32(fin); - (void) gbfgetuint32(fin); - name = mmo_readstr(); - DBG((sobj, "bitmap(0x%08X) = \"%s\"\n", icon_id, name)); - mmo_register_icon(icon_id, name); - xfree(name); - // The next four bytes hold the length of the image, - // read them and then skip the image data. - gbfseek(fin, gbfgetuint32(fin), SEEK_CUR); - } + int icon_id; + gbuint16 u16; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + if (mmo_version >= 0x18) { + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + } + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X\n", u16)); + + while ((icon_id = gbfgetuint32(fin))) { + char* name; + (void) gbfgetuint32(fin); + (void) gbfgetuint32(fin); + name = mmo_readstr(); + DBG((sobj, "bitmap(0x%08X) = \"%s\"\n", icon_id, name)); + mmo_register_icon(icon_id, name); + xfree(name); + // The next four bytes hold the length of the image, + // read them and then skip the image data. + gbfseek(fin, gbfgetuint32(fin), SEEK_CUR); + } } static void -mmo_read_CObjWaypoint(mmo_data_t *data) +mmo_read_CObjWaypoint(mmo_data_t* data) { #ifdef MMO_DBG - const char *sobj = "CObjWaypoint"; + const char* sobj = "CObjWaypoint"; #endif - waypoint *wpt; - time_t time; - int rtelinks; - mmo_data_t **rtelink = NULL; - char *str; - char buf[16]; - int i, ux; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - data->data = wpt = waypt_new(); - wpt->shortname = xstrdup(data->name); - - time = data->mtime; - if (! time) time = data->ctime; - if (time > 0) wpt->creation_time = time; - - if (mmo_version >= 0x18) { - gbuint16 u16; - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - } - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - - DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude)); - - rtelinks = gbfgetuint16(fin); - if (rtelinks > 0) { - - rtelink = xcalloc(sizeof(*rtelink), rtelinks); - DBG((sobj, "rtelinks = %d\n", rtelinks)); - - for (i = 0; i < rtelinks; i++) { - mmo_data_t *tmp; - - DBG((sobj, "read rtelink number %d\n", i + 1)); - rtelink[i] = tmp = mmo_read_object(); - } - - } - - str = mmo_readstr(); /* descr + url */ - if (strncmp(str, "_FILE_ ", 7) == 0) { - char *cx, *cend; - - cx = lrtrim(str + 7); - cend = strchr(cx, '\n'); - if (cend == NULL) cend = cx + strlen(cx); - - cx = lrtrim(xstrndup(cx, cend - cx)); - if (*cx) wpt->url = cx; - else xfree(cx); - - if (*cend++) wpt->notes = xstrdup(cend); - - if (wpt->url) DBG((sobj, "url = \"%s\"\n", wpt->url)); - } - else - if (*str) wpt->notes = xstrdup(str); - xfree(str); - - if (wpt->notes) DBG((sobj, "notes = \"%s\"\n", wpt->notes)); - - mmo_fillbuf(buf, 12, 1); - i = le_read32(&buf[8]); /* icon */ - if (i != -1) { - char key[16]; - char *name; - - snprintf(key, sizeof(key), "%d", i); - if (avltree_find(icons, key, (void *)&name)) { - wpt->icon_descr = xstrdup(name); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - DBG((sobj, "icon = \"%s\"\n", wpt->icon_descr)); - } + waypoint* wpt; + time_t time; + int rtelinks; + mmo_data_t** rtelink = NULL; + char* str; + char buf[16]; + int i, ux; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + data->data = wpt = waypt_new(); + wpt->shortname = xstrdup(data->name); + + time = data->mtime; + if (! time) { + time = data->ctime; + } + if (time > 0) { + wpt->creation_time = time; + } + + if (mmo_version >= 0x18) { + gbuint16 u16; + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + } + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + + DBG((sobj, "trackpoint %d/%d coordinates = %f / %f\n", ctp+1,tp, wpt->latitude, wpt->longitude)); + + rtelinks = gbfgetuint16(fin); + if (rtelinks > 0) { + + rtelink = (mmo_data_t**) xcalloc(sizeof(*rtelink), rtelinks); + DBG((sobj, "rtelinks = %d\n", rtelinks)); + + for (i = 0; i < rtelinks; i++) { + mmo_data_t* tmp; + + DBG((sobj, "read rtelink number %d\n", i + 1)); + rtelink[i] = tmp = mmo_read_object(); + } + + } + + str = mmo_readstr(); /* descr + url */ + if (strncmp(str, "_FILE_ ", 7) == 0) { + char* cx, *cend; + + cx = lrtrim(str + 7); + cend = strchr(cx, '\n'); + if (cend == NULL) { + cend = cx + strlen(cx); + } + + cx = lrtrim(xstrndup(cx, cend - cx)); + if (*cx) { + wpt->url = cx; + } else { + xfree(cx); + } + + if (*cend++) { + wpt->notes = xstrdup(cend); + } + + if (wpt->url) { + DBG((sobj, "url = \"%s\"\n", wpt->url)); + } + } else if (*str) { + wpt->notes = xstrdup(str); + } + xfree(str); + + if (wpt->notes) { + DBG((sobj, "notes = \"%s\"\n", wpt->notes)); + } + + mmo_fillbuf(buf, 12, 1); + i = le_read32(&buf[8]); /* icon */ + if (i != -1) { + char key[16]; + char* name; + + snprintf(key, sizeof(key), "%d", i); + if (avltree_find(icons, key, (const void**)&name)) { + wpt->icon_descr = xstrdup(name); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + DBG((sobj, "icon = \"%s\"\n", wpt->icon_descr)); + } #ifdef MMO_DBG - else { - DBG((sobj, "icon not found for 0x%08X\n", i)); - } + else { + DBG((sobj, "icon not found for 0x%08X\n", i)); + } #endif - } - - wpt->proximity = le_read_float(&buf[4]); - if (wpt->proximity) { - wpt->wpt_flags.proximity = 1; - DBG((sobj, "proximity = %f\n", wpt->proximity)); - } - - str = mmo_readstr(); /* name on gps ??? option ??? */ - if (*str) { - wpt->description = wpt->shortname; - wpt->shortname = str; - DBG((sobj, "name on gps = %s\n", str)); - } - else xfree(str); - - ux = gbfgetuint32(fin); - DBG((sobj, "proximity type = %d\n", ux)); - - data->loaded = 1; - - if (rtelink) xfree(rtelink); - else waypt_add(mmo_get_waypt(data)); + } + + wpt->proximity = le_read_float(&buf[4]); + if (wpt->proximity) { + wpt->wpt_flags.proximity = 1; + DBG((sobj, "proximity = %f\n", wpt->proximity)); + } + + str = mmo_readstr(); /* name on gps ??? option ??? */ + if (*str) { + wpt->description = wpt->shortname; + wpt->shortname = str; + DBG((sobj, "name on gps = %s\n", str)); + } else { + xfree(str); + } + + ux = gbfgetuint32(fin); + DBG((sobj, "proximity type = %d\n", ux)); + + data->loaded = 1; + + if (rtelink) { + xfree(rtelink); + } else { + waypt_add(mmo_get_waypt(data)); + } } static void -mmo_read_CObjRoute(mmo_data_t *data) +mmo_read_CObjRoute(mmo_data_t* data) { #ifdef MMO_DBG - const char *sobj = "CObjRoute"; + const char* sobj = "CObjRoute"; #endif - int rtept; - route_head *rte; - char buf[16]; - int ux; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - data->data = rte = route_head_alloc(); - rte->rte_name = xstrdup(data->name); - route_add_head(rte); - - if (mmo_version >= 0x18) { - gbuint16 u16; - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - } - - ux = gbfgetc(fin); /* line label */ - DBG((sobj, "line label = %d\n", ux)); - - data->left = rtept = gbfgetint16(fin); - DBG((sobj, "route has %d point(s)\n", rtept)); - - if (data->left <= 0) { - if (mmo_version >= 0x12) mmo_fillbuf(buf, 7, 1); - route_del_head(rte); - data->data = NULL; - - return; - } - - while (data->left > 0) { - mmo_data_t *tmp; - - DBG((sobj, "read next waypoint\n")); - tmp = mmo_read_object(); - if (tmp && tmp->data && (tmp->type = wptdata)) { - waypoint *wpt; - - /* FIXME: At this point this waypoint maybe not fully loaded (initialized) !!! - We need a final procedure to handle this !!! */ - if (! tmp->loaded) { - wpt = waypt_new(); - wpt->latitude = 0; - wpt->longitude = 0; - xasprintf(&wpt->shortname, "\01%p", tmp); - } - else wpt = mmo_get_waypt(tmp); - - route_add_wpt(rte, wpt); - data->left--; - } - } - - if (mmo_version > 0x11) mmo_end_of_route(data); + int rtept; + route_head* rte; + char buf[16]; + int ux; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + data->data = rte = route_head_alloc(); + rte->rte_name = xstrdup(data->name); + route_add_head(rte); + + if (mmo_version >= 0x18) { + gbuint16 u16; + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + } + + ux = gbfgetc(fin); /* line label */ + DBG((sobj, "line label = %d\n", ux)); + + data->left = rtept = gbfgetint16(fin); + DBG((sobj, "route has %d point(s)\n", rtept)); + + if (data->left <= 0) { + if (mmo_version >= 0x12) { + mmo_fillbuf(buf, 7, 1); + } + route_del_head(rte); + data->data = NULL; + + return; + } + + while (data->left > 0) { + mmo_data_t* tmp; + + DBG((sobj, "read next waypoint\n")); + tmp = mmo_read_object(); + if (tmp && tmp->data && (tmp->type = wptdata)) { + waypoint* wpt; + + /* FIXME: At this point this waypoint maybe not fully loaded (initialized) !!! + We need a final procedure to handle this !!! */ + if (! tmp->loaded) { + wpt = waypt_new(); + wpt->latitude = 0; + wpt->longitude = 0; + xasprintf(&wpt->shortname, "\01%p", tmp); + } else { + wpt = mmo_get_waypt(tmp); + } + + route_add_wpt(rte, wpt); + data->left--; + } + } + + if (mmo_version > 0x11) { + mmo_end_of_route(data); + } } static void -mmo_read_CObjTrack(mmo_data_t *data) +mmo_read_CObjTrack(mmo_data_t* data) { #ifdef MMO_DBG - const char *sobj = "CObjTrack"; + const char* sobj = "CObjTrack"; #endif - int tp, ctp; - route_head *trk; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - trk = route_head_alloc(); - trk->rte_name = xstrdup(data->name); - track_add_head(trk); - - if (mmo_version >= 0x18) { - gbuint16 u16; - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - } - - tp = gbfgetint16(fin); - DBG((sobj, "track has %d point(s)\n", tp)); - - for (ctp = 0; ctp < tp; ctp++) { - waypoint *wpt; - char unk; - - wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude)); - unk = gbfgetc(fin); - DBG((sobj, "Unknown = 0x%02X (%d)\n", unk, unk)); - - wpt->creation_time = gbfgetint32(fin); - wpt->altitude = gbfgetflt(fin); - - if (unk != 0) { - gbuint16 ux; - ux = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (%d)\n", ux, ux)); - if (unk > 1) { - gbuint16 ux; - ux = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (%d)\n", ux, ux)); - } - } - track_add_wpt(trk, wpt); - } - - if (mmo_version > 0) { - gbuint32 u32; - - u32 = gbfgetuint32(fin); /* Min. update interval */ - DBG((sobj, "min. update interval = %d\n", u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "min. update distance = %d\n", u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "track partition interval = %d\n", u32 / 60)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "tick interval = %d\n", u32 / 60)); - trk->line_color.bbggrr = gbfgetuint32(fin); /* rgb color */ - trk->line_color.opacity = 255; - DBG((sobj, "color = 0x%06X\n", trk->line_color.bbggrr)); - } - - if (mmo_version >= 0x12) { - char u8; - - u8 = gbfgetc(fin); - DBG((sobj, "line width = %d - (since 0x12)\n", u8)); - u8 = gbfgetc(fin); - DBG((sobj, "line style = %d - (since 0x12)\n", u8)); - u8 = gbfgetc(fin); - DBG((sobj, "transparency = %d - (since 0x12)\n", u8)); - trk->line_color.opacity = 255 - (u8 * 51); - - if (mmo_version >= 0x16) { - char u8; - gbuint16 u16; - - u8 = gbfgetc(fin); - DBG((sobj, "unknown value = 0x%02X (since 0x16)\n", u8)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x16)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x16)\n", u16)); - } - } - - if (trk->rte_waypt_ct == 0) { - track_del_head(trk); - data->data = NULL; - } + int tp, ctp; + route_head* trk; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + trk = route_head_alloc(); + trk->rte_name = xstrdup(data->name); + track_add_head(trk); + + if (mmo_version >= 0x18) { + gbuint16 u16; + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + } + + tp = gbfgetint16(fin); + DBG((sobj, "track has %d point(s)\n", tp)); + + for (ctp = 0; ctp < tp; ctp++) { + waypoint* wpt; + char unk; + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude)); + unk = gbfgetc(fin); + DBG((sobj, "Unknown = 0x%02X (%d)\n", unk, unk)); + + wpt->creation_time = gbfgetint32(fin); + wpt->altitude = gbfgetflt(fin); + + if (unk != 0) { + gbuint16 ux; + ux = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (%d)\n", ux, ux)); + if (unk > 1) { + gbuint16 ux; + ux = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (%d)\n", ux, ux)); + } + } + track_add_wpt(trk, wpt); + } + + if (mmo_version > 0) { + gbuint32 u32; + + u32 = gbfgetuint32(fin); /* Min. update interval */ + DBG((sobj, "min. update interval = %d\n", u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "min. update distance = %d\n", u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "track partition interval = %d\n", u32 / 60)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "tick interval = %d\n", u32 / 60)); + trk->line_color.bbggrr = gbfgetuint32(fin); /* rgb color */ + trk->line_color.opacity = 255; + DBG((sobj, "color = 0x%06X\n", trk->line_color.bbggrr)); + } + + if (mmo_version >= 0x12) { + char u8; + + u8 = gbfgetc(fin); + DBG((sobj, "line width = %d - (since 0x12)\n", u8)); + u8 = gbfgetc(fin); + DBG((sobj, "line style = %d - (since 0x12)\n", u8)); + u8 = gbfgetc(fin); + DBG((sobj, "transparency = %d - (since 0x12)\n", u8)); + trk->line_color.opacity = 255 - (u8 * 51); + + if (mmo_version >= 0x16) { + gbuint16 u16; + char* text; + + // XXX ARB was u8 = gbfgetc(fin); but actually a string + text = mmo_readstr(); + DBG((sobj, "text = \"%s\"\n", text)); + xfree(text); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x16)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x16)\n", u16)); + } + } + + if (trk->rte_waypt_ct == 0) { + track_del_head(trk); + data->data = NULL; + } } static void -mmo_read_CObjText(mmo_data_t *data) +mmo_read_CObjText(mmo_data_t* data) { #ifdef MMO_DBG - const char *sobj = "CObjText"; + const char* sobj = "CObjText"; #endif - char buf[28]; - double lat, lon; - char *text, *font; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); + char buf[28]; + double lat, lon; + char* text, *font; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); - lat = gbfgetdbl(fin); - lon = gbfgetdbl(fin); - DBG((sobj, "coordinates = %f / %f\n", lat, lon)); + lat = gbfgetdbl(fin); + lon = gbfgetdbl(fin); + DBG((sobj, "coordinates = %f / %f\n", lat, lon)); - text = mmo_readstr(); - DBG((sobj, "text = \"%s\"\n", text)); - xfree(text); + text = mmo_readstr(); + DBG((sobj, "text = \"%s\"\n", text)); + xfree(text); - mmo_fillbuf(buf, 28, 1); + mmo_fillbuf(buf, 28, 1); - font = mmo_readstr(); - DBG((sobj, "font = \"%s\"\n", font)); - xfree(font); + font = mmo_readstr(); + DBG((sobj, "font = \"%s\"\n", font)); + xfree(font); - mmo_fillbuf(buf, 25, 1); + mmo_fillbuf(buf, 25, 1); } static void -mmo_read_CObjCurrentPosition(mmo_data_t *data) +mmo_read_CObjCurrentPosition(mmo_data_t* data) { #ifdef MMO_DBG - const char *sobj = "CObjCurrentPosition"; + const char* sobj = "CObjCurrentPosition"; #endif - char buf[24]; - double lat, lon; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - lat = gbfgetdbl(fin); - lon = gbfgetdbl(fin); - DBG((sobj, "coordinates = %f / %f\n", lat, lon)); - - mmo_fillbuf(buf, 24, 1); - - if (mmo_version >= 0x14) { - char *name; - - name = mmo_readstr(); - DBG((sobj, "name = \"%s\"\n", name)); - xfree(name); - mmo_fillbuf(buf, 13, 1); - } + char buf[24]; + double lat, lon; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + lat = gbfgetdbl(fin); + lon = gbfgetdbl(fin); + DBG((sobj, "coordinates = %f / %f\n", lat, lon)); + + mmo_fillbuf(buf, 24, 1); + if (mmo_version >= 0x18) { + mmo_fillbuf(buf, 8, 1); // XXX ARB read an extra 8 + } + + if (mmo_version >= 0x14) { + char* name; + + name = mmo_readstr(); + DBG((sobj, "name = \"%s\"\n", name)); + xfree(name); + // XXX ARB was just: mmo_fillbuf(buf, 13, 1); + // but actually it's string/long/string/long/long + (void) gbfgetuint32(fin); + name = mmo_readstr(); + DBG((sobj, "name = \"%s\"\n", name)); + xfree(name); + (void) gbfgetuint32(fin); + (void) gbfgetuint32(fin); + } } -static mmo_data_t * +static mmo_data_t* mmo_read_object(void) { - int objid; - mmo_data_t *data = NULL; - - // There are three cases: - // a new object of a type that has not occurred previously in this file; - // a new object; or - // a back reference to an object that appears earlier in the file. - - objid = gbfgetuint16(fin); - if (objid == 0xFFFF) { - DBG(("mmo_read_object", "Registering new object type\n")); - gbuint16 version; - char *sobj; - int len; - - objid = mmo_object_id++; - - version = gbfgetuint16(fin); - is_fatal(version != mmo_version, MYNAME ": Invalid version identifier!\n"); - - len = gbfgetint16(fin); - - sobj = xmalloc(len + 1); - sobj[len] = '\0'; - gbfread(sobj, len, 1, fin); - DBG(("mmo_read_object", "%s\n", sobj)); - - if (strcmp(sobj, "CObjIcons") == 0) ico_object_id = objid; - else if (strcmp(sobj, "CCategory") == 0) cat_object_id = objid; - else if (strcmp(sobj, "CObjWaypoint") == 0) wpt_object_id = objid; - else if (strcmp(sobj, "CObjRoute") == 0) rte_object_id = objid; - else if (strcmp(sobj, "CObjTrack") == 0) trk_object_id = objid; - else if (strcmp(sobj, "CObjCurrentPosition") == 0) pos_object_id = objid; - else if (strcmp(sobj, "CObjText") == 0) txt_object_id = objid; - else - fatal(MYNAME ": Unknown Object \"%s\"!\n", sobj); - xfree(sobj); - } - - DBG(("mmo_read_object", "objid = 0x%04X\n", objid)); - - if (objid & 0x8000) { - data = mmo_register_object(mmo_object_id++, NULL, 0); - data->name = mmo_readstr(); - - if (objid != cat_object_id) { - data->ctime = gbfgetuint32(fin); - data->mtime = gbfgetuint32(fin); - data->locked = gbfgetc(fin); - data->visible = gbfgetc(fin); - - gbuint32 obj_type; - obj_type = gbfgetuint32(fin); + int objid; + mmo_data_t* data = NULL; + + // There are three cases: + // a new object of a type that has not occurred previously in this file; + // a new object; or + // a back reference to an object that appears earlier in the file. + + objid = gbfgetuint16(fin); + if (objid == 0xFFFF) { + gbuint16 version; + char* sobj; + int len; + DBG(("mmo_read_object", "Registering new object type\n")); + + objid = mmo_object_id++; + + version = gbfgetuint16(fin); + is_fatal(version != mmo_version, MYNAME ": Invalid version identifier!\n"); + + len = gbfgetint16(fin); + + sobj = (char*) xmalloc(len + 1); + sobj[len] = '\0'; + gbfread(sobj, len, 1, fin); + DBG(("mmo_read_object", "%s\n", sobj)); + + if (strcmp(sobj, "CObjIcons") == 0) { + ico_object_id = objid; + } else if (strcmp(sobj, "CCategory") == 0) { + cat_object_id = objid; + } else if (strcmp(sobj, "CObjWaypoint") == 0) { + wpt_object_id = objid; + } else if (strcmp(sobj, "CObjRoute") == 0) { + rte_object_id = objid; + } else if (strcmp(sobj, "CObjTrack") == 0) { + trk_object_id = objid; + } else if (strcmp(sobj, "CObjCurrentPosition") == 0) { + pos_object_id = objid; + } else if (strcmp(sobj, "CObjText") == 0) { + txt_object_id = objid; + } else { + fatal(MYNAME ": Unknown Object \"%s\"!\n", sobj); + } + xfree(sobj); + } + + DBG(("mmo_read_object", "objid = 0x%04X\n", objid)); + + if (objid & 0x8000) { + data = mmo_register_object(mmo_object_id++, NULL, (gpsdata_type)0); + data->name = mmo_readstr(); + + if (objid != cat_object_id) { + gbuint32 obj_type; + data->ctime = gbfgetuint32(fin); + data->mtime = gbfgetuint32(fin); + data->locked = gbfgetc(fin); + data->visible = gbfgetc(fin); + + obj_type = gbfgetuint32(fin); #ifdef MMO_DBG - gbuint32 expected_type = 0xFFFFFFFF; - if (objid == ico_object_id) expected_type = obj_type_ico; - else if (objid == trk_object_id) expected_type = obj_type_trk; - else if (objid == wpt_object_id) expected_type = obj_type_wpt; - else if (objid == rte_object_id) expected_type = obj_type_rte; - else if (objid == txt_object_id) expected_type = obj_type_txt; - if (mmo_version >= 0x18) expected_type <<= 24; - DBG(("mmo_read_object", "object type = 0x%08X\n", obj_type)); - if (obj_type != expected_type) - DBG(("mmo_read_object", " expected 0x%08X\n", expected_type)); + gbuint32 expected_type = 0xFFFFFFFF; + if (objid == ico_object_id) { + expected_type = obj_type_ico; + } else if (objid == trk_object_id) { + expected_type = obj_type_trk; + } else if (objid == wpt_object_id) { + expected_type = obj_type_wpt; + } else if (objid == rte_object_id) { + expected_type = obj_type_rte; + } else if (objid == txt_object_id) { + expected_type = obj_type_txt; + } + if (mmo_version >= 0x18) { + expected_type <<= 24; + } + DBG(("mmo_read_object", "object type = 0x%08X\n", obj_type)); + if (obj_type != expected_type) { + DBG(("mmo_read_object", " expected 0x%08X\n", expected_type)); + } #endif - if (objid != ico_object_id) mmo_read_category(data); - DBG(("mmo_read_object", "Category : %s\n", - data->category ? data->category : "[No category]")); - } - - if (objid == cat_object_id) ; /* do nothing */ - else if (objid == ico_object_id) mmo_read_CObjIcons(data); - else if (objid == trk_object_id) { - data->type = trkdata; - mmo_read_CObjTrack(data); - } - else if (objid == wpt_object_id) { - data->type = wptdata; - mmo_read_CObjWaypoint(data); - } - else if (objid == rte_object_id) { - data->type = rtedata; - mmo_read_CObjRoute(data); - } - else if (objid == pos_object_id) mmo_read_CObjCurrentPosition(data); - else if (objid == txt_object_id) mmo_read_CObjText(data); - else - fatal(MYNAME ": Unregistered Object-ID 0x%04X\n", objid); - } - else data = mmo_get_object(objid); - - return data; + if (objid != ico_object_id) { + mmo_read_category(data); + } + DBG(("mmo_read_object", "Category : %s\n", + data->category ? data->category : "[No category]")); + } + + if (objid == cat_object_id) ; /* do nothing */ + else if (objid == ico_object_id) { + mmo_read_CObjIcons(data); + } else if (objid == trk_object_id) { + data->type = trkdata; + mmo_read_CObjTrack(data); + } else if (objid == wpt_object_id) { + data->type = wptdata; + mmo_read_CObjWaypoint(data); + } else if (objid == rte_object_id) { + data->type = rtedata; + mmo_read_CObjRoute(data); + } else if (objid == pos_object_id) { + mmo_read_CObjCurrentPosition(data); + } else if (objid == txt_object_id) { + mmo_read_CObjText(data); + } else { + fatal(MYNAME ": Unregistered Object-ID 0x%04X\n", objid); + } + } else { + data = mmo_get_object(objid); + } + + return data; } static void -mmo_finalize_rtept_cb(const waypoint *wptref) +mmo_finalize_rtept_cb(const waypoint* wptref) { - waypoint *wpt = (waypoint *)wptref; - - if ((wpt->shortname[0] == 1) && (wpt->latitude == 0) && (wpt->longitude == 0)) { - mmo_data_t *data; - waypoint *wpt2; - - sscanf(wpt->shortname + 1, "%p", &data); - wpt2 = (waypoint *)data->data; - - wpt->latitude = wpt2->latitude; - wpt->longitude = wpt2->longitude; - - xfree(wpt->shortname); - wpt->shortname = xstrdup(wpt2->shortname); - - if (wpt2->description) wpt->description = xstrdup(wpt2->description); - if (wpt2->notes) wpt->notes = xstrdup(wpt2->notes); - if (wpt2->url) wpt->notes = xstrdup(wpt2->url); - - wpt->proximity = wpt2->proximity; - wpt->wpt_flags.proximity = wpt2->wpt_flags.proximity; - - if (wpt2->icon_descr) { - wpt->icon_descr = xstrdup(wpt2->icon_descr); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - } - } + waypoint* wpt = (waypoint*)wptref; + + if ((wpt->shortname[0] == 1) && (wpt->latitude == 0) && (wpt->longitude == 0)) { + mmo_data_t* data; + waypoint* wpt2; + + sscanf(wpt->shortname + 1, "%p", &data); + wpt2 = (waypoint*)data->data; + + wpt->latitude = wpt2->latitude; + wpt->longitude = wpt2->longitude; + + xfree(wpt->shortname); + wpt->shortname = xstrdup(wpt2->shortname); + + if (wpt2->description) { + wpt->description = xstrdup(wpt2->description); + } + if (wpt2->notes) { + wpt->notes = xstrdup(wpt2->notes); + } + if (wpt2->url) { + wpt->notes = xstrdup(wpt2->url); + } + + wpt->proximity = wpt2->proximity; + wpt->wpt_flags.proximity = wpt2->wpt_flags.proximity; + + if (wpt2->icon_descr) { + wpt->icon_descr = xstrdup(wpt2->icon_descr); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + } + } } /******************************************************************************* @@ -910,38 +1032,38 @@ mmo_finalize_rtept_cb(const waypoint *wptref) *******************************************************************************/ static void -mmo_rd_init(const char *fname) +mmo_rd_init(const char* fname) { - int i; - - fin = gbfopen_le(fname, "rb", MYNAME); - - category_ids = avltree_init(0, MYNAME); - objects = avltree_init(0, MYNAME); - icons = avltree_init(0, MYNAME); - - ico_object_id = pos_object_id = txt_object_id = cat_object_id = 0; - wpt_object_id = rte_object_id = trk_object_id = 0; - - mmo_object_id = 0x8001; - - i = 0; - while (mmo_icon_value_table[i].icon) { - mmo_register_icon(mmo_icon_value_table[i].value, mmo_icon_value_table[i].icon); - i++; - } + int i; + + fin = gbfopen_le(fname, "rb", MYNAME); + + category_ids = avltree_init(0, MYNAME); + objects = avltree_init(0, MYNAME); + icons = avltree_init(0, MYNAME); + + ico_object_id = pos_object_id = txt_object_id = cat_object_id = 0; + wpt_object_id = rte_object_id = trk_object_id = 0; + + mmo_object_id = 0x8001; + + i = 0; + while (mmo_icon_value_table[i].icon) { + mmo_register_icon(mmo_icon_value_table[i].value, mmo_icon_value_table[i].icon); + i++; + } } -static void +static void mmo_rd_deinit(void) { - route_disp_session(curr_session(), NULL, NULL, mmo_finalize_rtept_cb); + route_disp_session(curr_session(), NULL, NULL, mmo_finalize_rtept_cb); - mmo_release_avltree(icons, 0); - mmo_release_avltree(category_ids, 0); - mmo_release_avltree(objects, 1); - gbfclose(fin); + mmo_release_avltree(icons, 0); + mmo_release_avltree(category_ids, 0); + mmo_release_avltree(objects, 1); + gbfclose(fin); } @@ -949,433 +1071,495 @@ static void mmo_read(void) { #ifdef MMO_DBG - const char *sobj = "main"; + const char* sobj = "main"; #endif - gbfile *fx; - int i; + gbfile* fx; + int i; - /* copy file to memory stream (needed for seek-ops and piped commands) */ + /* copy file to memory stream (needed for seek-ops and piped commands) */ - DBG(("main", "loading file \"%s\".\n", fin->name)); - - fx = gbfopen(NULL, "wb", MYNAME); - gbfcopyfrom(fx, fin, 0x7FFFFFFF); - gbfrewind(fx); - gbfclose(fin); - fin = fx; - - mmo_obj_ct = gbfgetuint16(fin); - DBG((sobj, "number of objects = %d\n", mmo_obj_ct)); - - i = gbfgetuint16(fin); - if (i != 0xFFFF) fatal(MYNAME ": Marker not equal to 0xFFFF!\n"); + DBG(("main", "loading file \"%s\".\n", fin->name)); - mmo_version = gbfgetuint16(fin); - DBG((sobj, "version = 0x%02X\n", mmo_version)); + fx = gbfopen(NULL, "wb", MYNAME); + gbfcopyfrom(fx, fin, 0x7FFFFFFF); + gbfrewind(fx); + gbfclose(fin); + fin = fx; - mmo_filemark = 0xFFFF0000UL | be_read16(&mmo_version); - DBG((sobj, "filemark = 0x%08X\n", mmo_filemark)); + mmo_obj_ct = gbfgetuint16(fin); + DBG((sobj, "number of objects = %d\n", mmo_obj_ct)); - gbfseek(fin, -4, SEEK_CUR); + i = gbfgetuint16(fin); + if (i != 0xFFFF) { + fatal(MYNAME ": Marker not equal to 0xFFFF!\n"); + } - while (! gbfeof(fin)) { /* main read loop */ + mmo_version = gbfgetuint16(fin); + DBG((sobj, "version = 0x%02X\n", mmo_version)); - (void) mmo_read_object(); + mmo_filemark = 0xFFFF0000UL | be_read16(&mmo_version); + DBG((sobj, "filemark = 0x%08X\n", mmo_filemark)); - } + gbfseek(fin, -4, SEEK_CUR); + + while (! gbfeof(fin)) { /* main read loop */ + + (void) mmo_read_object(); + + } #ifdef MMO_DBG - printf("\n" MYNAME ":---------------------------------------\n"); - printf(MYNAME ": EOF reached, nice!!!\n"); - printf(MYNAME ": =======================================\n\n"); -#endif + printf("\n" MYNAME ":---------------------------------------\n"); + printf(MYNAME ": EOF reached, nice!!!\n"); + printf(MYNAME ": =======================================\n\n"); +#endif } /**************************************************************************/ static void -mmo_register_category_names(const char *name) +mmo_register_category_names(const char* name) { - char key[16]; + char key[16]; - snprintf(key, sizeof(key), "%d", mmo_object_id); - avltree_insert(category_names, name, xstrdup(key)); + snprintf(key, sizeof(key), "%d", mmo_object_id); + avltree_insert(category_names, name, xstrdup(key)); } static void -mmo_writestr(const char *str) +mmo_writestr(const char* str) { - int len = strlen(str); - - if (len > 254) { - len = len & 0x7FFF; - gbfputc(0xFF, fout); - gbfputint16(len, fout); - } - else gbfputc(len, fout); - if (len) gbfwrite(str, len, 1, fout); + int ii, topbitset = 0; + int len = strlen(str); + + // see if there's any utf-8 multi-byte chars + for (ii = 0; ii < len; ii++) { + if (str[ii] & 0x80) { + topbitset = 1; + break; + } + } + // Old version can't handle utf-16 + // XXX ARB check which version number can, just guessed at 0x12 + if (mmo_version < 0x12) { + topbitset = 0; + } + + // XXX ARB need to convert UTF-8 into UTF-16 + if (topbitset) { + gbfputc(0xFF, fout); // means two-byte length follows + gbfputc(0xFE, fout); // means utf-16 little-endian string follows + gbfputc(0xFF, fout); // ditto + gbfputc(len, fout); + } else if (len > 254) { + len = len & 0x7FFF; + gbfputc(0xFF, fout); // means two-byte length follows + gbfputint16(len, fout); + } else { + gbfputc(len, fout); + } + if (len) { + if (topbitset) { + int utf16val; + int utf16len; + for (ii=0; iirte_waypt_ct > 0) mmo_obj_ct++; + if (rte->rte_waypt_ct > 0) { + mmo_obj_ct++; + } } static int -mmo_write_obj_mark(const char *sobj, const char *name) +mmo_write_obj_mark(const char* sobj, const char* name) { - char *key; - gbuint16 nr; - char buf[16]; - int res; - - if (avltree_find(mmobjects, sobj, (void *)&key)) { - nr = (unsigned)atoi(key); - gbfputuint16(nr, fout); - } - else { - mmo_object_id++; - snprintf(buf, sizeof(buf), "%u", mmo_object_id); - - DBG(("write", "object \"%s\", registered type \"%s\" (id = 0x%04X)\n", - name, sobj, mmo_object_id)); - - avltree_insert(mmobjects, sobj, xstrdup(buf)); - - gbfputuint32(mmo_filemark, fout); - gbfputuint16(strlen(sobj), fout); - gbfwrite(sobj, strlen(sobj), 1, fout); - } - - mmo_object_id++; - res = mmo_object_id; - mmo_writestr(name); - - return res; + char* key; + gbuint16 nr; + char buf[16]; + int res; + + if (avltree_find(mmobjects, sobj, (const void**)&key)) { + nr = (unsigned)atoi(key); + gbfputuint16(nr, fout); + } else { + mmo_object_id++; + snprintf(buf, sizeof(buf), "%u", mmo_object_id); + + DBG(("write", "object \"%s\", registered type \"%s\" (id = 0x%04X)\n", + name, sobj, mmo_object_id)); + + avltree_insert(mmobjects, sobj, xstrdup(buf)); + + gbfputuint32(mmo_filemark, fout); + gbfputuint16(strlen(sobj), fout); + gbfwrite(sobj, strlen(sobj), 1, fout); + } + + mmo_object_id++; + res = mmo_object_id; + mmo_writestr(name); + + return res; } static void -mmo_write_category(const char *sobj, const char *name) +mmo_write_category(const char* sobj, const char* name) { - char *key; - gbuint16 nr; - - if (avltree_find(category_names, name, (void *)&key)) { - nr = (unsigned)atoi(key); - gbfputuint16(nr & 0x7FFF, fout); - } - else { - mmo_write_obj_mark(sobj, name); - mmo_register_category_names(name); - } + char* key; + gbuint16 nr; + + if (avltree_find(category_names, name, (const void**)&key)) { + nr = (unsigned)atoi(key); + gbfputuint16(nr & 0x7FFF, fout); + } else { + mmo_write_obj_mark(sobj, name); + mmo_register_category_names(name); + } } static int -mmo_write_obj_head(const char *sobj, const char *name, const time_t ctime, - const gbuint32 obj_type) +mmo_write_obj_head(const char* sobj, const char* name, const time_t ctime, + const gbuint32 obj_type) { - int res; + int res; - res = mmo_write_obj_mark(sobj, name); - - gbfputuint32(ctime, fout); - gbfputuint32(ctime, fout); + res = mmo_write_obj_mark(sobj, name); - gbfputc(*opt_locked, fout); - gbfputc(*opt_visible, fout); + gbfputuint32(ctime, fout); + gbfputuint32(ctime, fout); - gbfputuint32(obj_type, fout); - - return res; + gbfputc(*opt_locked, fout); + gbfputc(*opt_visible, fout); + + gbfputuint32(obj_type, fout); + + return res; } static void -mmo_write_wpt_cb(const waypoint *wpt) +mmo_write_wpt_cb(const waypoint* wpt) { - char *str, *cx; - int objid; - time_t time; - int icon = 0; - mmo_data_t *data; - - time = wpt->creation_time; - if (time < 0) time = 0; - - if (mmo_datatype == trkdata) { - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputc(0, fout); - gbfputuint32(time, fout); - if (wpt->altitude != unknown_alt) - gbfputflt(wpt->altitude, fout); - else - gbfputflt(0, fout); - - return; - } - - DBG(("write", "waypoint \"%s\"\n", wpt->shortname ? wpt->shortname : "Mark")); - - objid = mmo_write_obj_head("CObjWaypoint", - (wpt->shortname && *wpt->shortname) ? wpt->shortname : "Mark", time, obj_type_wpt); - data = mmo_register_object(objid, wpt, wptdata); - data->refct = 1; - mmo_write_category("CCategory", (mmo_datatype == rtedata) ? "Waypoints" : "Marks"); - - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - - if (mmo_datatype == rtedata) { - int i = mmo_get_objid(mmo_rte); - gbfputuint16(1, fout); /* two extra bytes */ - gbfputuint16(i & 0x7FFF, fout); - } - else - gbfputuint16(0, fout); /* extra bytes */ - - if (wpt->url && *wpt->url) { - str = xstrdup("_FILE_ "); - str = xstrappend(str, wpt->url); - str = xstrappend(str, "\n"); - } - else str = xstrdup(""); - - cx = wpt->notes; - if (cx == NULL) cx = wpt->description; - if (cx != NULL) { - char *kml = NULL; - - if (strcmp(wpt->session->name, "kml") == 0) { - utf_string tmp; - - tmp.utfstring = cx; - tmp.is_html = 1; - cx = kml = strip_html(&tmp); - } - str = xstrappend(str, cx); - if (kml) xfree(kml); - } - mmo_writestr(str); - xfree(str); - - gbfputuint32(0x01, fout); - if WAYPT_HAS(wpt, proximity) gbfputflt((int) wpt->proximity, fout); - else gbfputflt(0, fout); - - if (wpt->icon_descr) { - int i = 0; - - while (mmo_icon_value_table[i].icon) { - if (case_ignore_strcmp(wpt->icon_descr, mmo_icon_value_table[i].icon) == 0) { - icon = mmo_icon_value_table[i].value; - break; - } - i++; - } - } - gbfputuint32(icon, fout); - - mmo_writestr(""); /* name on gps */ - gbfputuint32(0x00, fout); + char* str, *cx; + int objid; + time_t time; + int icon = 0; + mmo_data_t* data; + + time = wpt->creation_time; + if (time < 0) { + time = 0; + } + + if (mmo_datatype == trkdata) { + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputc(0, fout); + gbfputuint32(time, fout); + if (wpt->altitude != unknown_alt) { + gbfputflt(wpt->altitude, fout); + } else { + gbfputflt(0, fout); + } + + return; + } + + DBG(("write", "waypoint \"%s\"\n", wpt->shortname ? wpt->shortname : "Mark")); + + objid = mmo_write_obj_head("CObjWaypoint", + (wpt->shortname && *wpt->shortname) ? wpt->shortname : "Mark", time, obj_type_wpt); + data = mmo_register_object(objid, wpt, wptdata); + data->refct = 1; + mmo_write_category("CCategory", (mmo_datatype == rtedata) ? "Waypoints" : "Marks"); + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + + if (mmo_datatype == rtedata) { + int i = mmo_get_objid(mmo_rte); + gbfputuint16(1, fout); /* two extra bytes */ + gbfputuint16(i & 0x7FFF, fout); + } else { + gbfputuint16(0, fout); /* extra bytes */ + } + + if (wpt->url && *wpt->url) { + str = xstrdup("_FILE_ "); + str = xstrappend(str, wpt->url); + str = xstrappend(str, "\n"); + } else { + str = xstrdup(""); + } + + cx = wpt->notes; + if (cx == NULL) { + cx = wpt->description; + } + if (cx != NULL) { + char* kml = NULL; + + if (strcmp(wpt->session->name, "kml") == 0) { + utf_string tmp; + + tmp.utfstring = cx; + tmp.is_html = 1; + cx = kml = strip_html(&tmp); + } + str = xstrappend(str, cx); + if (kml) { + xfree(kml); + } + } + mmo_writestr(str); + xfree(str); + + gbfputuint32(0x01, fout); + if WAYPT_HAS(wpt, proximity) { + gbfputflt((int) wpt->proximity, fout); + } else { + gbfputflt(0, fout); + } + + if (wpt->icon_descr) { + int i = 0; + + while (mmo_icon_value_table[i].icon) { + if (case_ignore_strcmp(wpt->icon_descr, mmo_icon_value_table[i].icon) == 0) { + icon = mmo_icon_value_table[i].value; + break; + } + i++; + } + } + gbfputuint32(icon, fout); + + mmo_writestr(""); /* name on gps */ + gbfputuint32(0x00, fout); } static void -mmo_write_rte_head_cb(const route_head *rte) +mmo_write_rte_head_cb(const route_head* rte) { - int objid; - queue *elem, *tmp; - time_t time = 0x7FFFFFFF; - - if (rte->rte_waypt_ct <= 0) return; - - mmo_rte = (route_head *)rte; - - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - - if ((wpt->creation_time > 0) && (wpt->creation_time < time)) - time = wpt->creation_time; - } - if (time == 0x7FFFFFFF) time = gpsbabel_time; - - objid = mmo_write_obj_head("CObjRoute", - (rte->rte_name && *rte->rte_name) ? rte->rte_name : "Route", time, obj_type_rte); - mmo_register_object(objid, rte, rtedata); - mmo_write_category("CCategory", "Route"); - gbfputc(0, fout); /* unknown */ - gbfputuint16(rte->rte_waypt_ct, fout); + int objid; + queue* elem, *tmp; + time_t time = 0x7FFFFFFF; + + if (rte->rte_waypt_ct <= 0) { + return; + } + + mmo_rte = (route_head*)rte; + + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + waypoint* wpt = (waypoint*)elem; + + if ((wpt->creation_time > 0) && (wpt->creation_time < time)) { + time = wpt->creation_time; + } + } + if (time == 0x7FFFFFFF) { + time = gpsbabel_time; + } + + objid = mmo_write_obj_head("CObjRoute", + (rte->rte_name && *rte->rte_name) ? rte->rte_name : "Route", time, obj_type_rte); + mmo_register_object(objid, rte, rtedata); + mmo_write_category("CCategory", "Route"); + gbfputc(0, fout); /* unknown */ + gbfputuint16(rte->rte_waypt_ct, fout); } static void -mmo_write_rte_tail_cb(const route_head *rte) +mmo_write_rte_tail_cb(const route_head* rte) { - queue *elem, *tmp; - - if (rte->rte_waypt_ct <= 0) return; - - DBG(("write", "route with %d point(s).\n", rte->rte_waypt_ct)); - - if (mmo_version >= 0x12) { - if (rte->line_color.bbggrr < 0) { - gbfputuint32(0xFF, fout); /* color; default red */ - gbfputc(0x01, fout); /* Line width "normal" */ - gbfputc(0x00, fout); /* Line style "solid"*/ - gbfputc(0x00, fout); /* Transparency "Opaque" */ - } - else { - gbfputuint32(rte->line_color.bbggrr, fout); /* color */ - gbfputc(0x01, fout); /* Line width "normal" */ - gbfputc(0x00, fout); /* Line style "solid"*/ - gbfputc((255 - rte->line_color.opacity) / 51, fout); /* Transparency "Opaque" */ - } - } - - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - int objid = mmo_get_objid(wpt); - gbfputuint16(objid & 0x7FFF, fout); - } + queue* elem, *tmp; + + if (rte->rte_waypt_ct <= 0) { + return; + } + + DBG(("write", "route with %d point(s).\n", rte->rte_waypt_ct)); + + if (mmo_version >= 0x12) { + if (rte->line_color.bbggrr < 0) { + gbfputuint32(0xFF, fout); /* color; default red */ + gbfputc(0x01, fout); /* Line width "normal" */ + gbfputc(0x00, fout); /* Line style "solid"*/ + gbfputc(0x00, fout); /* Transparency "Opaque" */ + } else { + gbfputuint32(rte->line_color.bbggrr, fout); /* color */ + gbfputc(0x01, fout); /* Line width "normal" */ + gbfputc(0x00, fout); /* Line style "solid"*/ + gbfputc((255 - rte->line_color.opacity) / 51, fout); /* Transparency "Opaque" */ + } + } + + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + waypoint* wpt = (waypoint*)elem; + int objid = mmo_get_objid(wpt); + gbfputuint16(objid & 0x7FFF, fout); + } } static void -mmo_write_trk_head_cb(const route_head *trk) +mmo_write_trk_head_cb(const route_head* trk) { - int objid; - - if (trk->rte_waypt_ct <= 0) return; - - objid = mmo_write_obj_head("CObjTrack", - (trk->rte_name && *trk->rte_name) ? trk->rte_name : "Track", gpsbabel_time, obj_type_trk); - mmo_write_category("CCategory", "Track"); - gbfputuint16(trk->rte_waypt_ct, fout); - - mmo_register_object(objid, trk, trkdata); + int objid; + + if (trk->rte_waypt_ct <= 0) { + return; + } + + objid = mmo_write_obj_head("CObjTrack", + (trk->rte_name && *trk->rte_name) ? trk->rte_name : "Track", gpsbabel_time, obj_type_trk); + mmo_write_category("CCategory", "Track"); + gbfputuint16(trk->rte_waypt_ct, fout); + + mmo_register_object(objid, trk, trkdata); } static void -mmo_write_trk_tail_cb(const route_head *trk) +mmo_write_trk_tail_cb(const route_head* trk) { - if (trk->rte_waypt_ct <= 0) return; - - gbfputuint32(0x0A, fout); /* Min. update interval */ - gbfputflt(0, fout); - gbfputflt(0, fout); - gbfputuint32(0x0F, fout); /* Min. update distance */ - gbfputuint32(0xE10, fout); /* Track partition interval */ - gbfputuint32(0x00, fout); /* ??? */ - gbfputuint32(0x12C, fout); - - if (trk->line_color.bbggrr < 0) { - gbfputuint32(0xFF0000, fout); /* color; default blue */ - if (mmo_version >= 0x12) { - gbfputc(0x01, fout); /* Line width "normal" */ - gbfputc(0x00, fout); /* Line style "solid"*/ - gbfputc(0x00, fout); /* Transparency "Opaque" */ - } - } - else { - gbfputuint32(trk->line_color.bbggrr, fout); /* color */ - if (mmo_version >= 0x12) { - gbfputc(0x01, fout); /* Line width "normal" */ - gbfputc(0x00, fout); /* Line style "solid"*/ - gbfputc((255 - trk->line_color.opacity) / 51, fout); /* Transparency "Opaque" */ - } - } + if (trk->rte_waypt_ct <= 0) { + return; + } + + gbfputuint32(0x0A, fout); /* Min. update interval */ + gbfputflt(0, fout); + gbfputflt(0, fout); + gbfputuint32(0x0F, fout); /* Min. update distance */ + gbfputuint32(0xE10, fout); /* Track partition interval */ + gbfputuint32(0x00, fout); /* ??? */ + gbfputuint32(0x12C, fout); + + if (trk->line_color.bbggrr < 0) { + gbfputuint32(0xFF0000, fout); /* color; default blue */ + if (mmo_version >= 0x12) { + gbfputc(0x01, fout); /* Line width "normal" */ + gbfputc(0x00, fout); /* Line style "solid"*/ + gbfputc(0x00, fout); /* Transparency "Opaque" */ + } + } else { + gbfputuint32(trk->line_color.bbggrr, fout); /* color */ + if (mmo_version >= 0x12) { + gbfputc(0x01, fout); /* Line width "normal" */ + gbfputc(0x00, fout); /* Line style "solid"*/ + gbfputc((255 - trk->line_color.opacity) / 51, fout); /* Transparency "Opaque" */ + } + } } /**************************************************************************/ static void -mmo_wr_init(const char *fname) +mmo_wr_init(const char* fname) { - fout = gbfopen_le(fname, "wb", MYNAME); - - objects = avltree_init(0, MYNAME); - mmobjects = avltree_init(0, MYNAME); - category_names = avltree_init(0, MYNAME); - - mmo_object_id = 0x8000; - mmo_obj_ct = 1; /* ObjIcons always present */ - mmo_version = 0x12; /* by default we write as version 0x12 */ - if (opt_version) { - while (isspace(*opt_version)) opt_version++; - errno = 0; - mmo_version = strtol(opt_version, NULL, 0); - if (errno || ((mmo_version != 0x11) && (mmo_version != 0x12))) { - fatal(MYNAME ": Unsupported version identifier (%s)!\n", opt_version); - } - } - DBG(("write", "version = 0x%02X\n", mmo_version)); - mmo_filemark = 0xFFFFUL | (mmo_version << 16); + fout = gbfopen_le(fname, "wb", MYNAME); + + objects = avltree_init(0, MYNAME); + mmobjects = avltree_init(0, MYNAME); + category_names = avltree_init(0, MYNAME); + + mmo_object_id = 0x8000; + mmo_obj_ct = 1; /* ObjIcons always present */ + mmo_version = 0x12; /* by default we write as version 0x12 */ + if (opt_version) { + while (isspace(*opt_version)) { + opt_version++; + } + errno = 0; + mmo_version = strtol(opt_version, NULL, 0); + if (errno || ((mmo_version != 0x11) && (mmo_version != 0x12))) { + fatal(MYNAME ": Unsupported version identifier (%s)!\n", opt_version); + } + } + DBG(("write", "version = 0x%02X\n", mmo_version)); + mmo_filemark = 0xFFFFUL | (mmo_version << 16); } static void mmo_wr_deinit(void) { - mmo_release_avltree(mmobjects, 0); - mmo_release_avltree(category_names, 0); - mmo_release_avltree(objects, 1); + mmo_release_avltree(mmobjects, 0); + mmo_release_avltree(category_names, 0); + mmo_release_avltree(objects, 1); - gbfclose(fout); + gbfclose(fout); } static void mmo_write(void) { - int i; - - /* find out number of objects we have to write */ - waypt_disp_all(mmo_enum_waypt_cb); - route_disp_all(mmo_enum_route_cb, NULL, mmo_enum_waypt_cb); - track_disp_all(mmo_enum_route_cb, NULL, NULL); - - gbfputuint16(mmo_obj_ct, fout); - - mmo_write_obj_head("CObjIcons", "Unnamed object", gpsbabel_time, obj_type_ico); - for (i = 0; i < 5; i++) gbfputuint16(0, fout); - - mmo_datatype = wptdata; - waypt_disp_all(mmo_write_wpt_cb); - mmo_datatype = rtedata; - route_disp_all(mmo_write_rte_head_cb, mmo_write_rte_tail_cb, mmo_write_wpt_cb); - mmo_datatype = trkdata; - track_disp_all(mmo_write_trk_head_cb, mmo_write_trk_tail_cb, mmo_write_wpt_cb); + int i; + + /* find out number of objects we have to write */ + waypt_disp_all(mmo_enum_waypt_cb); + route_disp_all(mmo_enum_route_cb, NULL, mmo_enum_waypt_cb); + track_disp_all(mmo_enum_route_cb, NULL, NULL); + + gbfputuint16(mmo_obj_ct, fout); + + mmo_write_obj_head("CObjIcons", "Unnamed object", gpsbabel_time, obj_type_ico); + for (i = 0; i < 5; i++) { + gbfputuint16(0, fout); + } + + mmo_datatype = wptdata; + waypt_disp_all(mmo_write_wpt_cb); + mmo_datatype = rtedata; + route_disp_all(mmo_write_rte_head_cb, mmo_write_rte_tail_cb, mmo_write_wpt_cb); + mmo_datatype = trkdata; + track_disp_all(mmo_write_trk_head_cb, mmo_write_trk_tail_cb, mmo_write_wpt_cb); } /**************************************************************************/ ff_vecs_t mmo_vecs = { - ff_type_file, - FF_CAP_RW_ALL, /* read and write waypoints, tracks and routes*/ - mmo_rd_init, - mmo_wr_init, - mmo_rd_deinit, - mmo_wr_deinit, - mmo_read, - mmo_write, - NULL, - mmo_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + FF_CAP_RW_ALL, /* read and write waypoints, tracks and routes*/ + mmo_rd_init, + mmo_wr_init, + mmo_rd_deinit, + mmo_wr_deinit, + mmo_read, + mmo_write, + NULL, + mmo_args, + CET_CHARSET_MS_ANSI, 0 }; diff --git a/gpsbabel/msroute.c b/gpsbabel/msroute.c index 83732fefd..6c5cbd590 100644 --- a/gpsbabel/msroute.c +++ b/gpsbabel/msroute.c @@ -1,7 +1,7 @@ -/* +/* Support for Microsoft AutoRoute 2002 ".axe" files, - + Copyright (C) 2005,2007,2008 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -28,34 +28,32 @@ #undef OLE_DEBUG -static gbfile *fin; +static gbfile* fin; -static arglist_t msroute_args[] = -{ - ARG_TERMINATOR +static arglist_t msroute_args[] = { + ARG_TERMINATOR }; /* MS-AutoRoute structures */ -typedef struct msroute_head_s -{ - gbuint32 U1; /* 58/02/00/00 */ - char masm[4]; /* "MASM " */ - gbuint32 U2; - gbuint32 U3; - gbint32 waypts; - gbuint32 U5; - gbuint32 U6; - gbuint32 U7; - gbuint32 U8; - gbuint32 U9; - gbuint32 U10; - gbuint32 U11; - gbuint32 U12; - gbuint32 U13; - gbuint32 U14; - gbuint32 U15; - gbuint32 U16; +typedef struct msroute_head_s { + gbuint32 U1; /* 58/02/00/00 */ + char masm[4]; /* "MASM " */ + gbuint32 U2; + gbuint32 U3; + gbint32 waypts; + gbuint32 U5; + gbuint32 U6; + gbuint32 U7; + gbuint32 U8; + gbuint32 U9; + gbuint32 U10; + gbuint32 U11; + gbuint32 U12; + gbuint32 U13; + gbuint32 U14; + gbuint32 U15; + gbuint32 U16; // short U17; // char U18; } msroute_head_t; @@ -69,66 +67,63 @@ typedef struct msroute_head_s #define BLOCKS(a, b) (((a) + (b) - 1) / (b)) -static const unsigned char ole_magic[8] = -{ - 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 +static const unsigned char ole_magic[8] = { + 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }; -/* +/* The ole implementation looks like a FAT filesystem. Thatswhy i use in code fat1 as item for the "big blocks" or bbd and fat2 for "small blocks" (sbd). - + Remarks: * in the moment ole_size1 and sector_sz represents the same value * in OLE_DEBUG mode: successfully tested with 64MB++ standard MS doc's (PowerPoint, Word) */ -typedef struct ole_head_s -{ - char magic[8]; - char clsid[16]; - gbuint16 rev; /* offset 0x18 */ - gbuint16 ver; /* offset 0x1a */ - gbint16 byte_order; /* offset 0x1c */ - gbuint16 fat1_size_shift; /* offset 0x1e */ - gbuint16 fat2_size_shift; /* offset 0x20 */ - gbuint16 U7; /* offset 0x22 */ - gbuint32 U8; /* offset 0x24 */ - gbuint32 U9; /* offset 0x28 */ - gbint32 fat1_blocks; /* offset 0x2c */ - gbint32 prop_start; /* offset 0x30 */ - gbuint32 U12; /* offset 0x34 */ - gbuint32 fat1_min_size; /* offset 0x38 */ - gbint32 fat2_start; /* offset 0x3c */ - gbint32 fat2_blocks; /* offset 0x40 */ - gbint32 fat1_extra_start; /* offset 0x44 */ - gbint32 fat1_extra_ct; /* offset 0x48 */ - gbint32 fat1[OLE_HEAD_FAT1_CT]; /* offset 0x4c */ +typedef struct ole_head_s { + char magic[8]; + char clsid[16]; + gbuint16 rev; /* offset 0x18 */ + gbuint16 ver; /* offset 0x1a */ + gbint16 byte_order; /* offset 0x1c */ + gbuint16 fat1_size_shift; /* offset 0x1e */ + gbuint16 fat2_size_shift; /* offset 0x20 */ + gbuint16 U7; /* offset 0x22 */ + gbuint32 U8; /* offset 0x24 */ + gbuint32 U9; /* offset 0x28 */ + gbint32 fat1_blocks; /* offset 0x2c */ + gbint32 prop_start; /* offset 0x30 */ + gbuint32 U12; /* offset 0x34 */ + gbuint32 fat1_min_size; /* offset 0x38 */ + gbint32 fat2_start; /* offset 0x3c */ + gbint32 fat2_blocks; /* offset 0x40 */ + gbint32 fat1_extra_start; /* offset 0x44 */ + gbint32 fat1_extra_ct; /* offset 0x48 */ + gbint32 fat1[OLE_HEAD_FAT1_CT]; /* offset 0x4c */ } ole_head_t; -typedef struct ole_prop_s -{ - gbuint16 name[32]; - gbuint16 name_sz; /* offset 0x40 */ - char ole_typ; /* offset 0x42 */ - char U1; /* offset 0x43 */ - gbuint32 previous; /* offset 0x44 */ - gbuint32 next; /* offset 0x48 */ - gbuint32 dir; /* offset 0x4c */ - gbuint32 U5; /* offset 0x50 */ - gbuint32 U6; /* offset 0x54 */ - gbuint32 U7; /* offset 0x58 */ - gbuint32 U8; /* offset 0x5c */ - gbuint32 U9; /* offset 0x60 */ - gbuint32 U10; /* offset 0x64 */ - gbuint32 U11; /* offset 0x68 */ - gbuint32 U12; /* offset 0x6c */ - gbuint32 U13; /* offset 0x70 */ - gbint32 first_sector; /* offset 0x74 */ - gbint32 data_sz; /* offset 0x78 */ - gbuint32 U16; /* offset 0x7c */ +typedef struct ole_prop_s { + gbuint16 name[32]; + gbuint16 name_sz; /* offset 0x40 */ + char ole_typ; /* offset 0x42 */ + char U1; /* offset 0x43 */ + gbuint32 previous; /* offset 0x44 */ + gbuint32 next; /* offset 0x48 */ + gbuint32 dir; /* offset 0x4c */ + gbuint32 U5; /* offset 0x50 */ + gbuint32 U6; /* offset 0x54 */ + gbuint32 U7; /* offset 0x58 */ + gbuint32 U8; /* offset 0x5c */ + gbuint32 U9; /* offset 0x60 */ + gbuint32 U10; /* offset 0x64 */ + gbuint32 U11; /* offset 0x68 */ + gbuint32 U12; /* offset 0x6c */ + gbuint32 U13; /* offset 0x70 */ + gbint32 first_sector; /* offset 0x74 */ + gbint32 data_sz; /* offset 0x78 */ + gbuint32 U16; /* offset 0x7c */ } ole_prop_t; #define DIR_ITEM_SIZE sizeof(ole_prop_t) @@ -142,162 +137,162 @@ static int sector_sz = 512; #define max(a,b) ((a) > (b)) ? (a) : (b) #endif -static gbint32 *ole_fat1 = NULL; -static gbint32 *ole_fat2 = NULL; +static gbint32* ole_fat1 = NULL; +static gbint32* ole_fat2 = NULL; static int ole_fat1_ct; static int ole_fat2_ct; static int ole_size1; static int ole_size2; static int ole_size1_min = 4096; -static ole_prop_t *ole_dir = NULL; +static ole_prop_t* ole_dir = NULL; static int ole_dir_ct; -static ole_prop_t *ole_root = NULL; -static char **ole_root_sec = NULL; +static ole_prop_t* ole_root = NULL; +static char** ole_root_sec = NULL; static int ole_root_sec_ct; /* local helpers */ static void -le_read32_buff(int *buff, const int count) +le_read32_buff(int* buff, const int count) { - int i; - for (i = 0; i < count; i++) - buff[i] = le_read32(&buff[i]); + int i; + for (i = 0; i < count; i++) { + buff[i] = le_read32(&buff[i]); + } } /* simple OLE file reader */ static void -ole_read_sector(const int sector, void *target, const char full) +ole_read_sector(const int sector, void* target, const char full) { - int res; - - res = gbfseek(fin, (sector + 1) * sector_sz, SEEK_SET); - is_fatal((res != 0), MYNAME ": Could not seek file to sector %d!", sector + 1); - res = gbfread(target, 1, sector_sz, fin); - is_fatal( - ((res < 0) || (full && (res < sector_sz))), - MYNAME ": Read error (%d, sector %d) on file \"%s\"!", res, sector, fin->name); + int res; + + res = gbfseek(fin, (sector + 1) * sector_sz, SEEK_SET); + is_fatal((res != 0), MYNAME ": Could not seek file to sector %d!", sector + 1); + res = gbfread(target, 1, sector_sz, fin); + is_fatal( + ((res < 0) || (full && (res < sector_sz))), + MYNAME ": Read error (%d, sector %d) on file \"%s\"!", res, sector, fin->name); } -static ole_prop_t * -ole_find_property(const char *property) +static ole_prop_t* +ole_find_property(const char* property) { - int i; - - for (i = 0; i < ole_dir_ct; i++) - { - int len, test; - char *str; - ole_prop_t *item; - - item = &ole_dir[i]; - if ((item->ole_typ != 1) && (item->ole_typ != 2) && (item->ole_typ != 5)) continue; - if ((item->data_sz <= 0) || (item->name_sz <= 0)) continue; - - len = min(OLE_MAX_NAME_LENGTH, item->name_sz / 2); - str = cet_str_uni_to_utf8((short *)&item->name, len); - test = case_ignore_strcmp(str, property); - xfree(str); - - if (test == 0) return item; - } - is_fatal((1), MYNAME ": \"%s\" not in property catalog!", property); - return 0; + int i; + + for (i = 0; i < ole_dir_ct; i++) { + int len, test; + char* str; + ole_prop_t* item; + + item = &ole_dir[i]; + if ((item->ole_typ != 1) && (item->ole_typ != 2) && (item->ole_typ != 5)) { + continue; + } + if ((item->data_sz <= 0) || (item->name_sz <= 0)) { + continue; + } + + len = min(OLE_MAX_NAME_LENGTH, item->name_sz / 2); + str = cet_str_uni_to_utf8((short*)&item->name, len); + test = case_ignore_strcmp(str, property); + xfree(str); + + if (test == 0) { + return item; + } + } + is_fatal((1), MYNAME ": \"%s\" not in property catalog!", property); + return 0; } -static char * -ole_read_stream(const ole_prop_t *property) +static char* +ole_read_stream(const ole_prop_t* property) { - const char *action = "ole_read_stream"; - int len, sector, big, blocksize, offs, left; - int i; - int *fat; - char *buff; - - len = property->data_sz; - - if (len >= ole_size1_min) - { - big = 1; - blocksize = ole_size1; - fat = ole_fat1; - } - else - { - big = 0; - blocksize = ole_size2; - fat = ole_fat2; - } - - offs = 0; - left = len; - sector = property->first_sector; - - i = ((len + blocksize - 1) / blocksize) * blocksize; - buff = xmalloc(i); /* blocksize aligned */ - - if (big != 0) - { - while (left > 0) - { - int bytes = (left <= blocksize) ? left : blocksize; - ole_read_sector(sector, buff + offs, (bytes >= sector_sz)); - left -= bytes; - offs += bytes; - if (left > 0) - { - sector = fat[sector]; - is_fatal((sector < 0), MYNAME ": Broken stream (%s)!", action); - } - } - } - else - { - int chain = sector; - int blocks = (len + blocksize - 1) / blocksize; - int blocks_per_sector = sector_sz / blocksize; - - offs = 0; - - while (blocks-- > 0) - { - char *temp; - int block_offs; - - is_fatal((chain < 0), MYNAME ": Broken stream (%s)!", action); - - sector = chain / blocks_per_sector; - is_fatal((sector >= ole_root_sec_ct), MYNAME ": Broken stream (%s)!", action); - - temp = ole_root_sec[sector]; - is_fatal((temp == NULL), MYNAME ": Broken stream (%s)!", action); - - block_offs = (chain % blocks_per_sector) * blocksize; - - memcpy(buff + offs, temp + block_offs, blocksize); - - offs += blocksize; - chain = fat[chain]; - } - } - return buff; + const char* action = "ole_read_stream"; + int len, sector, big, blocksize, offs, left; + int i; + int* fat; + char* buff; + + len = property->data_sz; + + if (len >= ole_size1_min) { + big = 1; + blocksize = ole_size1; + fat = ole_fat1; + } else { + big = 0; + blocksize = ole_size2; + fat = ole_fat2; + } + + offs = 0; + left = len; + sector = property->first_sector; + + i = ((len + blocksize - 1) / blocksize) * blocksize; + buff = (char*) xmalloc(i); /* blocksize aligned */ + + if (big != 0) { + while (left > 0) { + int bytes = (left <= blocksize) ? left : blocksize; + ole_read_sector(sector, buff + offs, (bytes >= sector_sz)); + left -= bytes; + offs += bytes; + if (left > 0) { + sector = fat[sector]; + is_fatal((sector < 0), MYNAME ": Broken stream (%s)!", action); + } + } + } else { + int chain = sector; + int blocks = (len + blocksize - 1) / blocksize; + int blocks_per_sector = sector_sz / blocksize; + + offs = 0; + + while (blocks-- > 0) { + char* temp; + int block_offs; + + is_fatal((chain < 0), MYNAME ": Broken stream (%s)!", action); + + sector = chain / blocks_per_sector; + is_fatal((sector >= ole_root_sec_ct), MYNAME ": Broken stream (%s)!", action); + + temp = ole_root_sec[sector]; + is_fatal((temp == NULL), MYNAME ": Broken stream (%s)!", action); + + block_offs = (chain % blocks_per_sector) * blocksize; + + memcpy(buff + offs, temp + block_offs, blocksize); + + offs += blocksize; + chain = fat[chain]; + } + } + return buff; } -static char * -ole_read_property_stream(const char *property_name, int *data_sz) +static char* +ole_read_property_stream(const char* property_name, int* data_sz) { - ole_prop_t *property; - char *result; - - if ((property = ole_find_property(property_name)) == NULL) return NULL; - - result = ole_read_stream(property); - if ((result != NULL) && (data_sz != NULL)) - *data_sz = property->data_sz; - - return result; + ole_prop_t* property; + char* result; + + if ((property = ole_find_property(property_name)) == NULL) { + return NULL; + } + + result = ole_read_stream(property); + if ((result != NULL) && (data_sz != NULL)) { + *data_sz = property->data_sz; + } + + return result; } #ifdef OLE_DEBUG @@ -305,260 +300,260 @@ ole_read_property_stream(const char *property_name, int *data_sz) static void ole_test_properties() { - int i; - - for (i = 0; i < ole_dir_ct; i++) - { - char *temp; - char name[OLE_MAX_NAME_LENGTH + 1]; - ole_prop_t *p = &ole_dir[i]; - - if ((p->ole_typ != 1) && (p->ole_typ != 2) && (p->ole_typ != 5)) continue; - if ((p->data_sz <= 0) || (p->name_sz <= 0)) continue; - - temp = cet_str_uni_to_utf8(&p->name, min(p->name_sz / 2, OLE_MAX_NAME_LENGTH)); - strncpy(name, temp, sizeof(name)); - xfree(temp); - - printf(MYNAME ": ole_test_properties for \"%s\" (%d bytes):", name, p->data_sz); - - if ((case_ignore_strcmp(name, "Root Entry") == 0) || - (p->data_sz < ole_size1_min)) - { - printf(" skipped...\n"); - continue; - } - else - { - int sector = p->first_sector; - int data_sz = p->data_sz; - int block_size = ole_size1; /* sector_sz */ - - printf("\n"); - - while ((data_sz > 0) && (sector >= 0)) - { - int bytes = (data_sz > block_size) ? block_size : data_sz; - int prev = sector; - - data_sz -= bytes; - sector = ole_fat1[sector]; - if (sector == -3) - { - printf(MYNAME ": special block at %d\n", prev); - if ((prev + 2) < ole_fat1_ct) - sector = ole_fat1[prev + 1]; - printf(MYNAME "-new sector: %d\n", sector); - } - } - is_fatal((data_sz != 0), MYNAME ": Error in fat1 chain, sector = %d, %d bytes (=%d blocks) left!", - sector, data_sz, BLOCKS(data_sz, block_size)); - } - } + int i; + + for (i = 0; i < ole_dir_ct; i++) { + char* temp; + char name[OLE_MAX_NAME_LENGTH + 1]; + ole_prop_t* p = &ole_dir[i]; + + if ((p->ole_typ != 1) && (p->ole_typ != 2) && (p->ole_typ != 5)) { + continue; + } + if ((p->data_sz <= 0) || (p->name_sz <= 0)) { + continue; + } + + temp = cet_str_uni_to_utf8(&p->name, min(p->name_sz / 2, OLE_MAX_NAME_LENGTH)); + strncpy(name, temp, sizeof(name)); + xfree(temp); + + printf(MYNAME ": ole_test_properties for \"%s\" (%d bytes):", name, p->data_sz); + + if ((case_ignore_strcmp(name, "Root Entry") == 0) || + (p->data_sz < ole_size1_min)) { + printf(" skipped...\n"); + continue; + } else { + int sector = p->first_sector; + int data_sz = p->data_sz; + int block_size = ole_size1; /* sector_sz */ + + printf("\n"); + + while ((data_sz > 0) && (sector >= 0)) { + int bytes = (data_sz > block_size) ? block_size : data_sz; + int prev = sector; + + data_sz -= bytes; + sector = ole_fat1[sector]; + if (sector == -3) { + printf(MYNAME ": special block at %d\n", prev); + if ((prev + 2) < ole_fat1_ct) { + sector = ole_fat1[prev + 1]; + } + printf(MYNAME "-new sector: %d\n", sector); + } + } + is_fatal((data_sz != 0), MYNAME ": Error in fat1 chain, sector = %d, %d bytes (=%d blocks) left!", + sector, data_sz, BLOCKS(data_sz, block_size)); + } + } } #endif static void ole_init(void) { - ole_head_t head; - int i, i_offs, sector, count, left; - int fat1_extra[128]; - - ole_fat1 = NULL; - ole_fat2 = NULL; - - sector_sz = 512; /* fixed for the moment */ - - is_fatal((sizeof(head) != sector_sz), - MYNAME ": (!) internal error - invalid header size (%lu)!", - (unsigned long) sizeof(head)); - - memset(&head, 0, sizeof(head)); - gbfread(&head, sizeof(head), 1, fin); - - is_fatal((strncmp(head.magic, (char *) ole_magic, sizeof(ole_magic)) != 0), MYNAME ": No MS document."); - - head.rev = le_read16(&head.rev); - head.ver = le_read16(&head.ver); - head.byte_order = le_read16(&head.byte_order); - head.fat1_size_shift = le_read16(&head.fat1_size_shift); - head.fat2_size_shift = le_read16(&head.fat2_size_shift); - head.fat1_blocks = le_read32(&head.fat1_blocks); - head.prop_start = le_read32(&head.prop_start); - head.fat1_min_size = le_read32(&head.fat1_min_size); - head.fat2_start = le_read32(&head.fat2_start); - head.fat2_blocks = le_read32(&head.fat2_blocks); - head.fat1_extra_start = le_read32(&head.fat1_extra_start); - head.fat1_extra_ct = le_read32(&head.fat1_extra_ct); - le_read32_buff(&head.fat1[0], OLE_HEAD_FAT1_CT); - - ole_size1 = (1 << head.fat1_size_shift); - ole_size2 = (1 << head.fat2_size_shift); - ole_size1_min = head.fat1_min_size; + ole_head_t head; + int i, i_offs, sector, count, left; + int fat1_extra[128]; + + ole_fat1 = NULL; + ole_fat2 = NULL; + + sector_sz = 512; /* fixed for the moment */ + + is_fatal((sizeof(head) != sector_sz), + MYNAME ": (!) internal error - invalid header size (%lu)!", + (unsigned long) sizeof(head)); + + memset(&head, 0, sizeof(head)); + gbfread(&head, sizeof(head), 1, fin); + + is_fatal((strncmp(head.magic, (char*) ole_magic, sizeof(ole_magic)) != 0), MYNAME ": No MS document."); + + head.rev = le_read16(&head.rev); + head.ver = le_read16(&head.ver); + head.byte_order = le_read16(&head.byte_order); + head.fat1_size_shift = le_read16(&head.fat1_size_shift); + head.fat2_size_shift = le_read16(&head.fat2_size_shift); + head.fat1_blocks = le_read32(&head.fat1_blocks); + head.prop_start = le_read32(&head.prop_start); + head.fat1_min_size = le_read32(&head.fat1_min_size); + head.fat2_start = le_read32(&head.fat2_start); + head.fat2_blocks = le_read32(&head.fat2_blocks); + head.fat1_extra_start = le_read32(&head.fat1_extra_start); + head.fat1_extra_ct = le_read32(&head.fat1_extra_ct); + le_read32_buff(&head.fat1[0], OLE_HEAD_FAT1_CT); + + ole_size1 = (1 << head.fat1_size_shift); + ole_size2 = (1 << head.fat2_size_shift); + ole_size1_min = head.fat1_min_size; #ifdef OLE_DEBUG - printf(MYNAME "-head: (version.revision) = %d.%d\n", head.ver, head.rev); - printf(MYNAME "-head: byte-order = %d\n", head.byte_order); - printf(MYNAME "-head: big fat start sector = %d (0x%x)\n", head.fat1[0], (head.fat1[0] + 1) * 512); - printf(MYNAME "-head: big fat blocks = %d\n", head.fat1_blocks); - printf(MYNAME "-head: big fat block size = %d\n", (1 << head.fat1_size_shift)); - printf(MYNAME "-head: small fat start sector = %d\n", head.fat2_start); - printf(MYNAME "-head: small fat blocks = %d\n", head.fat2_blocks); - printf(MYNAME "-head: small fat block size = %d\n", (1 << head.fat2_size_shift)); - printf(MYNAME "-head: big fat minimum length = %d\n", head.fat1_min_size); - printf(MYNAME "-head: property catalog start sector = %d\n", head.prop_start); - printf(MYNAME "-head: additional big fat blocks = %d\n", head.fat1_extra_ct); - printf(MYNAME "-head: additional big fat start sector = %d (0x%x)\n", head.fat1_extra_start, (head.fat1_extra_start + 1) * 512); + printf(MYNAME "-head: (version.revision) = %d.%d\n", head.ver, head.rev); + printf(MYNAME "-head: byte-order = %d\n", head.byte_order); + printf(MYNAME "-head: big fat start sector = %d (0x%x)\n", head.fat1[0], (head.fat1[0] + 1) * 512); + printf(MYNAME "-head: big fat blocks = %d\n", head.fat1_blocks); + printf(MYNAME "-head: big fat block size = %d\n", (1 << head.fat1_size_shift)); + printf(MYNAME "-head: small fat start sector = %d\n", head.fat2_start); + printf(MYNAME "-head: small fat blocks = %d\n", head.fat2_blocks); + printf(MYNAME "-head: small fat block size = %d\n", (1 << head.fat2_size_shift)); + printf(MYNAME "-head: big fat minimum length = %d\n", head.fat1_min_size); + printf(MYNAME "-head: property catalog start sector = %d\n", head.prop_start); + printf(MYNAME "-head: additional big fat blocks = %d\n", head.fat1_extra_ct); + printf(MYNAME "-head: additional big fat start sector = %d (0x%x)\n", head.fat1_extra_start, (head.fat1_extra_start + 1) * 512); #endif - is_fatal((head.byte_order != -2), MYNAME ": Unsupported byte-order %d", head.byte_order); + is_fatal((head.byte_order != -2), MYNAME ": Unsupported byte-order %d", head.byte_order); #if 0 - sector_sz = ole_size1; /* i'll implement this, if i get an MS-doc (ole) */ - /* with "sector_sz" other than 512 */ + sector_sz = ole_size1; /* i'll implement this, if i get an MS-doc (ole) */ + /* with "sector_sz" other than 512 */ #else - is_fatal((ole_size1 != 512), MYNAME ": Unsupported sector size %d", ole_size1); + is_fatal((ole_size1 != 512), MYNAME ": Unsupported sector size %d", ole_size1); #endif - ole_fat1 = xmalloc(head.fat1_blocks * sector_sz); - ole_fat1_ct = (head.fat1_blocks * sector_sz) / sizeof(gbint32); - + ole_fat1 = (gbint32*) xmalloc(head.fat1_blocks * sector_sz); + ole_fat1_ct = (head.fat1_blocks * sector_sz) / sizeof(gbint32); + #ifdef OLE_DEBUG - printf(MYNAME "-big fat: %d maximum sectors, size in memory %d, max. datasize %d bytes\n", - ole_fat1_ct, head.fat1_blocks * sector_sz, head.fat1_blocks * sector_sz * sector_sz / sizeof(gbint32)); + printf(MYNAME "-big fat: %d maximum sectors, size in memory %d, max. datasize %d bytes\n", + ole_fat1_ct, head.fat1_blocks * sector_sz, head.fat1_blocks * sector_sz * sector_sz / sizeof(gbint32)); #endif - i_offs = 0; /* load "big fat" into memory */ - left = head.fat1_blocks; - count = (left > OLE_HEAD_FAT1_CT) ? OLE_HEAD_FAT1_CT : left; - - for (i = 0; i < count; i++) - { - sector = head.fat1[i]; - ole_read_sector(sector, &ole_fat1[i_offs], 1); - i_offs += ole_size1 / 4; - } - - left -= count; - - if (left > 0) - { - sector = head.fat1_extra_start; - - while ((left > 0) && (sector >= 0)) - { - ole_read_sector(sector, &fat1_extra, 1); - le_read32_buff(&fat1_extra[0], 128); - - count = (left < 127) ? left : 127; - for (i = 0; i < count; i++) - { - ole_read_sector(fat1_extra[i], &ole_fat1[i_offs], 1); - i_offs += ole_size1 / 4; - } - left -= count; - if (left > 0) - sector = fat1_extra[127]; - } - is_fatal((left > 0), MYNAME ": Broken stream!"); - } - if (ole_fat1_ct > 0) - le_read32_buff(&ole_fat1[0], ole_fat1_ct); - - - /* load fat2 "small fat" into memory */ - - sector = head.fat2_start; - if (sector >= 0) - { - count = 0; - do - { - if (ole_fat2 == NULL) - ole_fat2 = (int *)xmalloc((count + 1) * sector_sz); - else - ole_fat2 = (int *)xrealloc(ole_fat2, (count + 1) * sector_sz); - - ole_read_sector(sector, (char *)ole_fat2 + (count * sector_sz), 1); - sector = ole_fat1[sector]; - - count++; - } - while (sector >= 0); - - ole_fat2_ct = (count * sector_sz) / sizeof(gbint32); - if (ole_fat2_ct > 0) - le_read32_buff(&ole_fat2[0], ole_fat2_ct); - } - - /* load directory (property catalog) */ - - sector = head.prop_start; - is_fatal((sector < 0), MYNAME ": Invalid file (no property catalog)!"); - - count = 0; - while (sector >= 0) - { - if (ole_dir == NULL) - ole_dir = (void *)xmalloc((count + 1) * sector_sz); - else - ole_dir = (void *)xrealloc(ole_dir, (count + 1) * sector_sz); - - ole_read_sector(sector, (char *)ole_dir + (count * sector_sz), 1); - sector = ole_fat1[sector]; - - count++; - } - ole_dir_ct = (count * sector_sz) / sizeof(ole_prop_t); - - /* fix endianess of property catalog */ - - for (i = 0; i < ole_dir_ct; i++) - { - ole_prop_t *item = &ole_dir[i]; - - item->first_sector = le_read32(&item->first_sector); - item->data_sz = le_read32(&item->data_sz); - } - - ole_root = ole_find_property("Root Entry"); - - /* read fat2 data sectors given by "Root Entry" */ - - ole_root_sec_ct = (ole_root->data_sz + (sector_sz - 1)) / sector_sz; - ole_root_sec = xcalloc(ole_root_sec_ct + 1, sizeof(char *)); - - i = 0; - sector = ole_root->first_sector; - while (sector >= 0) - { - char *temp; - - temp = ole_root_sec[i++] = xmalloc(sector_sz); - - ole_read_sector(sector, temp, 1); - sector = ole_fat1[sector]; - } + i_offs = 0; /* load "big fat" into memory */ + left = head.fat1_blocks; + count = (left > OLE_HEAD_FAT1_CT) ? OLE_HEAD_FAT1_CT : left; + + for (i = 0; i < count; i++) { + sector = head.fat1[i]; + ole_read_sector(sector, &ole_fat1[i_offs], 1); + i_offs += ole_size1 / 4; + } + + left -= count; + + if (left > 0) { + sector = head.fat1_extra_start; + + while ((left > 0) && (sector >= 0)) { + ole_read_sector(sector, &fat1_extra, 1); + le_read32_buff(&fat1_extra[0], 128); + + count = (left < 127) ? left : 127; + for (i = 0; i < count; i++) { + ole_read_sector(fat1_extra[i], &ole_fat1[i_offs], 1); + i_offs += ole_size1 / 4; + } + left -= count; + if (left > 0) { + sector = fat1_extra[127]; + } + } + is_fatal((left > 0), MYNAME ": Broken stream!"); + } + if (ole_fat1_ct > 0) { + le_read32_buff(&ole_fat1[0], ole_fat1_ct); + } + + + /* load fat2 "small fat" into memory */ + + sector = head.fat2_start; + if (sector >= 0) { + count = 0; + do { + if (ole_fat2 == NULL) { + ole_fat2 = (int*)xmalloc((count + 1) * sector_sz); + } else { + ole_fat2 = (int*)xrealloc(ole_fat2, (count + 1) * sector_sz); + } + + ole_read_sector(sector, (char*)ole_fat2 + (count * sector_sz), 1); + sector = ole_fat1[sector]; + + count++; + } while (sector >= 0); + + ole_fat2_ct = (count * sector_sz) / sizeof(gbint32); + if (ole_fat2_ct > 0) { + le_read32_buff(&ole_fat2[0], ole_fat2_ct); + } + } + + /* load directory (property catalog) */ + + sector = head.prop_start; + is_fatal((sector < 0), MYNAME ": Invalid file (no property catalog)!"); + + count = 0; + while (sector >= 0) { + if (ole_dir == NULL) { + ole_dir = (ole_prop_t*)xmalloc((count + 1) * sector_sz); + } else { + ole_dir = (ole_prop_t*)xrealloc(ole_dir, (count + 1) * sector_sz); + } + + ole_read_sector(sector, (char*)ole_dir + (count * sector_sz), 1); + sector = ole_fat1[sector]; + + count++; + } + ole_dir_ct = (count * sector_sz) / sizeof(ole_prop_t); + + /* fix endianess of property catalog */ + + for (i = 0; i < ole_dir_ct; i++) { + ole_prop_t* item = &ole_dir[i]; + + item->first_sector = le_read32(&item->first_sector); + item->data_sz = le_read32(&item->data_sz); + } + + ole_root = ole_find_property("Root Entry"); + + /* read fat2 data sectors given by "Root Entry" */ + + ole_root_sec_ct = (ole_root->data_sz + (sector_sz - 1)) / sector_sz; + ole_root_sec = (char**) xcalloc(ole_root_sec_ct + 1, sizeof(char*)); + + i = 0; + sector = ole_root->first_sector; + while (sector >= 0) { + char* temp; + + temp = ole_root_sec[i++] = (char*) xmalloc(sector_sz); + + ole_read_sector(sector, temp, 1); + sector = ole_fat1[sector]; + } #ifdef OLE_DEBUG - ole_test_properties(); + ole_test_properties(); #endif } static void ole_deinit(void) { - if (ole_root_sec != NULL) - { - int i; - for (i = 0; i < ole_root_sec_ct; i++) - { - char *c; - if ((c = ole_root_sec[i])) xfree(c); - } - xfree(ole_root_sec); - } - if (ole_fat1 != NULL) xfree(ole_fat1); - if (ole_fat2 != NULL) xfree(ole_fat2); - if (ole_dir != NULL) xfree(ole_dir); + if (ole_root_sec != NULL) { + int i; + for (i = 0; i < ole_root_sec_ct; i++) { + char* c; + if ((c = ole_root_sec[i])) { + xfree(c); + } + } + xfree(ole_root_sec); + } + if (ole_fat1 != NULL) { + xfree(ole_fat1); + } + if (ole_fat2 != NULL) { + xfree(ole_fat2); + } + if (ole_dir != NULL) { + xfree(ole_dir); + } } /* global MS AutoRoute functions */ @@ -566,118 +561,119 @@ ole_deinit(void) static void msroute_read_journey(void) { - int bufsz = 0; - char *buff; - - buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &bufsz); - - if ((buff != NULL) && (bufsz > 0)) - { - msroute_head_t *head = (msroute_head_t *)buff; - unsigned char *cin, *cend; - int count = 0; - route_head *route; - waypoint *wpt; - char version; - - is_fatal((strncmp(head->masm, "MASM", 4) != 0), MYNAME ": Invalid or unknown data!"); - - version = buff[0x14]; - is_fatal((version < 1) || (version > 7), MYNAME ": Unsupported version %d!", version); - - cin = (unsigned char *)buff + 71; // (at least?) sizeof(msroute_head_t); - cend = (unsigned char *)buff + bufsz; - - route = route_head_alloc(); - route_add_head(route); - - head->waypts = le_read32(&head->waypts); - - while (count < head->waypts) - { - int len; - - /* after version 6 we've seen data with different header length */ - /* now we try to find the next pair of names in buff */ - - while (1) { - len = *cin; - if ((cin + 120) > cend) { - cin = NULL; - break; - } - if ((cin + len < cend) && /* within buff ? */ - (cin[len + 3] == 0xff) && /* 0xff before next length byte ? */ - (cin[len + 4] == len) && /* wide string of same length ? */ - (le_read16(cin + len + 1) == 0xfeff)) { - break; - } - cin++; - } - if (cin == NULL) break; - - wpt = waypt_new(); - - len = *cin++; /* length of shortname */ - cin += len; - cin += 3; /* 0xfffeff */ - - len = *cin++; - wpt->shortname = cet_str_uni_to_utf8((const short *)cin, len); - cin += (len * 2); /* seek over wide string */ - cin += (5 * sizeof(gbint32)); /* five unknown DWORDs */ - - /* offs 12 !!!! Latitude int32 LE */ - /* offs 16 !!!! Longitude int32 LE */ - wpt->latitude = GPS_Math_Semi_To_Deg(le_read32(cin+12)); - wpt->longitude = GPS_Math_Semi_To_Deg(le_read32(cin+16)); - - cin += (23 * sizeof(gbint32)); - cin += 3; - + int bufsz = 0; + char* buff; + + buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &bufsz); + + if ((buff != NULL) && (bufsz > 0)) { + msroute_head_t* head = (msroute_head_t*)buff; + unsigned char* cin, *cend; + int count = 0; + route_head* route; + waypoint* wpt; + char version; + + is_fatal((strncmp(head->masm, "MASM", 4) != 0), MYNAME ": Invalid or unknown data!"); + + version = buff[0x14]; + is_fatal((version < 1) || (version > 7), MYNAME ": Unsupported version %d!", version); + + cin = (unsigned char*)buff + 71; // (at least?) sizeof(msroute_head_t); + cend = (unsigned char*)buff + bufsz; + + route = route_head_alloc(); + route_add_head(route); + + head->waypts = le_read32(&head->waypts); + + while (count < head->waypts) { + int len; + + /* after version 6 we've seen data with different header length */ + /* now we try to find the next pair of names in buff */ + + while (1) { + len = *cin; + if ((cin + 120) > cend) { + cin = NULL; + break; + } + if ((cin + len < cend) && /* within buff ? */ + (cin[len + 3] == 0xff) && /* 0xff before next length byte ? */ + (cin[len + 4] == len) && /* wide string of same length ? */ + (le_read16(cin + len + 1) == 0xfeff)) { + break; + } + cin++; + } + if (cin == NULL) { + break; + } + + wpt = waypt_new(); + + len = *cin++; /* length of shortname */ + cin += len; + cin += 3; /* 0xfffeff */ + + len = *cin++; + wpt->shortname = cet_str_uni_to_utf8((const short*)cin, len); + cin += (len * 2); /* seek over wide string */ + cin += (5 * sizeof(gbint32)); /* five unknown DWORDs */ + + /* offs 12 !!!! Latitude int32 LE */ + /* offs 16 !!!! Longitude int32 LE */ + wpt->latitude = GPS_Math_Semi_To_Deg(le_read32(cin+12)); + wpt->longitude = GPS_Math_Semi_To_Deg(le_read32(cin+16)); + + cin += (23 * sizeof(gbint32)); + cin += 3; + #ifdef OLE_DEBUG - waypt_add(waypt_dupe(wpt)); /* put to wpt-list to see results if no output is specified */ -#endif - route_add_wpt(route, wpt); - count++; - } - } - - if (buff != NULL) - xfree(buff); + waypt_add(waypt_dupe(wpt)); /* put to wpt-list to see results if no output is specified */ +#endif + route_add_wpt(route, wpt); + count++; + } + } + + if (buff != NULL) { + xfree(buff); + } } /* registered callbacks */ -static void msroute_rd_init(const char *fname) +static void msroute_rd_init(const char* fname) { - fin = gbfopen(fname, "rb", MYNAME); - - ole_init(); + fin = gbfopen(fname, "rb", MYNAME); + + ole_init(); } static void msroute_rd_deinit(void) { - ole_deinit(); + ole_deinit(); - gbfclose(fin); + gbfclose(fin); } static void msroute_read(void) { - msroute_read_journey(); + msroute_read_journey(); } ff_vecs_t msroute_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_none, ff_cap_read }, - msroute_rd_init, - NULL, - msroute_rd_deinit, - NULL, - msroute_read, - NULL, - NULL, - msroute_args, - CET_CHARSET_UTF8, 1 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read }, + msroute_rd_init, + NULL, + msroute_rd_deinit, + NULL, + msroute_read, + NULL, + NULL, + msroute_args, + CET_CHARSET_UTF8, 1 /* CET-REVIEW */ }; diff --git a/gpsbabel/msvc/GPSBabel.vcproj b/gpsbabel/msvc/GPSBabel.vcproj index f37f0f245..252bca73e 100644 --- a/gpsbabel/msvc/GPSBabel.vcproj +++ b/gpsbabel/msvc/GPSBabel.vcproj @@ -648,6 +648,10 @@ RelativePath="..\exif.c" > + + @@ -752,6 +756,10 @@ RelativePath="..\garmin_txt.c" > + + @@ -2284,6 +2292,10 @@ RelativePath="..\strptime.c" > + + @@ -3273,6 +3285,10 @@ RelativePath="..\defs.h" > + + diff --git a/gpsbabel/mtk_logger.c b/gpsbabel/mtk_logger.c index c48438337..37e948485 100644 --- a/gpsbabel/mtk_logger.c +++ b/gpsbabel/mtk_logger.c @@ -1,8 +1,8 @@ /* - Download track data from GPS loggers based in MTK chipset. + Download track data from GPS loggers based in MTK chipset. Copyright (C) 2007 Per Borgentun, e4borgen(at)yahoo.com - With lot of inspiration from wbt-200.c + With lot of inspiration from wbt-200.c Copyright (C) 2006 Andy Armstrong This program is free software; you can redistribute it and/or modify @@ -20,36 +20,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -/* +/* -------------------------------------------------------------- - This module will download track data from a MTK chipset based GPS logger. - It will also convert the raw data.bin file to MTK compatible CSV and + This module will download track data from a MTK chipset based GPS logger. + It will also convert the raw data.bin file to MTK compatible CSV and gpsbabel output of your choice. It has been tested with Transystem i-Blue 747 but other devices should work as well (Qstarz BT-Q1000, iTrek Z1, ...) - For more info and tweaks on MTK based loggers + For more info and tweaks on MTK based loggers For info about the used log format: - Module updated 2008-2009. Now also handles Holux M-241 and + Module updated 2008-2009. Now also handles Holux M-241 and Holux GR-245 aka. GPSport-245 devices. These devices have small differences in the log format and use a lower baudrate to transfer the data. - Example usage:: - # Read from USB port, output trackpoints & waypoints in GPX format + Example usage:: + # Read from USB port, output trackpoints & waypoints in GPX format ./gpsbabel -D 2 -t -w -i mtk -f /dev/ttyUSB0 -o gpx -F out.gpx - - # Parse an existing .bin file (data_2007_09_04.bin), output trackpoints as + + # Parse an existing .bin file (data_2007_09_04.bin), output trackpoints as # both CSV file and GPX, discard points without fix ./gpsbabel -D 2 -t -i mtk-bin,csv=data__2007_09_04.csv -f data_2007_09_04.bin -x discard,fixnone -o gpx -F out.gpx - Tip: Check out the -x height,wgs84tomsl filter to correct the altitude. + Tip: Check out the -x height,wgs84tomsl filter to correct the altitude. Todo: - o .... - + o .... + */ #include "defs.h" @@ -61,52 +61,54 @@ #define MYNAME "mtk_logger" /* MTK packet id's -- currently unused... */ -enum MTK_NMEA_PACKET { - PMTK_TEST = 0, - PMTK_ACK = 1, - PMTK_SYS_MSG = 10, - PMTK_CMD_HOT_START = 101, - PMTK_CMD_WARM_START = 102, - PMTK_CMD_COLD_START = 103, - PMTK_CMD_FULL_COLD_START = 104, - PMTK_CMD_LOG = 182, /* Data log commands */ - PMTK_SET_NMEA_BAUDRATE = 251, - PMTK_API_SET_DGPS_MODE = 301, - PMTK_API_SET_SBAS_ENABLED = 313, - PMTK_API_SET_NMEA_OUTPUT = 314, - PMTK_API_SET_PWR_SAV_MODE = 320, - PMTK_API_SET_DATUM = 330, - PMTK_API_SET_DATUM_ADVANCE = 331, - PMTK_API_SET_USER_OPTION = 390, - PMTK_API_Q_FIX_CTL = 400, - PMTK_API_Q_DGPS_MODE = 401, - PMTK_API_Q_SBAS_ENABLED = 413, - PMTK_API_Q_NMEA_OUTPUT = 414, - PMTK_API_Q_PWR_SAV_MODE = 420, - PMTK_API_Q_DATUM = 430, - PMTK_API_Q_DATUM_ADVANCE = 431, - PMTK_API_GET_USER_OPTION = 490, - PMTK_DT_FIX_CTL = 500, - PMTK_DT_DGPS_MODE = 501, - PMTK_DT_SBAS_ENABLED = 513, - PMTK_DT_NMEA_OUTPUT = 514, - PMTK_DT_PWR_SAV_MODE = 520, - PMTK_DT_DATUM = 530, - PMTK_DT_FLASH_USER_OPTION = 590, - PMTK_Q_VERSION = 604, - PMTK_Q_RELEASE = 605, - PMTK_DT_VERSION = 704, - PMTK_DT_RELEASE = 705 -}; - -static const unsigned char LOG_RST[16] = { - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* start marker */ - 0x00, 0x00, 0x00, 0x00, 0x00, /* data */ - 0xbb, 0xbb, 0xbb, 0xbb }; /* end marker */ - -static const char *MTK_ACK[] = { /* Flags returned from PMTK001 ack packet */ - "Invalid packet", "Unsupported packet type", - "Valid packet but action failed", "Valid packet, action success" }; +enum MTK_NMEA_PACKET { + PMTK_TEST = 0, + PMTK_ACK = 1, + PMTK_SYS_MSG = 10, + PMTK_CMD_HOT_START = 101, + PMTK_CMD_WARM_START = 102, + PMTK_CMD_COLD_START = 103, + PMTK_CMD_FULL_COLD_START = 104, + PMTK_CMD_LOG = 182, /* Data log commands */ + PMTK_SET_NMEA_BAUDRATE = 251, + PMTK_API_SET_DGPS_MODE = 301, + PMTK_API_SET_SBAS_ENABLED = 313, + PMTK_API_SET_NMEA_OUTPUT = 314, + PMTK_API_SET_PWR_SAV_MODE = 320, + PMTK_API_SET_DATUM = 330, + PMTK_API_SET_DATUM_ADVANCE = 331, + PMTK_API_SET_USER_OPTION = 390, + PMTK_API_Q_FIX_CTL = 400, + PMTK_API_Q_DGPS_MODE = 401, + PMTK_API_Q_SBAS_ENABLED = 413, + PMTK_API_Q_NMEA_OUTPUT = 414, + PMTK_API_Q_PWR_SAV_MODE = 420, + PMTK_API_Q_DATUM = 430, + PMTK_API_Q_DATUM_ADVANCE = 431, + PMTK_API_GET_USER_OPTION = 490, + PMTK_DT_FIX_CTL = 500, + PMTK_DT_DGPS_MODE = 501, + PMTK_DT_SBAS_ENABLED = 513, + PMTK_DT_NMEA_OUTPUT = 514, + PMTK_DT_PWR_SAV_MODE = 520, + PMTK_DT_DATUM = 530, + PMTK_DT_FLASH_USER_OPTION = 590, + PMTK_Q_VERSION = 604, + PMTK_Q_RELEASE = 605, + PMTK_DT_VERSION = 704, + PMTK_DT_RELEASE = 705 +}; + +static const unsigned char LOG_RST[16] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* start marker */ + 0x00, 0x00, 0x00, 0x00, 0x00, /* data */ + 0xbb, 0xbb, 0xbb, 0xbb +}; /* end marker */ + +static const char* MTK_ACK[] = { /* Flags returned from PMTK001 ack packet */ + "Invalid packet", "Unsupported packet type", + "Valid packet but action failed", "Valid packet, action success" +}; #define MTK_EVT_BITMASK (1<<0x02) #define MTK_EVT_PERIOD (1<<0x03) @@ -119,93 +121,93 @@ static const char *MTK_ACK[] = { /* Flags returned from PMTK001 ack packet */ /* Data id, type, sizes used by MTK chipset - don't touch.... */ enum { - UTC = 0, - VALID, - LATITUDE, - LONGITUDE, - HEIGHT, - SPEED, - HEADING, - DSTA, - DAGE, - PDOP, - HDOP, - VDOP, - NSAT, - SID, - ELEVATION, - AZIMUTH, - SNR, - RCR, - MILLISECOND, - DISTANCE, + UTC = 0, + VALID, + LATITUDE, + LONGITUDE, + HEIGHT, + SPEED, + HEADING, + DSTA, + DAGE, + PDOP, + HDOP, + VDOP, + NSAT, + SID, + ELEVATION, + AZIMUTH, + SNR, + RCR, + MILLISECOND, + DISTANCE, } DATA_TYPES; struct log_type { - int id; - int size; - const char *name; + int id; + int size; + const char* name; } log_type[32] = { - { 0, 4, "UTC" }, - { 1, 2, "VALID" }, - { 2, 8, "LATITUDE,N/S"}, - { 3, 8, "LONGITUDE,E/W"}, - { 4, 4, "HEIGHT" }, - { 5, 4, "SPEED" }, - { 6, 4, "HEADING" }, - { 7, 2, "DSTA" }, - { 8, 4, "DAGE" }, - { 9, 2, "PDOP" }, - { 10, 2, "HDOP"}, - { 11, 2, "VDOP"}, - { 12, 2, "NSAT (USED/VIEW)"}, - { 13, 4, "SID",}, - { 14, 2, "ELEVATION" }, - { 15, 2, "AZIMUTH" }, - { 16, 2, "SNR"}, - { 17, 2, "RCR"}, - { 18, 2, "MILLISECOND"}, - { 19, 8, "DISTANCE" }, - { 20, 0, NULL}, + { 0, 4, "UTC" }, + { 1, 2, "VALID" }, + { 2, 8, "LATITUDE,N/S"}, + { 3, 8, "LONGITUDE,E/W"}, + { 4, 4, "HEIGHT" }, + { 5, 4, "SPEED" }, + { 6, 4, "HEADING" }, + { 7, 2, "DSTA" }, + { 8, 4, "DAGE" }, + { 9, 2, "PDOP" }, + { 10, 2, "HDOP"}, + { 11, 2, "VDOP"}, + { 12, 2, "NSAT (USED/VIEW)"}, + { 13, 4, "SID",}, + { 14, 2, "ELEVATION" }, + { 15, 2, "AZIMUTH" }, + { 16, 2, "SNR"}, + { 17, 2, "RCR"}, + { 18, 2, "MILLISECOND"}, + { 19, 8, "DISTANCE" }, + { 20, 0, NULL}, }; struct sat_info { - char id, used; - short elevation, azimut, snr; + char id, used; + short elevation, azimut, snr; } sat_info; struct data_item { - time_t timestamp; - short valid; - double lat; - double lon; - float height; - float speed; - float heading; - short dsta; // differential station id - float dage; // differential data age - float pdop, hdop, vdop; - char sat_used, sat_view, sat_count; - short rcr; - unsigned short timestamp_ms; - double distance; - struct sat_info sat_data[32]; + time_t timestamp; + short valid; + double lat; + double lon; + float height; + float speed; + float heading; + short dsta; // differential station id + float dage; // differential data age + float pdop, hdop, vdop; + char sat_used, sat_view, sat_count; + short rcr; + unsigned short timestamp_ms; + double distance; + struct sat_info sat_data[32]; } data_item; struct mtk_loginfo { - unsigned int bitmask; - int logLen; - int period, distance, speed; /* in 10:ths of sec, m, km/h */ - int track_event; + unsigned int bitmask; + int logLen; + int period, distance, speed; /* in 10:ths of sec, m, km/h */ + int track_event; } mtk_loginfo; /* *************************************** */ -/* MTK chip based devices with different baudrate, tweaks, ... */ +/* MTK chip based devices with different baudrate, tweaks, ... */ enum MTK_DEVICE_TYPE { - MTK_LOGGER, - HOLUX_M241, - HOLUX_GR245 + MTK_LOGGER, + HOLUX_M241, + HOLUX_GR245 }; #define TIMEOUT 1500 @@ -214,13 +216,13 @@ enum MTK_DEVICE_TYPE { #define HOLUX245_MASK (1 << 27) -static void *fd; /* serial fd */ -static FILE *fl; /* bin.file fd */ -static char *port; /* serial port name */ -static char *OPT_erase; /* erase ? command option */ -static char *OPT_erase_only; /* erase_only ? command option */ -static char *OPT_log_enable; /* enable ? command option */ -static char *csv_file; /* csv ? command option */ +static void* fd; /* serial fd */ +static FILE* fl; /* bin.file fd */ +static char* port; /* serial port name */ +static char* OPT_erase; /* erase ? command option */ +static char* OPT_erase_only; /* erase_only ? command option */ +static char* OPT_log_enable; /* enable ? command option */ +static char* csv_file; /* csv ? command option */ static enum MTK_DEVICE_TYPE mtk_device = MTK_LOGGER; struct mtk_loginfo mtk_info; @@ -237,324 +239,351 @@ const char CMD_LOG_ERASE[] = "$PMTK182,6,1*3E\r\n"; const char CMD_LOG_STATUS[] = "$PMTK182,2,7*3C\r\n"; static int mtk_log_len(unsigned int bitmask); -static void mtk_rd_init(const char *fname); -static void file_init(const char *fname); +static void mtk_rd_init(const char* fname); +static void file_init(const char* fname); static void file_deinit(void) ; static void holux245_init(void); static void file_read(void); -static int mtk_parse_info(const unsigned char *data, int dataLen); +static int mtk_parse_info(const unsigned char* data, int dataLen); // Arguments for log fetch 'mtk' command.. static arglist_t mtk_sargs[] = { - { "erase", &OPT_erase, "Erase device data after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "erase_only", &OPT_erase_only, "Only erase device data, do not download anything", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "log_enable", &OPT_log_enable, "Enable logging after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "csv", &csv_file, "MTK compatible CSV output file", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "erase", &OPT_erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "erase_only", &OPT_erase_only, "Only erase device data, do not download anything", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "log_enable", &OPT_log_enable, "Enable logging after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "csv", &csv_file, "MTK compatible CSV output file", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static void dbg(int l, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - vfprintf(stderr,msg, ap); - fflush(stderr); - } - va_end(ap); +static void dbg(int l, const char* msg, ...) +{ + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vfprintf(stderr,msg, ap); + fflush(stderr); + } + va_end(ap); } -static int do_send_cmd(const char *cmd, int cmdLen) { - int rc; - - dbg(6, "Send %s ", cmd); - rc = gbser_print(fd, cmd); - if ( rc != gbser_OK ) - fatal(MYNAME ": Write error (%d)\n", rc); +static int do_send_cmd(const char* cmd, int cmdLen) +{ + int rc; + + dbg(6, "Send %s ", cmd); + rc = gbser_print(fd, cmd); + if (rc != gbser_OK) { + fatal(MYNAME ": Write error (%d)\n", rc); + } - return cmdLen; + return cmdLen; } -static int do_cmd(const char *cmd, const char *expect, char **rslt, time_t timeout_sec) { - char line[256]; - int len, done, loops, cmd_erase; - int expect_len; - time_t tout; - - if ( expect ) - expect_len = strlen(expect); - else - expect_len = 0; - - time(&tout); - if ( timeout_sec > 0 ) - tout += timeout_sec; - else - tout += 1; - - cmd_erase = 0; - if ( strncmp(cmd, CMD_LOG_ERASE, 12) == 0 ){ - cmd_erase = 1; - if (global_opts.verbose_status || global_opts.debug_level > 0) { - fprintf(stderr, "Erasing "); - } - } - // dbg(6, "## Send '%s' -- Expect '%s' in %d sec\n", cmd, expect, timeout_sec); - - do_send_cmd(cmd, strlen(cmd)); // success or fatal()... - - done = 0; - loops = 0; - memset(line, '\0', sizeof(line)); - do { +static int do_cmd(const char* cmd, const char* expect, char** rslt, time_t timeout_sec) +{ + char line[256]; + int len, done, loops, cmd_erase; + int expect_len; + time_t tout; + + if (expect) { + expect_len = strlen(expect); + } else { + expect_len = 0; + } + + time(&tout); + if (timeout_sec > 0) { + tout += timeout_sec; + } else { + tout += 1; + } + + cmd_erase = 0; + if (strncmp(cmd, CMD_LOG_ERASE, 12) == 0) { + cmd_erase = 1; + if (global_opts.verbose_status || global_opts.debug_level > 0) { + fprintf(stderr, "Erasing "); + } + } + // dbg(6, "## Send '%s' -- Expect '%s' in %d sec\n", cmd, expect, timeout_sec); + + do_send_cmd(cmd, strlen(cmd)); // success or fatal()... + + done = 0; + loops = 0; + memset(line, '\0', sizeof(line)); + do { int rc; rc = gbser_read_line(fd, line, sizeof(line)-1, TIMEOUT, 0x0A, 0x0D); - if ( rc != gbser_OK) { - if ( rc == gbser_TIMEOUT && time(NULL) > tout ){ - dbg(2, "NMEA command '%s' timeout !\n", cmd); - return -1; - // fatal(MYNAME "do_cmd(): Read error (%d)\n", rc); - } - len = -1; + if (rc != gbser_OK) { + if (rc == gbser_TIMEOUT && time(NULL) > tout) { + dbg(2, "NMEA command '%s' timeout !\n", cmd); + return -1; + // fatal(MYNAME "do_cmd(): Read error (%d)\n", rc); + } + len = -1; } else { - len = strlen(line); + len = strlen(line); } loops++; dbg(8, "Read %d bytes: '%s'\n", len, line); - if ( cmd_erase && (global_opts.verbose_status || (global_opts.debug_level > 0 && global_opts.debug_level <= 3)) ){ - // erase cmd progress wheel -- only for debug level 1-3 - fprintf(stderr,"\b%c", LIVE_CHAR[loops%4]); fflush(stderr); + if (cmd_erase && (global_opts.verbose_status || (global_opts.debug_level > 0 && global_opts.debug_level <= 3))) { + // erase cmd progress wheel -- only for debug level 1-3 + fprintf(stderr,"\b%c", LIVE_CHAR[loops%4]); + fflush(stderr); } - if ( len > 5 && line[0] == '$' ){ - if ( expect_len > 0 && strncmp(&line[1], expect, expect_len) == 0 ){ - if ( cmd_erase && (global_opts.verbose_status || global_opts.debug_level > 0) ) fprintf(stderr,"\n"); - dbg(6, "NMEA command success !\n"); - if ( (len - 4) > expect_len ){ // alloc and copy data segment... - if ( line[len-3] == '*' ) - line[len-3] = '\0'; - // printf("Data segment: #%s#\n", &line[expect_len+1]); - if ( rslt ){ - *rslt = xmalloc(len-3-expect_len+1); - strcpy(*rslt, &line[expect_len+1]); - } + if (len > 5 && line[0] == '$') { + if (expect_len > 0 && strncmp(&line[1], expect, expect_len) == 0) { + if (cmd_erase && (global_opts.verbose_status || global_opts.debug_level > 0)) { + fprintf(stderr,"\n"); + } + dbg(6, "NMEA command success !\n"); + if ((len - 4) > expect_len) { // alloc and copy data segment... + if (line[len-3] == '*') { + line[len-3] = '\0'; + } + // printf("Data segment: #%s#\n", &line[expect_len+1]); + if (rslt) { + *rslt = (char*) xmalloc(len-3-expect_len+1); + strcpy(*rslt, &line[expect_len+1]); + } + } + done = 1; + } else if (strncmp(line, "$PMTK", 5) == 0) { + /* A quick parser for ACK packets */ + if (!cmd_erase && strncmp(line, "$PMTK001,", 9) == 0 && line[9] != '\0') { + char* pType, *pRslt; + int pAck; + pType = &line[9]; + pRslt = strchr(&line[9], ',') + 1; + if (memcmp(&cmd[5], pType, 3) == 0 && pRslt != NULL && *pRslt != '\0') { + pAck = *pRslt - '0'; + if (pAck != 3 && pAck >= 0 && pAck < 4) { // Erase will return '2' + dbg(1, "NMEA command '%s' failed - %s\n", cmd, MTK_ACK[pAck]); + return -1; } - done = 1; - } else if ( strncmp(line, "$PMTK", 5) == 0 ){ - /* A quick parser for ACK packets */ - if ( !cmd_erase && strncmp(line, "$PMTK001,", 9) == 0 && line[9] != '\0' ){ - char *pType, *pRslt; - int pAck; - pType = &line[9]; - pRslt = strchr(&line[9], ',') + 1; - if ( memcmp(&cmd[5], pType, 3) == 0 && pRslt != NULL && *pRslt != '\0' ){ - pAck = *pRslt - '0'; - if ( pAck != 3 && pAck >= 0 && pAck < 4 ){ // Erase will return '2' - dbg(1, "NMEA command '%s' failed - %s\n", cmd, MTK_ACK[pAck]); - return -1; - } - } - - } - dbg(6, "RECV: '%s'\n", line); } - - } - if ( !done && time(NULL) > tout ){ - dbg(1, "NMEA command '%s' timeout !\n", cmd); - return -1; + + } + dbg(6, "RECV: '%s'\n", line); } - } while ( len != 0 && loops > 0 && !done ); - return done?0:1; + + } + if (!done && time(NULL) > tout) { + dbg(1, "NMEA command '%s' timeout !\n", cmd); + return -1; + } + } while (len != 0 && loops > 0 && !done); + return done?0:1; } /******************************************************************************* * %%% global callbacks called by gpsbabel main process %%% * *******************************************************************************/ -static void mtk_rd_init_m241 (const char *fname) { - mtk_device = HOLUX_M241; - mtk_rd_init(fname); +static void mtk_rd_init_m241(const char* fname) +{ + mtk_device = HOLUX_M241; + mtk_rd_init(fname); } -static void mtk_rd_init(const char *fname){ - int rc; - char *model; - - port = xstrdup(fname); - - errno = 0; - dbg(1, "Opening port %s...\n", fname); - if ( (fd = gbser_init(port)) == NULL ) { - fatal(MYNAME ": Can't initialise port \"%s\" (%s)\n", port, strerror(errno)); - } - - // verify that we have a MTK based logger... - dbg(1, "Verifying MTK based device...\n"); - - switch ( mtk_device ){ - case HOLUX_M241: - case HOLUX_GR245: - log_type[LATITUDE].size = log_type[LONGITUDE].size = 4; - log_type[HEIGHT].size = 3; - rc = gbser_set_port(fd, MTK_BAUDRATE_M241, 8, 0, 1); - break; - case MTK_LOGGER: - default: - rc = gbser_set_port(fd, MTK_BAUDRATE, 8, 0, 1); - break; - } - if (rc) { - dbg(1, "Set baud rate to %d failed (%d)\n", MTK_BAUDRATE, rc); - fatal(MYNAME ": Failed to set baudrate !\n"); - } +static void mtk_rd_init(const char* fname) +{ + int rc; + char* model; + + port = xstrdup(fname); + + errno = 0; + dbg(1, "Opening port %s...\n", fname); + if ((fd = gbser_init(port)) == NULL) { + fatal(MYNAME ": Can't initialise port \"%s\" (%s)\n", port, strerror(errno)); + } - rc = do_cmd("$PMTK605*31\r\n", "PMTK705,", &model, 10); - if ( rc != 0 ) - fatal(MYNAME ": This is not a MTK based GPS ! (or is device turned off ?)\n"); - - // say hello to GR245 to make it display "USB PROCESSING" - if (strstr(model, "GR-245")) { - holux245_init(); // remember we have a GR245 for mtk_rd_deinit() - rc |= do_cmd("$PHLX810*35\r\n", "PHLX852,", NULL, 10); - rc |= do_cmd("$PHLX826*30\r\n", "PHLX859*38", NULL, 10); - if (rc != 0) - dbg(2, "Greeting not successfull.\n"); + // verify that we have a MTK based logger... + dbg(1, "Verifying MTK based device...\n"); + + switch (mtk_device) { + case HOLUX_M241: + case HOLUX_GR245: + log_type[LATITUDE].size = log_type[LONGITUDE].size = 4; + log_type[HEIGHT].size = 3; + rc = gbser_set_port(fd, MTK_BAUDRATE_M241, 8, 0, 1); + break; + case MTK_LOGGER: + default: + rc = gbser_set_port(fd, MTK_BAUDRATE, 8, 0, 1); + break; + } + if (rc) { + dbg(1, "Set baud rate to %d failed (%d)\n", MTK_BAUDRATE, rc); + fatal(MYNAME ": Failed to set baudrate !\n"); + } + + rc = do_cmd("$PMTK605*31\r\n", "PMTK705,", &model, 10); + if (rc != 0) { + fatal(MYNAME ": This is not a MTK based GPS ! (or is device turned off ?)\n"); + } + + // say hello to GR245 to make it display "USB PROCESSING" + if (strstr(model, "GR-245")) { + holux245_init(); // remember we have a GR245 for mtk_rd_deinit() + rc |= do_cmd("$PHLX810*35\r\n", "PHLX852,", NULL, 10); + rc |= do_cmd("$PHLX826*30\r\n", "PHLX859*38", NULL, 10); + if (rc != 0) { + dbg(2, "Greeting not successfull.\n"); } - xfree(model); - } - -static void mtk_rd_deinit(void){ - if (mtk_device == HOLUX_GR245) { - int rc = do_cmd("$PHLX827*31\r\n", "PHLX860*32", NULL, 10); - if (rc != 0) - dbg(2, "Goodbye not successfull.\n"); + } + xfree(model); +} + +static void mtk_rd_deinit(void) +{ + if (mtk_device == HOLUX_GR245) { + int rc = do_cmd("$PHLX827*31\r\n", "PHLX860*32", NULL, 10); + if (rc != 0) { + dbg(2, "Goodbye not successfull.\n"); } + } - dbg(3, "Closing port...\n"); - gbser_deinit(fd); - fd = NULL; - xfree(port); + dbg(3, "Closing port...\n"); + gbser_deinit(fd); + fd = NULL; + xfree(port); } -static int mtk_erase(void){ - int log_status, log_mask, err; - char *lstatus = NULL; - +static int mtk_erase(void) +{ + int log_status, log_mask, err; + char* lstatus = NULL; + log_status = 0; // check log status - is logging disabled ? do_cmd(CMD_LOG_STATUS, "PMTK182,3,7,", &lstatus, 2); - if ( lstatus ){ - log_status = atoi(lstatus); - dbg(3, "LOG Status '%s'\n", lstatus); - xfree(lstatus); - lstatus = NULL; - } + if (lstatus) { + log_status = atoi(lstatus); + dbg(3, "LOG Status '%s'\n", lstatus); + xfree(lstatus); + lstatus = NULL; + } do_cmd(CMD_LOG_FORMAT, "PMTK182,3,2,", &lstatus, 2); - if ( lstatus ){ - log_mask = strtoul(lstatus, NULL, 16); - dbg(3, "LOG Mask '%s' - 0x%.8x \n", lstatus, log_mask); - xfree(lstatus); - lstatus = NULL; - } - - dbg(1, "Start flash erase..\n"); - do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", NULL, 1); - gb_sleep(10*1000); - - // Erase log.... - do_cmd(CMD_LOG_ERASE, "PMTK001,182,6", NULL, 30); - gb_sleep(100*1000); - - if ( (log_status & 2) ){ // auto-log were enabled before..re-enable log. - err = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", NULL, 2); - dbg(3, "re-enable log %s\n", err==0?"Success":"Fail"); - } - return 0; + if (lstatus) { + log_mask = strtoul(lstatus, NULL, 16); + dbg(3, "LOG Mask '%s' - 0x%.8x \n", lstatus, log_mask); + xfree(lstatus); + lstatus = NULL; + } + + dbg(1, "Start flash erase..\n"); + do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", NULL, 1); + gb_sleep(10*1000); + + // Erase log.... + do_cmd(CMD_LOG_ERASE, "PMTK001,182,6", NULL, 30); + gb_sleep(100*1000); + + if ((log_status & 2)) { // auto-log were enabled before..re-enable log. + err = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", NULL, 2); + dbg(3, "re-enable log %s\n", err==0?"Success":"Fail"); + } + return 0; } -static void mtk_read(void){ +static void mtk_read(void) +{ char cmd[256]; - char *line = NULL; + char* line = NULL; unsigned char crc, *data = NULL; int cmdLen, j, bsize, i, len, ff_len, null_len, rc, init_scan, retry_cnt, log_enabled; unsigned int line_size, data_size, data_addr, addr, addr_max; unsigned long dsize, dpos = 0; - FILE *dout; - char *fusage = NULL; + FILE* dout; + char* fusage = NULL; - if ( *OPT_erase_only != '0' ) { - mtk_erase(); - return; - } + if (*OPT_erase_only != '0') { + mtk_erase(); + return; + } log_enabled = 0; init_scan = 0; dout = fopen(TEMP_DATA_BIN, "r+b"); - if ( dout == NULL ){ - dout = fopen(TEMP_DATA_BIN, "wb"); - if ( dout == NULL ){ - fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); - return; - } + if (dout == NULL) { + dout = fopen(TEMP_DATA_BIN, "wb"); + if (dout == NULL) { + fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); + return; + } } fseek(dout, 0L,SEEK_END); dsize = ftell(dout); - if ( dsize > 1024 ){ - dbg(1, "Temp %s file exists. with size %d\n", TEMP_DATA_BIN, dsize); - dpos = 0; - init_scan = 1; + if (dsize > 1024) { + dbg(1, "Temp %s file exists. with size %d\n", TEMP_DATA_BIN, dsize); + dpos = 0; + init_scan = 1; } dbg(1, "Download %s -> %s\n", port, TEMP_DATA_BIN); // check log status - is logging disabled ? do_cmd(CMD_LOG_STATUS, "PMTK182,3,7,", &fusage, 2); - if ( fusage ){ - log_enabled = (atoi(fusage) & 2)?1:0; - dbg(3, "LOG Status '%s' -- log %s \n", fusage, log_enabled?"enabled":"disabled"); - xfree(fusage); - fusage = NULL; - } - - gb_sleep(10*1000); - if ( 1 || log_enabled ){ - i = do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", NULL, 2); - dbg(3, " ---- LOG DISABLE ---- %s\n", i==0?"Success":"Fail"); - } - gb_sleep(100*1000); - + if (fusage) { + log_enabled = (atoi(fusage) & 2)?1:0; + dbg(3, "LOG Status '%s' -- log %s \n", fusage, log_enabled?"enabled":"disabled"); + xfree(fusage); + fusage = NULL; + } + + gb_sleep(10*1000); + if (1 || log_enabled) { + i = do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", NULL, 2); + dbg(3, " ---- LOG DISABLE ---- %s\n", i==0?"Success":"Fail"); + } + gb_sleep(100*1000); + addr_max = 0; // get flash usage, current log address..cmd only works if log disabled. - do_cmd("$PMTK182,2,8*33\r\n", "PMTK182,3,8,", &fusage, 2); - if ( fusage ){ - addr_max = strtoul(fusage, NULL, 16); - if ( addr_max > 0 ) - addr_max = addr_max - addr_max%65536 + 65535; - xfree(fusage); - } - - if ( addr_max == 0 ) { // get flash usage failed... - addr_max = 0x200000; // 16Mbit/2Mbyte/32x64kByte block. -- fixme Q1000-ng has 32Mbit + do_cmd("$PMTK182,2,8*33\r\n", "PMTK182,3,8,", &fusage, 2); + if (fusage) { + addr_max = strtoul(fusage, NULL, 16); + if (addr_max > 0) { + addr_max = addr_max - addr_max%65536 + 65535; + } + xfree(fusage); + } + + if (addr_max == 0) { // get flash usage failed... + addr_max = 0x200000; // 16Mbit/2Mbyte/32x64kByte block. -- fixme Q1000-ng has 32Mbit init_scan = 1; } dbg(1, "Download %dkB from device\n", (addr_max+1) >> 10); - if ( dsize > addr_max ){ - dbg(1, "Temp %s file (%ld) is larger than data size %d. Data erased since last download !\n", TEMP_DATA_BIN, dsize, addr_max); - fclose(dout); - dsize = 0; - init_scan = 0; - rename(TEMP_DATA_BIN, TEMP_DATA_BIN_OLD); - dout = fopen(TEMP_DATA_BIN, "wb"); - if ( dout == NULL ){ - fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); - return; - } + if (dsize > addr_max) { + dbg(1, "Temp %s file (%ld) is larger than data size %d. Data erased since last download !\n", TEMP_DATA_BIN, dsize, addr_max); + fclose(dout); + dsize = 0; + init_scan = 0; + rename(TEMP_DATA_BIN, TEMP_DATA_BIN_OLD); + dout = fopen(TEMP_DATA_BIN, "wb"); + if (dout == NULL) { + fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); + return; + } } bsize = 0x0400; @@ -562,901 +591,998 @@ static void mtk_read(void){ line_size = 2*bsize + 32; // logdata as nmea/hex. data_size = bsize + 32; - if ( (line = xmalloc(line_size)) == NULL){ - fatal(MYNAME ": Can't allocate %u bytes for NMEA buffer\n", line_size); + if ((line = (char*) xmalloc(line_size)) == NULL) { + fatal(MYNAME ": Can't allocate %u bytes for NMEA buffer\n", line_size); } - if ( (data = xmalloc(data_size)) == NULL ){ - fatal(MYNAME ": Can't allocate %u bytes for data buffer\n", data_size); + if ((data = (unsigned char*) xmalloc(data_size)) == NULL) { + fatal(MYNAME ": Can't allocate %u bytes for data buffer\n", data_size); } memset(line, '\0', line_size); memset(data, '\0', data_size); retry_cnt = 0; - - while ( init_scan || addr < addr_max ) { - // generate - read address NMEA command, add crc. - crc = 0; - cmdLen = snprintf(cmd, sizeof(cmd), "$PMTK182,7,%.8x,%.8x", addr, bsize); - for (i=1;i 0 ) { - line[len] = '\0'; - if ( strncmp(line, "$PMTK182,8", 10) == 0 ){// $PMTK182,8,00005000,FFFFFFF - retry_cnt = 0; - data_addr = strtoul(&line[11], NULL, 16); - fseek(dout, data_addr, SEEK_SET); - i = 20; - j = 0; - ff_len = 0; // number of 0xff bytes. - null_len = 0; // number of 0x00 bytes. - while ( i < (len-3) ){ - data[j] = (isdigit(line[i])?(line[i]-'0'):(line[i]-'A'+0xA))*0x10 + - (isdigit(line[i+1])?(line[i+1]-'0'):(line[i+1]-'A'+0xA)); - if ( data[j] == 0xff ) - ff_len++; - if ( data[j] == 0x00 ) - null_len++; - i += 2; - j++; - } - if ( init_scan ){ - if ( dsize > 0 && addr < dsize ){ - fseek(dout, addr, SEEK_SET); - if ( fread(line, 1, bsize, dout) == bsize && memcmp(line, data, bsize) == 0 ){ - dpos = addr; - dbg(2, "%s same at %d\n", TEMP_DATA_BIN, addr); - } else { - dbg(2, "%s differs at %d\n", TEMP_DATA_BIN, addr); - } - } - if ( ff_len == j ){ // data in sector - we've found max sector.. - addr_max = addr; - dbg(1, "Initial scan done - Download %dkB from device\n", (addr_max+1) >> 10); - } - len = 0; - } else { - if ( null_len == j ){ // 0x00 block - bad block.... - fprintf(stderr, "FIXME -- read bad block at 0x%.6x - retry ? skip ?\n%s\n", data_addr, line); - } - if ( fwrite(data, 1, j, dout) != j ) - fatal(MYNAME ": Failed to write temp. binary file\n"); - if ( ff_len == j ){ // 0xff block - read complete... - len = ff_len; - addr_max = addr; - break; - } else { - len = 0; - } - } - } else if ( strncmp(line, "$PMTK001,182,7,", 15) == 0 ){ // Command ACK - if ( line[15] != '3' ) { - // fixme - we should timeout here when no log data has been received... - dbg(2, "\nLog req. failed (%c)\n", line[15]); - gb_sleep(10*1000); - retry_cnt++; - goto mtk_retry; - } + while (init_scan || addr < addr_max) { + // generate - read address NMEA command, add crc. + crc = 0; + cmdLen = snprintf(cmd, sizeof(cmd), "$PMTK182,7,%.8x,%.8x", addr, bsize); + for (i=1; i 0) { + line[len] = '\0'; + if (strncmp(line, "$PMTK182,8", 10) == 0) { // $PMTK182,8,00005000,FFFFFFF + retry_cnt = 0; + data_addr = strtoul(&line[11], NULL, 16); + fseek(dout, data_addr, SEEK_SET); + i = 20; + j = 0; + ff_len = 0; // number of 0xff bytes. + null_len = 0; // number of 0x00 bytes. + while (i < (len-3)) { + data[j] = (isdigit(line[i])?(line[i]-'0'):(line[i]-'A'+0xA))*0x10 + + (isdigit(line[i+1])?(line[i+1]-'0'):(line[i+1]-'A'+0xA)); + if (data[j] == 0xff) { + ff_len++; } - } - } while ( len != 0 ); - if ( init_scan ){ - addr += 0x10000; - if ( addr >= addr_max ){ // initial scan complete... - init_scan = 0; - addr = dpos; - } - } else { - addr += bsize; - if ( global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5) ){ - int perc; - perc = 100 - 100*(addr_max-addr)/addr_max; - if ( addr >= addr_max ) - perc = 100; - fprintf(stderr, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bReading 0x%.6x %3d %%", addr, perc); - } + if (data[j] == 0x00) { + null_len++; + } + i += 2; + j++; + } + if (init_scan) { + if (dsize > 0 && addr < dsize) { + fseek(dout, addr, SEEK_SET); + if (fread(line, 1, bsize, dout) == bsize && memcmp(line, data, bsize) == 0) { + dpos = addr; + dbg(2, "%s same at %d\n", TEMP_DATA_BIN, addr); + } else { + dbg(2, "%s differs at %d\n", TEMP_DATA_BIN, addr); + } + } + if (ff_len == j) { // data in sector - we've found max sector.. + addr_max = addr; + dbg(1, "Initial scan done - Download %dkB from device\n", (addr_max+1) >> 10); + } + len = 0; + } else { + if (null_len == j) { // 0x00 block - bad block.... + fprintf(stderr, "FIXME -- read bad block at 0x%.6x - retry ? skip ?\n%s\n", data_addr, line); + } + if (fwrite(data, 1, j, dout) != j) { + fatal(MYNAME ": Failed to write temp. binary file\n"); + } + if (ff_len == j) { // 0xff block - read complete... + len = ff_len; + addr_max = addr; + break; + } else { + len = 0; + } + } + } else if (strncmp(line, "$PMTK001,182,7,", 15) == 0) { // Command ACK + if (line[15] != '3') { + // fixme - we should timeout here when no log data has been received... + dbg(2, "\nLog req. failed (%c)\n", line[15]); + gb_sleep(10*1000); + retry_cnt++; + goto mtk_retry; + } + } + } + } while (len != 0); + if (init_scan) { + addr += 0x10000; + if (addr >= addr_max) { // initial scan complete... + init_scan = 0; + addr = dpos; + } + } else { + addr += bsize; + if (global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5)) { + int perc; + perc = 100 - 100*(addr_max-addr)/addr_max; + if (addr >= addr_max) { + perc = 100; + } + fprintf(stderr, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bReading 0x%.6x %3d %%", addr, perc); } + } + } + if (dout != NULL) { + fclose(dout); + } + if (global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5)) { + fprintf(stderr,"\n"); } - if ( dout != NULL ) - fclose(dout); - if ( global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5) ) - fprintf(stderr,"\n"); // Fixme - Order or. Enable - parse - erase ?? - if ( log_enabled || *OPT_log_enable=='1' ){ - i = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", NULL, 2); - dbg(3, " ---- LOG ENABLE ----%s\n", i==0?"Success":"Fail"); + if (log_enabled || *OPT_log_enable=='1') { + i = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", NULL, 2); + dbg(3, " ---- LOG ENABLE ----%s\n", i==0?"Success":"Fail"); } else { - dbg(1, "Note !!! -- Logging is DISABLED !\n"); + dbg(1, "Note !!! -- Logging is DISABLED !\n"); } - if ( line != NULL ) - xfree(line); - if ( data != NULL ) - xfree(data); - + if (line != NULL) { + xfree(line); + } + if (data != NULL) { + xfree(data); + } + file_init(TEMP_DATA_BIN); file_read(); - file_deinit(); - - /* fixme -- we're assuming all went well - erase flash.... */ - if ( *OPT_erase != '0' ) { - mtk_erase(); - } - - return; + file_deinit(); + + /* fixme -- we're assuming all went well - erase flash.... */ + if (*OPT_erase != '0') { + mtk_erase(); + } + + return; } -static route_head *trk_head = NULL; -static int add_trackpoint(int idx, unsigned long bmask, struct data_item *itm){ - char wp_name[20]; - waypoint *trk = waypt_new(); +static route_head* trk_head = NULL; +static int add_trackpoint(int idx, unsigned long bmask, struct data_item* itm) +{ + char wp_name[20]; + waypoint* trk = waypt_new(); - if ( global_opts.masked_objective & TRKDATAMASK && (trk_head == NULL || (mtk_info.track_event & MTK_EVT_START) ) ){ - char spds[50]; - trk_head = route_head_alloc(); - xasprintf(&trk_head->rte_name, "track-%d", 1+track_count() ); + if (global_opts.masked_objective& TRKDATAMASK && (trk_head == NULL || (mtk_info.track_event & MTK_EVT_START))) { + char spds[50]; + trk_head = route_head_alloc(); + xasprintf(&trk_head->rte_name, "track-%d", 1+track_count()); - spds[0] = '\0'; - if ( mtk_info.speed > 0 ) - sprintf(spds, " when moving above %.0f km/h", mtk_info.speed/10.); - xasprintf(&trk_head->rte_desc, "Log every %.0f sec, %.0f m%s" - , mtk_info.period/10., mtk_info.distance/10., spds); - track_add_head(trk_head); + spds[0] = '\0'; + if (mtk_info.speed > 0) { + sprintf(spds, " when moving above %.0f km/h", mtk_info.speed/10.); } + xasprintf(&trk_head->rte_desc, "Log every %.0f sec, %.0f m%s" + , mtk_info.period/10., mtk_info.distance/10., spds); + track_add_head(trk_head); + } - if ( bmask & (1<latitude = itm->lat; - trk->longitude = itm->lon; - } else { - return -1; // GPX requires lat/lon... - } + if (bmask & (1<latitude = itm->lat; + trk->longitude = itm->lon; + } else { + return -1; // GPX requires lat/lon... + } - if ( bmask & (1<altitude = itm->height; - } - trk->creation_time = itm->timestamp; // in UTC.. - if ( bmask & (1<microseconds = MILLI_TO_MICRO(itm->timestamp_ms); - - if ( bmask & (1<pdop = itm->pdop; - if ( bmask & (1<hdop = itm->hdop; - if ( bmask & (1<vdop = itm->vdop; - - if ( bmask & (1<heading); - } - if ( bmask & (1<speed)); - } - if ( bmask & (1<valid){ - case 0x0040: trk->fix = fix_unknown;break; /* Estimated mode */ - case 0x0001: trk->fix = fix_none; break; /* "No Fix" */ - case 0x0002: trk->fix = fix_3d; break; /* "SPS" - 2d/3d ?*/ - case 0x0004: trk->fix = fix_dgps; break; - case 0x0008: trk->fix = fix_pps; break; /* Military GPS */ - - case 0x0010: /* "RTK" */ - case 0x0020: /* "FRTK" */ - case 0x0080: /* "Manual input mode" */ - case 0x0100: /* "Simulator";*/ - default: - trk->fix = fix_unknown; - break; - } - /* This is a flagrantly bogus position; don't queue it. - * The 747 does log some "real" positions with fix_none, though, - * so keep those. - */ - if ((trk->fix == fix_unknown || trk->fix == fix_none) && - trk->latitude - 90.0 < .000001 && trk->longitude < 0.000001) { - waypt_free(trk); - return -1; - } + if (bmask & (1<altitude = itm->height; + } + trk->creation_time = itm->timestamp; // in UTC.. + if (bmask & (1<microseconds = MILLI_TO_MICRO(itm->timestamp_ms); + } + + if (bmask & (1<pdop = itm->pdop; + } + if (bmask & (1<hdop = itm->hdop; + } + if (bmask & (1<vdop = itm->vdop; + } + + if (bmask & (1<heading); + } + if (bmask & (1<speed)); + } + if (bmask & (1<valid) { + case 0x0040: + trk->fix = fix_unknown; + break; /* Estimated mode */ + case 0x0001: + trk->fix = fix_none; + break; /* "No Fix" */ + case 0x0002: + trk->fix = fix_3d; + break; /* "SPS" - 2d/3d ?*/ + case 0x0004: + trk->fix = fix_dgps; + break; + case 0x0008: + trk->fix = fix_pps; + break; /* Military GPS */ + + case 0x0010: /* "RTK" */ + case 0x0020: /* "FRTK" */ + case 0x0080: /* "Manual input mode" */ + case 0x0100: /* "Simulator";*/ + default: + trk->fix = fix_unknown; + break; } - if ( bmask & (1<sat = itm->sat_used; - - // RCR is a bitmask of possibly several log reasons.. - // Holux devics use a Event prefix for each waypt. - if ( global_opts.masked_objective & WPTDATAMASK - && ( (bmask & (1<rcr & 0x0008) - || (mtk_info.track_event & MTK_EVT_WAYPT) - ) - ) - { - /* Button press -- create waypoint, start count at 1 */ - waypoint *w = waypt_dupe(trk); - - sprintf(wp_name, "WP%06d", waypt_count()+1); - w->shortname = xstrdup(wp_name); - waypt_add(w); + /* This is a flagrantly bogus position; don't queue it. + * The 747 does log some "real" positions with fix_none, though, + * so keep those. + */ + if ((trk->fix == fix_unknown || trk->fix == fix_none) && + trk->latitude - 90.0 < .000001 && trk->longitude < 0.000001) { + waypt_free(trk); + return -1; } - // In theory we would not add the waypoint to the list of - // trackpoints. But as the MTK logger restart the - // log session from the button press we would loose a - // trackpoint unless we include/duplicate it. + } + if (bmask & (1<sat = itm->sat_used; + } - if ( global_opts.masked_objective & TRKDATAMASK ){ - sprintf(wp_name, "TP%06d", idx); - trk->shortname = xstrdup(wp_name); + // RCR is a bitmask of possibly several log reasons.. + // Holux devics use a Event prefix for each waypt. + if (global_opts.masked_objective & WPTDATAMASK + && ((bmask & (1<rcr & 0x0008) + || (mtk_info.track_event & MTK_EVT_WAYPT) + ) + ) { + /* Button press -- create waypoint, start count at 1 */ + waypoint* w = waypt_dupe(trk); + + sprintf(wp_name, "WP%06d", waypt_count()+1); + w->shortname = xstrdup(wp_name); + waypt_add(w); + } + // In theory we would not add the waypoint to the list of + // trackpoints. But as the MTK logger restart the + // log session from the button press we would loose a + // trackpoint unless we include/duplicate it. - track_add_wpt(trk_head, trk); - } - return 0; + if (global_opts.masked_objective & TRKDATAMASK) { + sprintf(wp_name, "TP%06d", idx); + trk->shortname = xstrdup(wp_name); + + track_add_wpt(trk_head, trk); + } + return 0; } /********************** MTK Logger -- CSV output *************************/ -static gbfile *cd; -static void mtk_csv_init(char *csv_fname, unsigned long bitmask){ - int i; - FILE *cf; - - dbg(1, "Opening csv output file %s...\n", csv_fname); - - // can't use gbfopen here - it will fatal() if file doesn't exist - if ( (cf = fopen(csv_fname, "r")) != NULL ) { - fclose(cf); - warning(MYNAME ": CSV file %s already exist ! Cowardly refusing to overwrite.\n", csv_fname); - return; +static gbfile* cd; +static void mtk_csv_init(char* csv_fname, unsigned long bitmask) +{ + int i; + FILE* cf; + + dbg(1, "Opening csv output file %s...\n", csv_fname); + + // can't use gbfopen here - it will fatal() if file doesn't exist + if ((cf = fopen(csv_fname, "r")) != NULL) { + fclose(cf); + warning(MYNAME ": CSV file %s already exist ! Cowardly refusing to overwrite.\n", csv_fname); + return; + } + + if ((cd = gbfopen(csv_fname, "w", MYNAME)) == NULL) { + fatal(MYNAME ": Can't open csv file '%s'\n", csv_fname); + } + + /* Add the header line */ + gbfprintf(cd, "INDEX,%s%s", ((1<timestamp)); - strftime(ts_str, sizeof(ts_str)-1, "%Y/%m/%d,%H:%M:%S", ts_tm); - - if ( bmask & (1<valid){ - case 0x0001: fix_str = "No fix"; break; - case 0x0002: fix_str = "SPS"; break; - case 0x0004: fix_str = "DGPS"; break; - case 0x0008: fix_str = "PPS"; break; /* Military GPS */ - case 0x0010: fix_str = "RTK"; break; /* RealTime Kinematic */ - case 0x0020: fix_str = "FRTK"; break; - case 0x0040: fix_str = "Estimated mode"; break; - case 0x0080: fix_str = "Manual input mode"; break; - case 0x0100: fix_str = "Simulator"; break; - default: fix_str = "???"; break; - } - } - gbfprintf(csvFile, "%d,", idx); - - // RCR is a bitmask of possibly several log reasons.. - if ( bmask & (1<rcr&0x0001?"T":"",itm->rcr&0x0002?"S":"" - , itm->rcr&0x0004?"D":"",itm->rcr&0x0008?"B":""); - - if ( bmask & (1<timestamp_ms:0); - - if ( bmask & (1<lat), itm->lat>0?'N':'S', - fabs(itm->lon), itm->lon>0?'E':'W'); - - if ( bmask & (1<height); - - if ( bmask & (1<speed); - - if ( bmask & (1<heading); - - if ( bmask & (1<dsta); - if ( bmask & (1<dage); - - if ( bmask & (1<pdop); - if ( bmask & (1<hdop); // note bug in MTK appl. 1.02 is output as 1.2 ! - if ( bmask & (1<vdop); - if ( bmask & (1<sat_used, itm->sat_view); - - if ( bmask & (1<sat_count;l++){ - slen = 0; - slen += sprintf(&sstr[slen], "%s%.2d" - , itm->sat_data[l].used?"#":"" - , itm->sat_data[l].id); - if ( bmask & (1<sat_data[l].elevation); - if ( bmask & (1<sat_data[l].azimut); - if ( bmask & (1<sat_data[l].snr); - - gbfprintf(csvFile, "%s%s" , do_sc?";":"", sstr); - do_sc = 1; +static int csv_line(gbfile* csvFile, int idx, unsigned long bmask, struct data_item* itm) +{ + struct tm* ts_tm; + char ts_str[30]; + const char* fix_str = ""; + + ts_tm = gmtime(&(itm->timestamp)); + strftime(ts_str, sizeof(ts_str)-1, "%Y/%m/%d,%H:%M:%S", ts_tm); + + if (bmask & (1<valid) { + case 0x0001: + fix_str = "No fix"; + break; + case 0x0002: + fix_str = "SPS"; + break; + case 0x0004: + fix_str = "DGPS"; + break; + case 0x0008: + fix_str = "PPS"; + break; /* Military GPS */ + case 0x0010: + fix_str = "RTK"; + break; /* RealTime Kinematic */ + case 0x0020: + fix_str = "FRTK"; + break; + case 0x0040: + fix_str = "Estimated mode"; + break; + case 0x0080: + fix_str = "Manual input mode"; + break; + case 0x0100: + fix_str = "Simulator"; + break; + default: + fix_str = "???"; + break; + } + } + gbfprintf(csvFile, "%d,", idx); + + // RCR is a bitmask of possibly several log reasons.. + if (bmask & (1<rcr&0x0001?"T":"",itm->rcr&0x0002?"S":"" + , itm->rcr&0x0004?"D":"",itm->rcr&0x0008?"B":""); + + if (bmask & (1<timestamp_ms:0); + } + + if (bmask & (1<lat), itm->lat>0?'N':'S', + fabs(itm->lon), itm->lon>0?'E':'W'); + + if (bmask & (1<height); + } + + if (bmask & (1<speed); + } + + if (bmask & (1<heading); + } + + if (bmask & (1<dsta); + } + if (bmask & (1<dage); + } + + if (bmask & (1<pdop); + } + if (bmask & (1<hdop); // note bug in MTK appl. 1.02 is output as 1.2 ! + } + if (bmask & (1<vdop); + } + if (bmask & (1<sat_used, itm->sat_view); + } + + if (bmask & (1<sat_count; l++) { + slen = 0; + slen += sprintf(&sstr[slen], "%s%.2d" + , itm->sat_data[l].used?"#":"" + , itm->sat_data[l].id); + if (bmask & (1<sat_data[l].elevation); + } + if (bmask & (1<sat_data[l].azimut); } - gbfprintf(csvFile, ","); - } - - if ( bmask & (1<distance); - - gbfprintf(csvFile, "\n"); - return 0; + if (bmask & (1<sat_data[l].snr); + } + + gbfprintf(csvFile, "%s%s" , do_sc?";":"", sstr); + do_sc = 1; + } + gbfprintf(csvFile, ","); + } + + if (bmask & (1<distance); + } + + gbfprintf(csvFile, "\n"); + return 0; } /********************* MTK Logger -- Parse functions *********************/ -int mtk_parse(unsigned char *data, int dataLen, unsigned int bmask){ - static int count = 0; - int i, k, sat_id, hspd; - unsigned char crc, hbuf[4]; - struct data_item itm; - - dbg(5,"Entering mtk_parse, count = %i, dataLen = %i\n", count, dataLen); - if ( global_opts.debug_level > 5 ) { - int j; - fprintf(stderr,"# Data block:"); - for(j=0;j 32 ) - sat_count = 32; // this can't happen ? or... - - itm.sat_count = sat_count; - sid_size = log_type[SID].size; - if ( sat_count > 0 ){ // handle 'Zero satellites in view issue' - if ( bmask & (1< 0 ){ - if ( bmask & (1< 0 ); - } - continue; // dont do any more checksum calc.. - break; - case 1< 5) { + int j; + fprintf(stderr,"# Data block:"); + for (j=0; j 32) { + sat_count = 32; // this can't happen ? or... + } + + itm.sat_count = sat_count; + sid_size = log_type[SID].size; + if (sat_count > 0) { // handle 'Zero satellites in view issue' + if (bmask & (1< 0) { + if (bmask & (1< 0); + } + continue; // dont do any more checksum calc.. + break; + case 1<= 16 - && memcmp(&data[0], &LOG_RST[0], 6) == 0 - && memcmp(&data[12], &LOG_RST[12], 4) == 0 ) - { - - cmd = le_read16(data + 8); - switch ( data[7] ){ - case 0x02: - bm = le_read32(data + 8); - dbg(1, "# Log bitmask is: %.8x\n", bm); - if ( mtk_device != MTK_LOGGER ) - bm &= 0x7fffffffU; - if ( mtk_device == HOLUX_GR245 ) - bm &= ~HOLUX245_MASK; - if ( mtk_info.bitmask != bm ){ - dbg(1," ########## Bitmask Change %.8x -> %.8x ###########\n", mtk_info.bitmask, bm); - mtk_info.track_event |= MTK_EVT_BITMASK; - } - mtk_info.bitmask = bm; - mtk_info.logLen = mtk_log_len(mtk_info.bitmask); - break; - case 0x03: - dbg(1, "# Log period change %.0f sec\n", cmd/10.); - mtk_info.track_event |= MTK_EVT_PERIOD; - mtk_info.period = cmd; - break; - case 0x04: - dbg(1, "# Log distance change %.1f m\n", cmd/10.); - mtk_info.track_event |= MTK_EVT_DISTANCE; - mtk_info.distance = cmd; - break; - case 0x05: - dbg(1, "# Log speed change %.1f km/h\n", cmd/10.); - mtk_info.track_event |= MTK_EVT_SPEED; - mtk_info.speed = cmd; - break; - case 0x06: - dbg(1, "# Log policy change 0x%.4x\n", cmd); - if ( cmd == 0x01 ) - dbg(1, "# Log policy change to OVERWRITE\n"); - if ( cmd == 0x02 ) - dbg(1, "# Log policy change to STOP\n"); - break; - case 0x07: - if ( cmd == 0x0106 ){ - dbg(5, "# GPS Logger# Turned On\n"); // Fixme - start new trk - mtk_info.track_event |= MTK_EVT_START; - } - if ( cmd == 0x0104 ) - dbg(5, "# GPS Logger# Log disabled\n"); - break; - default: - dbg(1, "## Unknown INFO 0x%.2x\n", data[7]); - break; +static int mtk_parse_info(const unsigned char* data, int dataLen) +{ + unsigned short cmd; + unsigned int bm; + + if (dataLen >= 16 + && memcmp(&data[0], &LOG_RST[0], 6) == 0 + && memcmp(&data[12], &LOG_RST[12], 4) == 0) { + + cmd = le_read16(data + 8); + switch (data[7]) { + case 0x02: + bm = le_read32(data + 8); + dbg(1, "# Log bitmask is: %.8x\n", bm); + if (mtk_device != MTK_LOGGER) { + bm &= 0x7fffffffU; + } + if (mtk_device == HOLUX_GR245) { + bm &= ~HOLUX245_MASK; + } + if (mtk_info.bitmask != bm) { + dbg(1," ########## Bitmask Change %.8x -> %.8x ###########\n", mtk_info.bitmask, bm); + mtk_info.track_event |= MTK_EVT_BITMASK; } - } else { - if ( global_opts.debug_level > 0 ){ - fprintf(stderr,"#!! Invalid INFO block !! %d bytes\n >> ", dataLen); - for (bm=0;bm<16;bm++) fprintf(stderr, "%.2x ", data[bm]); - fprintf(stderr,"\n"); + mtk_info.bitmask = bm; + mtk_info.logLen = mtk_log_len(mtk_info.bitmask); + break; + case 0x03: + dbg(1, "# Log period change %.0f sec\n", cmd/10.); + mtk_info.track_event |= MTK_EVT_PERIOD; + mtk_info.period = cmd; + break; + case 0x04: + dbg(1, "# Log distance change %.1f m\n", cmd/10.); + mtk_info.track_event |= MTK_EVT_DISTANCE; + mtk_info.distance = cmd; + break; + case 0x05: + dbg(1, "# Log speed change %.1f km/h\n", cmd/10.); + mtk_info.track_event |= MTK_EVT_SPEED; + mtk_info.speed = cmd; + break; + case 0x06: + dbg(1, "# Log policy change 0x%.4x\n", cmd); + if (cmd == 0x01) { + dbg(1, "# Log policy change to OVERWRITE\n"); } - return 0; - } - return 16; + if (cmd == 0x02) { + dbg(1, "# Log policy change to STOP\n"); + } + break; + case 0x07: + if (cmd == 0x0106) { + dbg(5, "# GPS Logger# Turned On\n"); // Fixme - start new trk + mtk_info.track_event |= MTK_EVT_START; + } + if (cmd == 0x0104) { + dbg(5, "# GPS Logger# Log disabled\n"); + } + break; + default: + dbg(1, "## Unknown INFO 0x%.2x\n", data[7]); + break; + } + } else { + if (global_opts.debug_level > 0) { + fprintf(stderr,"#!! Invalid INFO block !! %d bytes\n >> ", dataLen); + for (bm=0; bm<16; bm++) { + fprintf(stderr, "%.2x ", data[bm]); + } + fprintf(stderr,"\n"); + } + return 0; + } + return 16; } -static int mtk_log_len(unsigned int bitmask){ - int i, len; - - /* calculate the length of a binary log item. */ - switch ( mtk_device ){ - case HOLUX_M241: - case HOLUX_GR245: - len = 1; // add crc - break; - case MTK_LOGGER: - default: - len = 2; // add '*' + crc - break; - } - for (i=0;i<32;i++){ - if ( (1< DISTANCE && global_opts.debug_level > 0 ) - warning(MYNAME ": Unknown size/meaning of bit %d\n", i); - if ( (i == SID || i == ELEVATION || i == AZIMUTH || i == SNR) && (1< DISTANCE && global_opts.debug_level > 0) { + warning(MYNAME ": Unknown size/meaning of bit %d\n", i); + } + if ((i == SID || i == ELEVATION || i == AZIMUTH || i == SNR) && (1<= 5 && - data[0] == (0xff & 'H') && - data[1] == (0xff & 'O') && - data[2] == (0xff & 'L') && - data[3] == (0xff & 'U') && - data[4] == (0xff & 'X') ) { - return 1; - } - return 0; +static int is_holux_string(const unsigned char* data, int dataLen) +{ + if (mtk_device != MTK_LOGGER && + dataLen >= 5 && + data[0] == (0xff & 'H') && + data[1] == (0xff & 'O') && + data[2] == (0xff & 'L') && + data[3] == (0xff & 'U') && + data[4] == (0xff & 'X')) { + return 1; + } + return 0; } -static void file_read(void) { - long fsize, pos; - int i, j, k, bLen; - unsigned char buf[512]; - - memset(buf, '\0', sizeof(buf)); - - /* Get size of file to parse */ - fseek(fl, 0L, SEEK_END); - fsize = ftell(fl); - if ( fsize <= 0 ) - fatal(MYNAME ": File has size %ld\n", fsize); - - fseek(fl, 0L, SEEK_SET); - - /* Header: 20 bytes - 47 05 | 7f 1e 0e 00 | 04 01 | 32 00 00 00 e8 03 00 00 00 00 00 00 - - u16: Log count 'this 64kByte block' - ffff if not complete. - u32: Bitmask for logging. (default mask) - u16; ?? ?? Overwrite/Stop policy - u32: log period, sec*10 - u32: log distance , meters*10 - u32: log speed , km/h*10 - */ - - bLen = 0; - j = 0; - pos = 0; - - /* get default bitmask, log period/speed/distance */ - bLen = fread(buf, 1, 20, fl); - if ( bLen == 20 ){ - unsigned int mask, log_period, log_distance, log_speed, log_policy; +static void file_read(void) +{ + long fsize, pos; + int i, j, k, bLen; + unsigned char buf[512]; + + memset(buf, '\0', sizeof(buf)); + + /* Get size of file to parse */ + fseek(fl, 0L, SEEK_END); + fsize = ftell(fl); + if (fsize <= 0) { + fatal(MYNAME ": File has size %ld\n", fsize); + } + + fseek(fl, 0L, SEEK_SET); + + /* Header: 20 bytes + 47 05 | 7f 1e 0e 00 | 04 01 | 32 00 00 00 e8 03 00 00 00 00 00 00 + + u16: Log count 'this 64kByte block' - ffff if not complete. + u32: Bitmask for logging. (default mask) + u16; ?? ?? Overwrite/Stop policy + u32: log period, sec*10 + u32: log distance , meters*10 + u32: log speed , km/h*10 + */ + + bLen = 0; + j = 0; + pos = 0; + + /* get default bitmask, log period/speed/distance */ + bLen = fread(buf, 1, 20, fl); + if (bLen == 20) { + unsigned int mask, log_period, log_distance, log_speed, log_policy; + log_policy = le_read16(buf + 6); + + if (!(log_policy == 0x0104 || log_policy == 0x0106) && fsize > 0x10000) { + dbg(1, "Invalid initial log policy 0x%.4x - check next block\n", log_policy); + fseek(fl, 0x10000, SEEK_SET); + bLen = fread(buf, 1, 20, fl); log_policy = le_read16(buf + 6); + } + mask = le_read32(buf + 2); + if (mtk_device != MTK_LOGGER) { // clear Holux-specific 'low precision' bit + mask &= 0x7fffffffU; + } + log_period = le_read32(buf + 8); + log_distance = le_read32(buf + 12); + log_speed = le_read32(buf + 16); + + dbg(1, "Default Bitmask %.8x, Log every %.0f sec, %.0f m, %.0f km/h\n", + mask, log_period/10., log_distance/10., log_speed/10.); + mtk_info.bitmask = mask; + dbg(3, "Using initial bitmask %.8x for parsing the .bin file\n", mtk_info.bitmask); + + mtk_info.period = log_period; + mtk_info.distance = log_distance; + mtk_info.speed = log_speed; + } + mtk_info.track_event = 0; + + pos = 0x200; // skip header...first data position + fseek(fl, pos, SEEK_SET); + + /* read initial info blocks -- if any */ + do { + bLen = fread(buf, 1, 16, fl); + j = 0; + if (buf[0] == 0xaa) { // pre-validate to avoid error... + j = mtk_parse_info(buf, bLen); + pos += j; + } else if (is_holux_string(buf, bLen)) { + pos += j; + // Note -- Holux245 will have here...handled below.. + } + } while (j == 16); + j = bLen; + pos += j; + + mtk_info.logLen = mtk_log_len(mtk_info.bitmask); + dbg(3, "Log item size %d bytes\n", mtk_info.logLen); + if (csv_file && *csv_file) { + mtk_csv_init(csv_file, mtk_info.bitmask); + } - if ( !(log_policy == 0x0104 || log_policy == 0x0106) && fsize > 0x10000 ){ - dbg(1, "Invalid initial log policy 0x%.4x - check next block\n", log_policy); - fseek(fl, 0x10000, SEEK_SET); - bLen = fread(buf, 1, 20, fl); - log_policy = le_read16(buf + 6); - } - mask = le_read32(buf + 2); - if ( mtk_device != MTK_LOGGER ) { // clear Holux-specific 'low precision' bit - mask &= 0x7fffffffU; - } - log_period = le_read32(buf + 8); - log_distance = le_read32(buf + 12); - log_speed = le_read32(buf + 16); - - dbg(1, "Default Bitmask %.8x, Log every %.0f sec, %.0f m, %.0f km/h\n", - mask, log_period/10., log_distance/10., log_speed/10.); - mtk_info.bitmask = mask; - dbg(3, "Using initial bitmask %.8x for parsing the .bin file\n", mtk_info.bitmask); - - mtk_info.period = log_period; - mtk_info.distance = log_distance; - mtk_info.speed = log_speed; - } - mtk_info.track_event = 0; - - pos = 0x200; // skip header...first data position - fseek(fl, pos, SEEK_SET); - - /* read initial info blocks -- if any */ - do { - bLen = fread(buf, 1, 16, fl); - j = 0; - if ( buf[0] == 0xaa ){ // pre-validate to avoid error... - j = mtk_parse_info(buf, bLen); - pos += j; - } else if ( is_holux_string(buf, bLen) ) { - pos += j; - // Note -- Holux245 will have here...handled below.. - } - } while ( j == 16 ); - j = bLen; - pos += j; - - mtk_info.logLen = mtk_log_len(mtk_info.bitmask); - dbg(3, "Log item size %d bytes\n", mtk_info.logLen); - if ( csv_file && *csv_file ) - mtk_csv_init(csv_file, mtk_info.bitmask); - - while ( pos < fsize && (bLen = fread(&buf[j], 1, sizeof(buf)-j, fl)) > 0 ){ - bLen += j; - i = 0; - while ( (bLen - i) >= mtk_info.logLen ){ - k = 0; - if ( (bLen - i) >= 16 && memcmp(&buf[i], &LOG_RST[0], 6) == 0 - && memcmp(&buf[i+12], &LOG_RST[12], 4) == 0 ) - { - mtk_parse_info(&buf[i], (bLen-i)); - k = 16; - } else if ( is_holux_string(&buf[i], (bLen - i)) ) { - if ( memcmp(&buf[i+10], "WAYPNT", 6) == 0 ) - mtk_info.track_event |= MTK_EVT_WAYPT; - - k = 16; - // m241 - HOLUXGR241LOGGER or HOLUXGR241WAYPNT or HOLUXGR241LOGGER - // gr245 - HOLUXGR245LOGGER or HOLUXGR245WAYPNT - if (memcmp(&buf[i], "HOLUXGR245", 10) == 0) { - dbg(2, "Detected Holux GR245 !\n"); - holux245_init(); - } + while (pos < fsize && (bLen = fread(&buf[j], 1, sizeof(buf)-j, fl)) > 0) { + bLen += j; + i = 0; + while ((bLen - i) >= mtk_info.logLen) { + k = 0; + if ((bLen - i) >= 16 && memcmp(&buf[i], &LOG_RST[0], 6) == 0 + && memcmp(&buf[i+12], &LOG_RST[12], 4) == 0) { + mtk_parse_info(&buf[i], (bLen-i)); + k = 16; + } else if (is_holux_string(&buf[i], (bLen - i))) { + if (memcmp(&buf[i+10], "WAYPNT", 6) == 0) { + mtk_info.track_event |= MTK_EVT_WAYPT; + } - // skip the 4 spaces that may occur on every device - if ( memcmp(&buf[i+16], " ", 4) == 0 ){ // Assume loglen >= 20... - k += 4; - } - } else if ( buf[i] == 0xff && buf[i+1] == 0xff && buf[i+2] == 0xff && buf[i+3] == 0xff - /* && ((pos + 2*mtk_info.logLen) & 0xffff) < mtk_info.logLen */ ) - { - /* End of 64k block segment -- realign to next data area */ - - k = ((pos+mtk_info.logLen+1024)/0x10000) *0x10000 + 0x200; - i = sizeof(buf); - if ( k <= pos ) { - k += 0x10000; - } - dbg(3, "Jump %ld -> %d / 0x%.6x (fsize %ld) --- \n", pos, k, k, fsize); - if ( k > fsize ){ - dbg(3, "File parse complete !\n"); - pos = k; - break; - } else { - fseek(fl, k, SEEK_SET); - } - pos = k; - continue; - } else { - k = mtk_parse(&buf[i], mtk_info.logLen, mtk_info.bitmask); - } - - i += k; - pos += k; + k = 16; + // m241 - HOLUXGR241LOGGER or HOLUXGR241WAYPNT or HOLUXGR241LOGGER + // gr245 - HOLUXGR245LOGGER or HOLUXGR245WAYPNT + if (memcmp(&buf[i], "HOLUXGR245", 10) == 0) { + dbg(2, "Detected Holux GR245 !\n"); + holux245_init(); + } + + // Tobias Verbree reports that an M-12ee is like a 245. + if (memcmp(&buf[i], "HOLUXM1200", 10) == 0) { + dbg(2, "Detected Holux HOLUXM1200 !\n"); + holux245_init(); + } + + // skip the 4 spaces that may occur on every device + if (memcmp(&buf[i+16], " ", 4) == 0) { // Assume loglen >= 20... + k += 4; + } + } else if (buf[i] == 0xff && buf[i+1] == 0xff && buf[i+2] == 0xff && buf[i+3] == 0xff + /* && ((pos + 2*mtk_info.logLen) & 0xffff) < mtk_info.logLen */) { + /* End of 64k block segment -- realign to next data area */ + + k = ((pos+mtk_info.logLen+1024)/0x10000) *0x10000 + 0x200; + i = sizeof(buf); + if (k <= pos) { + k += 0x10000; + } + dbg(3, "Jump %ld -> %d / 0x%.6x (fsize %ld) --- \n", pos, k, k, fsize); + if (k > fsize) { + dbg(3, "File parse complete !\n"); + pos = k; + break; + } else { + fseek(fl, k, SEEK_SET); + } + pos = k; + continue; + } else { + k = mtk_parse(&buf[i], mtk_info.logLen, mtk_info.bitmask); } - memmove(buf, &buf[i], sizeof(buf)-i); - j = sizeof(buf)-i; - } - mtk_csv_deinit(); + + i += k; + pos += k; + } + memmove(buf, &buf[i], sizeof(buf)-i); + j = sizeof(buf)-i; + } + mtk_csv_deinit(); } @@ -1465,77 +1591,79 @@ static void file_read(void) { // GPS logger will only handle tracks - neither waypoints or tracks... ff_vecs_t mtk_vecs = { - ff_type_serial, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - mtk_rd_init, - NULL, - mtk_rd_deinit, - NULL, - mtk_read, - NULL, - NULL, - mtk_sargs, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + mtk_rd_init, + NULL, + mtk_rd_deinit, + NULL, + mtk_read, + NULL, + NULL, + mtk_sargs, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; ff_vecs_t mtk_m241_vecs = { - ff_type_serial, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - mtk_rd_init_m241, - NULL, - mtk_rd_deinit, - NULL, - mtk_read, - NULL, - NULL, - mtk_sargs, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + mtk_rd_init_m241, + NULL, + mtk_rd_deinit, + NULL, + mtk_read, + NULL, + NULL, + mtk_sargs, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /* used for mtk-bin */ static arglist_t mtk_fargs[] = { - { "csv", &csv_file, "MTK compatible CSV output file", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "csv", &csv_file, "MTK compatible CSV output file", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t mtk_fvecs = { - ff_type_file, - { ff_cap_read, ff_cap_read, ff_cap_none }, - file_init, - NULL, - file_deinit, - NULL, - file_read, - NULL, - NULL, - mtk_fargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_none }, + file_init, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + mtk_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; ff_vecs_t mtk_m241_fvecs = { - ff_type_file, - { ff_cap_read, ff_cap_read, ff_cap_none }, - file_init_m241, - NULL, - file_deinit, - NULL, - file_read, - NULL, - NULL, - mtk_fargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_none }, + file_init_m241, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + mtk_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; /* End file: mtk_logger.c */ /**************************************************************************/ diff --git a/gpsbabel/navicache.c b/gpsbabel/navicache.c index 5e416e798..1d9b9eaa4 100644 --- a/gpsbabel/navicache.c +++ b/gpsbabel/navicache.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2003 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -23,27 +23,30 @@ static XML_Parser psr; #endif -static waypoint *wpt_tmp; +static waypoint* wpt_tmp; -static gbfile *fin, *fout; +static gbfile* fin, *fout; -static char *noretired = NULL; +static char* noretired = NULL; static arglist_t nav_args[] = { - {"noretired", &noretired, "Suppress retired geocaches", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "noretired", &noretired, "Suppress retired geocaches", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #define MYNAME "navicache" #define MY_CBUF 4096 +#define NC_URL "http://www.navicache.com/cgi-bin/db/displaycache2.pl?CacheID=" #if ! HAVE_LIBEXPAT static void -nav_rd_init(const char *fname) +nav_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); } static void @@ -53,191 +56,184 @@ nav_read(void) #else static struct -nc_type_mapping{ - geocache_type type; - const char *name; + nc_type_mapping { + geocache_type type; + const char* name; } nc_type_map[] = { - { gt_unknown, "unknown" }, - { gt_traditional, "normal" }, - { gt_multi, "Multi-part" }, - { gt_virtual, "Virtual" }, - { gt_event, "event" } + { gt_unknown, "unknown" }, + { gt_traditional, "normal" }, + { gt_multi, "Multi-part" }, + { gt_virtual, "Virtual" }, + { gt_event, "event" } }; static struct -nc_container_mapping{ - geocache_container type; - const char *name; + nc_container_mapping { + geocache_container type; + const char* name; } nc_container_map[] = { - { gc_other, "Unknown" }, - { gc_micro, "Micro" }, - { gc_regular, "Normal" }, - { gc_large, "Large" }, - { gc_virtual, "Virtual" } + { gc_other, "Unknown" }, + { gc_micro, "Micro" }, + { gc_regular, "Normal" }, + { gc_large, "Large" }, + { gc_virtual, "Virtual" } }; static geocache_type -nc_mktype(const char *t) +nc_mktype(const char* t) { - int i; - int sz = sizeof(nc_type_map) / sizeof(nc_type_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, nc_type_map[i].name)) { - return nc_type_map[i].type; - } - } - return gt_unknown; + int i; + int sz = sizeof(nc_type_map) / sizeof(nc_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, nc_type_map[i].name)) { + return nc_type_map[i].type; + } + } + return gt_unknown; } static geocache_container -nc_mkcont(const char *t) +nc_mkcont(const char* t) { - int i; - int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) { - return nc_container_map[i].type; - } - } - return gc_unknown; + int i; + int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) { + return nc_container_map[i].type; + } + } + return gc_unknown; } static void -nav_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) +nav_start(void* data, const XML_Char* xml_el, const XML_Char** xml_attr) { - const char *el; - const char **attr; - - el = xml_convert_to_char_string(xml_el); - attr = xml_convert_attrs_to_char_string(xml_attr); - if (0 == strcmp(el, "CacheDetails")) { - const char **ap; - geocache_data *gc_data; - wpt_tmp = waypt_new(); - gc_data = waypt_alloc_gc_data(wpt_tmp); - - for (ap = attr; *ap; ap+=2) { - if (0 == strcmp(ap[0], "cache_id")) { - wpt_tmp->shortname = xstrdup(ap[1]); - } else - if (0 == strcmp(ap[0], "name")) { - wpt_tmp->description = xstrdup(ap[1]); - } else - if (0 == strcmp(ap[0], "latitude")) { - sscanf(ap[1], "%lf", - &wpt_tmp->latitude); - } else - if (0 == strcmp(ap[0], "longitude")) { - sscanf(ap[1], "%lf", - &wpt_tmp->longitude); - } else - if (0 == strcmp(ap[0], "longitude")) { - sscanf(ap[1], "%lf", - &wpt_tmp->longitude); - } else - if (0 == strcmp(ap[0], "difficulty")) { - float x; - sscanf(ap[1], "%f", &x); - gc_data->diff = x * 10; - } else - if (0 == strcmp(ap[0], "terrain")) { - float x; - sscanf(ap[1], "%f", &x); - gc_data->terr = x * 10; - } else - if (0 == strcmp(ap[0], "cache_type")) { - static char buf[512]; - - gc_data->type = nc_mktype(ap[1]); - if (!strcmp(ap[1], "normal")) - wpt_tmp->icon_descr = "Geocache-regular"; - else if (!strcmp(ap[1], "multi-part")) - wpt_tmp->icon_descr = "Geocache-multi"; - else if (!strcmp(ap[1], "moving_travelling")) - wpt_tmp->icon_descr = "Geocache-moving"; - else { - sprintf(buf, "Geocache-%-.20s", ap[1]); - wpt_tmp->icon_descr = xstrdup(buf); - } - } else - if (0 == strcmp(ap[0], "hidden_date")) { - struct tm tm; - - sscanf(ap[1], "%d-%d-%d", - &tm.tm_year, - &tm.tm_mon, - &tm.tm_mday); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - wpt_tmp->creation_time = mktime(&tm); - } else - if (0 == strcmp(ap[0], "retired")) { - if (!strcmp(ap[1], "yes") && noretired) { - xfree(wpt_tmp); - return; - } - } else - if (0 == strcmp(ap[0], "cache_size")) { - gc_data->container = nc_mkcont(ap[1]); - } else - if (0 == strcmp(ap[0], "description")) { - gc_data->desc_long.is_html = 1; - gc_data->desc_long.utfstring = xstrdup(ap[1]); - } else - if (0 == strcmp(ap[0], "comments")) { - gc_data->desc_short.is_html = 1; - gc_data->desc_short.utfstring = xstrdup(ap[1]); - } - } - waypt_add(wpt_tmp); - } - - xml_free_converted_attrs(attr); - xml_free_converted_string(el); + const char* el; + const char** attr; + + el = xml_convert_to_char_string(xml_el); + attr = xml_convert_attrs_to_char_string(xml_attr); + if (0 == strcmp(el, "CacheDetails")) { + const char** ap; + geocache_data* gc_data; + wpt_tmp = waypt_new(); + gc_data = waypt_alloc_gc_data(wpt_tmp); + + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "cache_id")) { + int id; + + id = atoi(ap[1]); + xasprintf(&wpt_tmp->shortname, "N%05X", id); + xasprintf(&wpt_tmp->url, "%s%d", NC_URL, id); + } else if (0 == strcmp(ap[0], "name")) { + wpt_tmp->description = xstrdup(ap[1]); + } else if (0 == strcmp(ap[0], "user_name")) { + gc_data->placer = xstrdup(ap[1]); + } else if (0 == strcmp(ap[0], "latitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->latitude); + } else if (0 == strcmp(ap[0], "longitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->longitude); + } else if (0 == strcmp(ap[0], "longitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->longitude); + } else if (0 == strcmp(ap[0], "difficulty")) { + float x; + sscanf(ap[1], "%f", &x); + gc_data->diff = x * 10; + } else if (0 == strcmp(ap[0], "terrain")) { + float x; + sscanf(ap[1], "%f", &x); + gc_data->terr = x * 10; + } else if (0 == strcmp(ap[0], "cache_type")) { + gc_data->type = nc_mktype(ap[1]); + if (!strcmp(ap[1], "normal")) { + wpt_tmp->icon_descr = "Geocache-regular"; + } else if (!strcmp(ap[1], "multi-part")) { + wpt_tmp->icon_descr = "Geocache-multi"; + } else if (!strcmp(ap[1], "moving_travelling")) { + wpt_tmp->icon_descr = "Geocache-moving"; + } else { + // WARNING: casting away const-ness. + xasprintf((char**)&wpt_tmp->icon_descr, + "Geocache-%-.20s", ap[1]); + } + } else if (0 == strcmp(ap[0], "hidden_date")) { + struct tm tm; + + sscanf(ap[1], "%d-%d-%d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + wpt_tmp->creation_time = mktime(&tm); + } else if (0 == strcmp(ap[0], "retired")) { + if (!strcmp(ap[1], "yes") && noretired) { + xfree(wpt_tmp); + return; + } + } else if (0 == strcmp(ap[0], "cache_size")) { + gc_data->container = nc_mkcont(ap[1]); + } else if (0 == strcmp(ap[0], "description")) { + gc_data->desc_long.is_html = 1; + gc_data->desc_long.utfstring = xstrdup(ap[1]); + } else if (0 == strcmp(ap[0], "comments")) { + gc_data->desc_short.is_html = 1; + gc_data->desc_short.utfstring = xstrdup(ap[1]); + } + } + waypt_add(wpt_tmp); + } + + xml_free_converted_attrs(attr); + xml_free_converted_string(el); } static void -nav_end(void *data, const XML_Char *el) +nav_end(void* data, const XML_Char* el) { } static void -nav_rd_init(const char *fname) +nav_rd_init(const char* fname) { - fin = gbfopen(fname, "r", MYNAME); + fin = gbfopen(fname, "r", MYNAME); - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ":Cannot create XML parser\n"); - } + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - XML_SetElementHandler(psr, nav_start, nav_end); + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, nav_start, nav_end); } static void nav_read(void) { - int len; - char buf[MY_CBUF]; - - while ((len = gbfread(buf, 1, sizeof(buf), fin))) { - if (!XML_Parse(psr, buf, len, gbfeof(fin))) { - fatal(MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - } - - XML_ParserFree(psr); + int len; + char buf[MY_CBUF]; + + while ((len = gbfread(buf, 1, sizeof(buf), fin))) { + if (!XML_Parse(psr, buf, len, gbfeof(fin))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + + XML_ParserFree(psr); } #endif @@ -245,20 +241,20 @@ nav_read(void) static void nav_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void -nav_wr_init(const char *fname) +nav_wr_init(const char* fname) { - fatal(MYNAME ": Does not support writing Navicache files.\n"); - fout = gbfopen(fname, "w", MYNAME); + fatal(MYNAME ": Does not support writing Navicache files.\n"); + fout = gbfopen(fname, "w", MYNAME); } static void nav_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void @@ -267,15 +263,15 @@ nav_write(void) } ff_vecs_t navicache_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_none, ff_cap_none }, - nav_rd_init, - nav_wr_init, - nav_rd_deinit, - nav_wr_deinit, - nav_read, - nav_write, - NULL, - nav_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_none }, + nav_rd_init, + nav_wr_init, + nav_rd_deinit, + nav_wr_deinit, + nav_read, + nav_write, + NULL, + nav_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/naviguide.c b/gpsbabel/naviguide.c index bdcb701ca..80be9bdb3 100755 --- a/gpsbabel/naviguide.c +++ b/gpsbabel/naviguide.c @@ -1,6 +1,6 @@ /* Naviguide Routes - + Copyright (C) 2009 Erez Zuler @@ -24,7 +24,7 @@ #include "csv_util.h" #include "jeeps/gpsmath.h" #include -#include +#include #define MYNAME "Naviguide" @@ -37,41 +37,41 @@ /* Naviguide file header */ typedef struct { - gbuint16 nof_wp; /* Little endean format */ - char pad1[6]; /* 0xff, 0xff, 0x01, 0x00, 0x06, 0x00 */ - char signature[9]; /* cWaypoint */ - char pad2[4]; /* 0x01, 0x00, 0x00, 0x00 */ + gbuint16 nof_wp; /* Little endean format */ + char pad1[6]; /* 0xff, 0xff, 0x01, 0x00, 0x06, 0x00 */ + char signature[9]; /* cWaypoint */ + char pad2[4]; /* 0x01, 0x00, 0x00, 0x00 */ } ng_file_header_t; /* Naviguide waypoint/rout data */ -typedef struct{ - char pad1[8]; /* 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 */ - /* coordination are in old israeli grid */ - gbuint32 East; - gbuint32 North; - char pad2[2]; /* 0x01, 0x01 */ - gbuint32 Alt; - char CommentLength; +typedef struct { + char pad1[8]; /* 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 */ + /* coordination are in old israeli grid */ + gbuint32 East; + gbuint32 North; + char pad2[2]; /* 0x01, 0x01 */ + gbuint32 Alt; + char CommentLength; } ng_wp_data_t; -typedef struct{ - char pad1[2]; /* 0x01, 0x80 */ - gbuint16 next_wp; - char pad2[2]; /* 0x00, 0x00 */ +typedef struct { + char pad1[2]; /* 0x01, 0x80 */ + gbuint16 next_wp; + char pad2[2]; /* 0x00, 0x00 */ } ng_next_wp_t; typedef struct { - unsigned char chHeaderLen; - char strName[255]; - ng_wp_data_t wp_data; + unsigned char chHeaderLen; + char strName[255]; + ng_wp_data_t wp_data; } ng_wp_no_comment_t; /* Global variables */ -static gbfile *file_in, *file_out; +static gbfile* file_in, *file_out; static gbuint16 nof_wp; -static route_head *rte_head; +static route_head* rte_head; static ng_file_header_t ng_file_header; static ng_wp_no_comment_t WPNC; static ng_next_wp_t ng_next_wp; @@ -81,8 +81,8 @@ static char strComment[101]; /* wp - process only waypoints */ /* rte - process as route */ /* wprte - Process waypoints and route */ -static char *process = NULL; -static char *reorder = NULL; +static char* process = NULL; +static char* reorder = NULL; static int process_rte = 1; static int reorder_wp = 0; @@ -96,29 +96,33 @@ static void ng_read_file_header(void); static arglist_t ng_args[] = { - {"output", &process, "'wp' - Create waypoint file , 'rte' - Create route file", - "rte", ARGTYPE_STRING, ARG_NOMINMAX}, - {"reorder", &reorder, "'n' - Keep the existing wp name, 'y' - rename waypoints", - "n", ARGTYPE_STRING, ARG_NOMINMAX}, - - ARG_TERMINATOR + { + "output", &process, "'wp' - Create waypoint file , 'rte' - Create route file", + "rte", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "reorder", &reorder, "'n' - Keep the existing wp name, 'y' - rename waypoints", + "n", ARGTYPE_STRING, ARG_NOMINMAX + }, + + ARG_TERMINATOR }; /*===================Utilities ==========================================*/ static void -ng_convert_datum(waypoint *wpt) +ng_convert_datum(waypoint* wpt) { - double lat, lon, east, north, alt; - - east = (double) WPNC.wp_data.East; - north = (double) WPNC.wp_data.North; - alt = (double) WPNC.wp_data.Alt; - - GPS_Math_ICS_EN_To_WGS84(east, north, &lat, &lon); - wpt->latitude = lat; - wpt->longitude = lon; - wpt->altitude = alt; + double lat, lon, east, north, alt; + + east = (double) WPNC.wp_data.East; + north = (double) WPNC.wp_data.North; + alt = (double) WPNC.wp_data.Alt; + + GPS_Math_ICS_EN_To_WGS84(east, north, &lat, &lon); + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; } @@ -126,208 +130,224 @@ ng_convert_datum(waypoint *wpt) /*=================== File read/write utilities ==========================================*/ static void -ng_fwrite_wp_data (char *s, char *d, ng_wp_data_t *wp_data, gbfile *f) { - int i; - char z[50]; - - memset (z, 0, 50); - - i = (s == NULL) ? 0 : strlen (s); - gbfwrite (&i, 1, 1, f); - gbfwrite (s, 1, i, f); - - gbfwrite (&wp_data->pad1[0], 8, 1, f); - gbfputint32 (wp_data->East, f); - gbfputint32 (wp_data->North, f); - gbfwrite (&wp_data->pad2[0], 2, 1, f); - gbfputint32 (wp_data->Alt, f); - - i = (d == NULL) ? 0 : strlen (d); - gbfwrite (&i, 1, 1, f); - gbfwrite (d, 1, i, f); - gbfwrite (z, 44, 1, f); +ng_fwrite_wp_data(char* s, char* d, ng_wp_data_t* wp_data, gbfile* f) +{ + int i; + char z[50]; + + memset(z, 0, 50); + + i = (s == NULL) ? 0 : strlen(s); + gbfwrite(&i, 1, 1, f); + gbfwrite(s, 1, i, f); + + gbfwrite(&wp_data->pad1[0], 8, 1, f); + gbfputint32(wp_data->East, f); + gbfputint32(wp_data->North, f); + gbfwrite(&wp_data->pad2[0], 2, 1, f); + gbfputint32(wp_data->Alt, f); + + i = (d == NULL) ? 0 : strlen(d); + gbfwrite(&i, 1, 1, f); + gbfwrite(d, 1, i, f); + gbfwrite(z, 44, 1, f); } static void -ng_fwrite_next_wp (ng_next_wp_t *nwp, gbfile *f) { - gbfwrite (nwp->pad1, 2, 1, f); - gbfputint16 (nwp->next_wp, f); - gbfwrite (nwp->pad2, 2, 1, f); +ng_fwrite_next_wp(ng_next_wp_t* nwp, gbfile* f) +{ + gbfwrite(nwp->pad1, 2, 1, f); + gbfputint16(nwp->next_wp, f); + gbfwrite(nwp->pad2, 2, 1, f); } static void -ng_fread_wp_data (char *d, ng_wp_no_comment_t *wpnc, gbfile *f) { +ng_fread_wp_data(char* d, ng_wp_no_comment_t* wpnc, gbfile* f) +{ + + int i; + + gbfread(&wpnc->chHeaderLen ,sizeof(wpnc->chHeaderLen), 1, f); + gbfread(&wpnc->strName, wpnc->chHeaderLen, 1, f); + wpnc->strName[wpnc->chHeaderLen] = 0; - int i; - - gbfread (&wpnc->chHeaderLen ,sizeof (wpnc->chHeaderLen), 1, f); - gbfread (&wpnc->strName, wpnc->chHeaderLen, 1, f); - wpnc->strName[wpnc->chHeaderLen] = 0; - - gbfread (&wpnc->wp_data, 8, 1, f); - wpnc->wp_data.East = gbfgetint32 (f); - wpnc->wp_data.North = gbfgetint32 (f); - gbfread (&wpnc->wp_data.pad2,2, 1, f); - wpnc->wp_data.Alt = gbfgetint32 (f); - gbfread (&wpnc->wp_data.CommentLength, 1, 1, f); - i = (int)wpnc->wp_data.CommentLength; + gbfread(&wpnc->wp_data, 8, 1, f); + wpnc->wp_data.East = gbfgetint32(f); + wpnc->wp_data.North = gbfgetint32(f); + gbfread(&wpnc->wp_data.pad2,2, 1, f); + wpnc->wp_data.Alt = gbfgetint32(f); + gbfread(&wpnc->wp_data.CommentLength, 1, 1, f); + i = (int)wpnc->wp_data.CommentLength; - /* Read the comment field */ - gbfread (d, i + 44, 1, f); + /* Read the comment field */ + gbfread(d, i + 44, 1, f); } static void -ng_fread_next_wp (ng_next_wp_t *nwp, gbfile *f) { - gbfread (&nwp->pad1, 2, 1, f); - nwp->next_wp = gbfgetint16 (f); - gbfread (&nwp->pad2, 2, 1, f); +ng_fread_next_wp(ng_next_wp_t* nwp, gbfile* f) +{ + gbfread(&nwp->pad1, 2, 1, f); + nwp->next_wp = gbfgetint16(f); + gbfread(&nwp->pad2, 2, 1, f); } /* =================== Write data functions ====================================*/ static void -ng_fill_header_default (void) { - ng_file_header_t default_header = { - 0x00, - {0xff, 0xff, 0x01, 0x00, 0x09, 0x00}, - {'C', 'W', 'a', 'y', 'P', 'o', 'i', 'n', 't'}, - {0x01, 0x00, 0x00, 0x00}, - }; - - ng_file_header =default_header; - +ng_fill_header_default(void) +{ + ng_file_header_t default_header = { + 0x00, + {0xff, 0xff, 0x01, 0x00, 0x09, 0x00}, + {'C', 'W', 'a', 'y', 'P', 'o', 'i', 'n', 't'}, + {0x01, 0x00, 0x00, 0x00}, + }; + + ng_file_header =default_header; + } static void -ng_fill_waypoint_default (void) { - ng_wp_data_t default_wp = { - {0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00}, - 0, - 0, - {0x01, 0x01}, - 0, - 0x00, - - }; - - ng_next_wp_t default_ng_next_wp = { - {0x01, 0x80}, - 0, - {0x00, 0x00}, - }; - - WPNC.wp_data = default_wp; - ng_next_wp = default_ng_next_wp; +ng_fill_waypoint_default(void) +{ + ng_wp_data_t default_wp = { + {0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00}, + 0, + 0, + {0x01, 0x01}, + 0, + 0x00, + + }; + + ng_next_wp_t default_ng_next_wp = { + {0x01, 0x80}, + 0, + {0x00, 0x00}, + }; + + WPNC.wp_data = default_wp; + ng_next_wp = default_ng_next_wp; } static void -ng_waypt_rd (const waypoint * wpt) { - char * s = NULL; - - char z[50]; - double lat, lon; - static int current_wp_ix=0; - - memset (z, 0, 50); - current_wp_ix++; - ng_fill_waypoint_default(); - - if (!GPS_Math_WGS84_To_ICS_EN(wpt->latitude, wpt->longitude, &lon, &lat)) { - fatal(MYNAME ": Waypoint %d is out of the israeli grid area", current_wp_ix); - } - - WPNC.wp_data.North = (gbuint32)lat; - WPNC.wp_data.East = (gbuint32)lon; - - if (reorder_wp) { - sprintf (temp_short_name, "A%03d", current_wp_ix); - s = temp_short_name; - } - - else - s = wpt->shortname; - - ng_fwrite_wp_data (s, wpt->description, &WPNC.wp_data, file_out); - - - /* if not Last WP, write the next one index */ - - if (nof_wp > current_wp_ix) { - ng_next_wp.next_wp = current_wp_ix + 1; - - ng_fwrite_next_wp (&ng_next_wp, file_out); - - } +ng_waypt_rd(const waypoint* wpt) +{ + char* s = NULL; + + char z[50]; + double lat, lon; + static int current_wp_ix=0; + + memset(z, 0, 50); + current_wp_ix++; + ng_fill_waypoint_default(); + + if (!GPS_Math_WGS84_To_ICS_EN(wpt->latitude, wpt->longitude, &lon, &lat)) { + fatal(MYNAME ": Waypoint %d is out of the israeli grid area", current_wp_ix); + } + + WPNC.wp_data.North = (gbuint32)lat; + WPNC.wp_data.East = (gbuint32)lon; + + if (reorder_wp) { + sprintf(temp_short_name, "A%03d", current_wp_ix); + s = temp_short_name; + } + + else { + s = wpt->shortname; + } + + ng_fwrite_wp_data(s, wpt->description, &WPNC.wp_data, file_out); + + + /* if not Last WP, write the next one index */ + + if (nof_wp > current_wp_ix) { + ng_next_wp.next_wp = current_wp_ix + 1; + + ng_fwrite_next_wp(&ng_next_wp, file_out); + + } } static void -header_write (void) { - ng_file_header.nof_wp = nof_wp; - gbfputint16 (nof_wp, file_out); - gbfwrite(&ng_file_header.pad1[0], 19, 1, file_out); +header_write(void) +{ + ng_file_header.nof_wp = nof_wp; + gbfputint16(nof_wp, file_out); + gbfwrite(&ng_file_header.pad1[0], 19, 1, file_out); } static void -data_write (void) { - nof_wp = waypt_count(); - if (nof_wp) { - header_write (); - waypt_disp_all(ng_waypt_rd); - } - else { - nof_wp = route_waypt_count(); - if (nof_wp) { - header_write (); - route_disp_all(NULL, NULL, ng_waypt_rd); - } - } -} +data_write(void) +{ + nof_wp = waypt_count(); + if (nof_wp) { + header_write(); + waypt_disp_all(ng_waypt_rd); + } else { + nof_wp = route_waypt_count(); + if (nof_wp) { + header_write(); + route_disp_all(NULL, NULL, ng_waypt_rd); + } + } +} static void -wr_init(const char *fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); - ng_fill_header_default (); - if (NULL != reorder) - if (!case_ignore_strcmp(reorder, "y")) {reorder_wp = 1;} +wr_init(const char* fname) +{ + file_out = gbfopen_le(fname, "wb", MYNAME); + ng_fill_header_default(); + if (NULL != reorder) + if (!case_ignore_strcmp(reorder, "y")) { + reorder_wp = 1; + } } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } /*=========================== Read data functions ==================================*/ static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); + + ng_read_file_header(); - ng_read_file_header(); + if (NULL != process) { + if (!case_ignore_strcmp(process, "wp")) { + process_rte = 0; + } + if (!case_ignore_strcmp(process, "rte")) { + process_rte = 1; + } + } - if (NULL != process) { - if (!case_ignore_strcmp(process, "wp")) {process_rte = 0;} - if (!case_ignore_strcmp(process, "rte")) {process_rte = 1;} - } - } static void rd_deinit(void) { - gbfclose(file_in); - file_in = NULL; + gbfclose(file_in); + file_in = NULL; } @@ -335,81 +355,84 @@ rd_deinit(void) static void ng_read_file_header(void) { - - nof_wp = gbfgetint16 (file_in); - gbfread (&ng_file_header.pad1[0], 19, 1, file_in); - ng_file_header.nof_wp = nof_wp; - - - if (strncmp ("CWayPoint", ng_file_header.signature, 9)) - fatal ("\nInvalid Naviguide file format\n"); - - + + nof_wp = gbfgetint16(file_in); + gbfread(&ng_file_header.pad1[0], 19, 1, file_in); + ng_file_header.nof_wp = nof_wp; + + + if (strncmp("CWayPoint", ng_file_header.signature, 9)) { + fatal("\nInvalid Naviguide file format\n"); + } + + } static void data_read(void) { - int n; - unsigned i; - waypoint *wpt_tmp; - - if (process_rte) { - rte_head = route_head_alloc(); - rte_head->rte_waypt_ct = nof_wp; - route_add_head(rte_head); - } - - for (n = 0; n < nof_wp; ++n) { - - wpt_tmp = waypt_new (); - - /* Read waypoint data */ - - ng_fread_wp_data (strComment, &WPNC, file_in); - - - if (n < nof_wp - 1) { - /* - gbfread (&ng_next_wp.pad1[0], 2, 1, file_in); - ng_next_wp.next_wp = gbfgetint16 (file_in); - gbfread (&ng_next_wp.pad2[0], 2, 1, file_in); - */ - ng_fread_next_wp (&ng_next_wp, file_in); - - } - /* Clear commas form the comment for CSV file commonality */ - for (i = 0; i shortname = xstrdup (WPNC.strName); - wpt_tmp->description = xstrdup (strComment); - - if (process_rte) - route_add_wpt(rte_head, wpt_tmp); - else - waypt_add(wpt_tmp); - } + int n; + unsigned i; + waypoint* wpt_tmp; + + if (process_rte) { + rte_head = route_head_alloc(); + rte_head->rte_waypt_ct = nof_wp; + route_add_head(rte_head); + } + + for (n = 0; n < nof_wp; ++n) { + + wpt_tmp = waypt_new(); + + /* Read waypoint data */ + + ng_fread_wp_data(strComment, &WPNC, file_in); + + + if (n < nof_wp - 1) { + /* + gbfread (&ng_next_wp.pad1[0], 2, 1, file_in); + ng_next_wp.next_wp = gbfgetint16 (file_in); + gbfread (&ng_next_wp.pad2[0], 2, 1, file_in); + */ + ng_fread_next_wp(&ng_next_wp, file_in); + + } + /* Clear commas form the comment for CSV file commonality */ + for (i = 0; i shortname = xstrdup(WPNC.strName); + wpt_tmp->description = xstrdup(strComment); + + if (process_rte) { + route_add_wpt(rte_head, wpt_tmp); + } else { + waypt_add(wpt_tmp); + } + } } /* data_read */ ff_vecs_t ng_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - ng_args, - //CET_CHARSET_ASCII, 0 /* CET-REVIEW */ - CET_CHARSET_HEBREW, 0 + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + ng_args, + //CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + CET_CHARSET_HEBREW, 0 }; diff --git a/gpsbabel/navilink.c b/gpsbabel/navilink.c index e828983cd..7c5b987d2 100644 --- a/gpsbabel/navilink.c +++ b/gpsbabel/navilink.c @@ -29,27 +29,27 @@ #define MYNAME "NAVILINK" -static char *nuketrk = NULL; -static char *nukerte = NULL; -static char *nukewpt = NULL; -static char *nukedlg = NULL; -static char *poweroff = NULL; -static char *datalog = NULL; - -static void *serial_handle = NULL; -static gbfile *file_handle = NULL; - -static unsigned char *track_data; -static unsigned char *track_data_ptr; -static unsigned char *track_data_end; +static char* nuketrk = NULL; +static char* nukerte = NULL; +static char* nukewpt = NULL; +static char* nukedlg = NULL; +static char* poweroff = NULL; +static char* datalog = NULL; + +static void* serial_handle = NULL; +static gbfile* file_handle = NULL; + +static unsigned char* track_data; +static unsigned char* track_data_ptr; +static unsigned char* track_data_end; static unsigned track_serial; -static waypoint **route_waypts; -static unsigned *route_ids; +static waypoint** route_waypts; +static unsigned* route_ids; static unsigned route_id_ptr; static enum { - READING, - WRITING + READING, + WRITING } operation = READING; #define SERIAL_TIMEOUT 8000 @@ -88,180 +88,197 @@ static enum { #define PID_CLEAR_DATALOG 0x1b static -const char *const icon_table[] = { - "Star", - "Flag", - "House", - "Left Sign", - "Telegraph Pole", - "People", - "Fuel", - "Phone", - "Pole", - "Mountain", - "Water", - "Tree", - "Road Narrows", - "Crossroads", - "Road Fork", - "Turn Right", - "Turn Left", - "Bird", - "3D House", - "Trig Point", - "Tower", - "Cable Car", - "Church", - "Telegraph Pole", - "Skier", - "Anchor", - "Fish", - "Fishes", - "Rain", - "Fisherman", - "Tower", - "Boats", - "Boat", - "Bicycle", - "Railway Track", - "Dollar Sign", - "Bus", - "Camera", - "Fuel Pump", - "Cup", - "Merging Road", - "Plane", - "Red Cross", - "House", - "Parking" +const char* const icon_table[] = { + "Star", + "Flag", + "House", + "Left Sign", + "Telegraph Pole", + "People", + "Fuel", + "Phone", + "Pole", + "Mountain", + "Water", + "Tree", + "Road Narrows", + "Crossroads", + "Road Fork", + "Turn Right", + "Turn Left", + "Bird", + "3D House", + "Trig Point", + "Tower", + "Cable Car", + "Church", + "Telegraph Pole", + "Skier", + "Anchor", + "Fish", + "Fishes", + "Rain", + "Fisherman", + "Tower", + "Boats", + "Boat", + "Bicycle", + "Railway Track", + "Dollar Sign", + "Bus", + "Camera", + "Fuel Pump", + "Cup", + "Merging Road", + "Plane", + "Red Cross", + "House", + "Parking" }; static arglist_t navilink_args[] = { - { "nuketrk", &nuketrk, "Delete all track points", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - { "nukerte", &nukerte, "Delete all routes", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - { "nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - { "nukedlg", &nukedlg, "Clear the datalog", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - { "datalog", &datalog, "Read from datalogger buffer", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "power_off", &poweroff, "Command unit to power itself down", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "nuketrk", &nuketrk, "Delete all track points", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nukerte", &nukerte, "Delete all routes", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nukedlg", &nukedlg, "Clear the datalog", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "datalog", &datalog, "Read from datalogger buffer", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "power_off", &poweroff, "Command unit to power itself down", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static void (*write_waypoint)(const waypoint *) = NULL; -static void (*write_track_start)(const route_head *track) = NULL; -static void (*write_track_point)(const waypoint *waypt) = NULL; -static void (*write_track_end)(const route_head *track) = NULL; -static void (*write_route_start)(const route_head *track) = NULL; -static void (*write_route_point)(const waypoint *waypt) = NULL; -static void (*write_route_end)(const route_head *track) = NULL; +static void (*write_waypoint)(const waypoint*) = NULL; +static void (*write_track_start)(const route_head* track) = NULL; +static void (*write_track_point)(const waypoint* waypt) = NULL; +static void (*write_track_end)(const route_head* track) = NULL; +static void (*write_route_start)(const route_head* track) = NULL; +static void (*write_route_point)(const waypoint* waypt) = NULL; +static void (*write_route_end)(const route_head* track) = NULL; static int -find_icon_from_descr(const char *descr) +find_icon_from_descr(const char* descr) { - int i; + int i; - for (i = 0; descr && i < sizeof(icon_table) / sizeof(const char *); i++) { - if (strcmp(descr, icon_table[i]) == 0) - return i; - } + for (i = 0; descr && i < sizeof(icon_table) / sizeof(const char*); i++) { + if (strcmp(descr, icon_table[i]) == 0) { + return i; + } + } - return 0; + return 0; } static void -free_waypoints(waypoint **waypts) +free_waypoints(waypoint** waypts) { - waypoint **wayptp; + waypoint** wayptp; - for (wayptp = waypts; wayptp < waypts + MAX_WAYPOINTS; wayptp++) { - if (*wayptp) { - waypt_free(*wayptp); - } - } + for (wayptp = waypts; wayptp < waypts + MAX_WAYPOINTS; wayptp++) { + if (*wayptp) { + waypt_free(*wayptp); + } + } - xfree(waypts); + xfree(waypts); } static unsigned -compare_waypoints(const waypoint *waypt1, const waypoint *waypt2) +compare_waypoints(const waypoint* waypt1, const waypoint* waypt2) { - return waypt1->latitude == waypt2->latitude && - waypt1->longitude == waypt2->longitude && - waypt1->altitude == waypt2->altitude && - strcmp(waypt1->shortname, waypt2->shortname) == 0; + return waypt1->latitude == waypt2->latitude && + waypt1->longitude == waypt2->longitude && + waypt1->altitude == waypt2->altitude && + strcmp(waypt1->shortname, waypt2->shortname) == 0; } unsigned -navilink_checksum_packet(const unsigned char *packet, unsigned length) +navilink_checksum_packet(const unsigned char* packet, unsigned length) { - unsigned checksum = 0; + unsigned checksum = 0; - while (length-- > 0) { - checksum += *packet++; - } + while (length-- > 0) { + checksum += *packet++; + } - return checksum & 0x7fff; + return checksum & 0x7fff; } #ifdef NAVILINK_DEBUG static void -dump_packet(char *prefix, unsigned char *packet, unsigned length) +dump_packet(char* prefix, unsigned char* packet, unsigned length) { - unsigned i; - - for (i = 0; i < length; i++ ) { - if ((i % 16) == 0) fprintf(stderr, "%s %08x :", prefix, i); - fprintf(stderr, " %02x", packet[i]); - if ((i % 16) == 15 || i == length - 1) fprintf(stderr, "\n"); - } - - fprintf(stderr, "\n"); + unsigned i; + + for (i = 0; i < length; i++) { + if ((i % 16) == 0) { + fprintf(stderr, "%s %08x :", prefix, i); + } + fprintf(stderr, " %02x", packet[i]); + if ((i % 16) == 15 || i == length - 1) { + fprintf(stderr, "\n"); + } + } + + fprintf(stderr, "\n"); } #endif static void -write_packet(unsigned type, const void *payload, unsigned length) +write_packet(unsigned type, const void* payload, unsigned length) { - unsigned char *packet = xmalloc(length + 9); + unsigned char* packet = (unsigned char*) xmalloc(length + 9); - packet[0] = 0xa0; - packet[1] = 0xa2; - le_write16(packet + 2, length + 1); - packet[4] = type; - memcpy(packet + 5, payload, length); - le_write16(packet + length + 5, navilink_checksum_packet(packet + 4, length + 1)); - packet[length + 7] = 0xb0; - packet[length + 8] = 0xb3; + packet[0] = 0xa0; + packet[1] = 0xa2; + le_write16(packet + 2, length + 1); + packet[4] = type; + memcpy(packet + 5, payload, length); + le_write16(packet + length + 5, navilink_checksum_packet(packet + 4, length + 1)); + packet[length + 7] = 0xb0; + packet[length + 8] = 0xb3; #ifdef NAVILINK_DEBUG - dump_packet(">>>", packet + 4, length + 1); + dump_packet(">>>", packet + 4, length + 1); #endif - if (gbser_write(serial_handle, packet, length + 9) != gbser_OK) { - fatal(MYNAME ": Write error\n"); - } + if (gbser_write(serial_handle, packet, length + 9) != gbser_OK) { + fatal(MYNAME ": Write error\n"); + } - xfree(packet); + xfree(packet); } static unsigned read_word(void) { - unsigned char buffer[2]; + unsigned char buffer[2]; - if (gbser_read_wait(serial_handle, buffer, 2, SERIAL_TIMEOUT) != 2) { - fatal(MYNAME ": Read error\n"); - } + if (gbser_read_wait(serial_handle, buffer, 2, SERIAL_TIMEOUT) != 2) { + fatal(MYNAME ": Read error\n"); + } - return (buffer[1] << 8) | buffer[0]; + return (buffer[1] << 8) | buffer[0]; } /* @@ -275,565 +292,567 @@ read_word(void) * Returns TRUE if the packet was successfully read into payload. */ static int -read_packet(unsigned type, void *payload, +read_packet(unsigned type, void* payload, unsigned minlength, unsigned maxlength, int handle_nak) { - unsigned size; - unsigned char *data; - unsigned checksum; + unsigned size; + unsigned char* data; + unsigned checksum; - if (read_word() != 0xa2a0) { - fatal(MYNAME ": Protocol error: Bad packet header." - " Is your NaviGPS in NAVILINK mode?\n"); - } + if (read_word() != 0xa2a0) { + fatal(MYNAME ": Protocol error: Bad packet header." + " Is your NaviGPS in NAVILINK mode?\n"); + } - if ((size = read_word()) <= minlength) { - fatal(MYNAME ": Protocol error: Packet too short\n"); - } + if ((size = read_word()) <= minlength) { + fatal(MYNAME ": Protocol error: Packet too short\n"); + } - data = xmalloc(size); + data = (unsigned char*) xmalloc(size); - if (gbser_read_wait(serial_handle, data, size, SERIAL_TIMEOUT) != size) { - fatal(MYNAME ": Read error reading %d byte payload\n", size); - } + if (gbser_read_wait(serial_handle, data, size, SERIAL_TIMEOUT) != size) { + fatal(MYNAME ": Read error reading %d byte payload\n", size); + } #ifdef NAVILINK_DEBUG - dump_packet("<<<", data, size); + dump_packet("<<<", data, size); #endif - if (data[0] != type) { - if (handle_nak && data[0] == PID_NAK) { - return FALSE; - } + if (data[0] != type) { + if (handle_nak && data[0] == PID_NAK) { + return FALSE; + } - fatal(MYNAME ": Protocol error: Bad packet type (expected 0x%02x but got 0x%02x)\n", type, data[0]); - } + fatal(MYNAME ": Protocol error: Bad packet type (expected 0x%02x but got 0x%02x)\n", type, data[0]); + } - if ((checksum = read_word()) != navilink_checksum_packet(data, size)) { - fatal(MYNAME ": Checksum error - expected %x got %x\n", - navilink_checksum_packet(data, size), checksum); - } + if ((checksum = read_word()) != navilink_checksum_packet(data, size)) { + fatal(MYNAME ": Checksum error - expected %x got %x\n", + navilink_checksum_packet(data, size), checksum); + } - if (read_word() != 0xb3b0) { - fatal(MYNAME ": Protocol error: Bad packet trailer\n"); - } + if (read_word() != 0xb3b0) { + fatal(MYNAME ": Protocol error: Bad packet trailer\n"); + } - if (size - 1 > maxlength) { - memcpy(payload, data + 1, maxlength); - } else { - memcpy(payload, data + 1, size - 1); - } + if (size - 1 > maxlength) { + memcpy(payload, data + 1, maxlength); + } else { + memcpy(payload, data + 1, size - 1); + } - xfree(data); + xfree(data); - return TRUE; + return TRUE; } static time_t -decode_datetime(const unsigned char *buffer) +decode_datetime(const unsigned char* buffer) { - struct tm tm; + struct tm tm; - tm.tm_sec = buffer[5]; - tm.tm_min = buffer[4]; - tm.tm_hour = buffer[3]; - tm.tm_mday = buffer[2]; - tm.tm_mon = buffer[1] - 1; - tm.tm_year = buffer[0] + 100; + tm.tm_sec = buffer[5]; + tm.tm_min = buffer[4]; + tm.tm_hour = buffer[3]; + tm.tm_mday = buffer[2]; + tm.tm_mon = buffer[1] - 1; + tm.tm_year = buffer[0] + 100; - return mkgmtime(&tm); + return mkgmtime(&tm); } static void -encode_datetime(time_t datetime, unsigned char *buffer) +encode_datetime(time_t datetime, unsigned char* buffer) { - struct tm *tm; - - if ((tm = gmtime(&datetime)) != NULL) { - buffer[0] = tm->tm_year - 100; - buffer[1] = tm->tm_mon + 1; - buffer[2] = tm->tm_mday; - buffer[3] = tm->tm_hour; - buffer[4] = tm->tm_min; - buffer[5] = tm->tm_sec; - } else { - memset(buffer, 0, 6); - } + struct tm* tm; + + if ((tm = gmtime(&datetime)) != NULL) { + buffer[0] = tm->tm_year - 100; + buffer[1] = tm->tm_mon + 1; + buffer[2] = tm->tm_mday; + buffer[3] = tm->tm_hour; + buffer[4] = tm->tm_min; + buffer[5] = tm->tm_sec; + } else { + memset(buffer, 0, 6); + } } static void -decode_position(const unsigned char *buffer, waypoint *waypt) +decode_position(const unsigned char* buffer, waypoint* waypt) { - waypt->latitude = le_read32(buffer + 0) / 10000000.0; - waypt->longitude = le_read32(buffer + 4) / 10000000.0; - waypt->altitude = FEET_TO_METERS(le_read16(buffer + 8)); + waypt->latitude = le_read32(buffer + 0) / 10000000.0; + waypt->longitude = le_read32(buffer + 4) / 10000000.0; + waypt->altitude = FEET_TO_METERS(le_read16(buffer + 8)); } static void -encode_position(const waypoint *waypt, unsigned char *buffer) +encode_position(const waypoint* waypt, unsigned char* buffer) { - le_write32(buffer + 0, (int) (waypt->latitude * 10000000)); - le_write32(buffer + 4, (int) (waypt->longitude * 10000000)); - le_write16(buffer + 8, METERS_TO_FEET(waypt->altitude)); + le_write32(buffer + 0, (int)(waypt->latitude * 10000000)); + le_write32(buffer + 4, (int)(waypt->longitude * 10000000)); + le_write16(buffer + 8, METERS_TO_FEET(waypt->altitude)); } static unsigned -decode_waypoint_id(const unsigned char *buffer) +decode_waypoint_id(const unsigned char* buffer) { - unsigned id = le_read16(buffer + 2); + unsigned id = le_read16(buffer + 2); - if (id >= MAX_WAYPOINTS) { - fatal(MYNAME ": Invalid waypoint ID\n"); - } + if (id >= MAX_WAYPOINTS) { + fatal(MYNAME ": Invalid waypoint ID\n"); + } - return id; + return id; } -static waypoint * -decode_waypoint(const unsigned char *buffer) +static waypoint* +decode_waypoint(const unsigned char* buffer) { - waypoint *waypt = waypt_new(); + waypoint* waypt = waypt_new(); - decode_position(buffer + 12, waypt); - waypt->shortname = xstrdup((char *)buffer + 4); - waypt->icon_descr = icon_table[buffer[28]]; - waypt->creation_time = decode_datetime(buffer + 22); + decode_position(buffer + 12, waypt); + waypt->shortname = xstrdup((char*)buffer + 4); + waypt->icon_descr = icon_table[buffer[28]]; + waypt->creation_time = decode_datetime(buffer + 22); - return waypt; + return waypt; } static void -encode_waypoint(const waypoint *waypt, unsigned char *buffer) +encode_waypoint(const waypoint* waypt, unsigned char* buffer) { - buffer[0] = 0x00; - buffer[1] = 0x40; - le_write16(buffer + 2, 0); - strncpy((char *)buffer + 4, waypt->shortname, 6); - buffer[10] = 0; - buffer[11] = 0; - encode_position(waypt, buffer + 12); - encode_datetime(waypt->creation_time, buffer + 22); - buffer[28] = find_icon_from_descr(waypt->icon_descr); - buffer[29] = 0; - buffer[30] = 0x00; - buffer[31] = 0x7e; + buffer[0] = 0x00; + buffer[1] = 0x40; + le_write16(buffer + 2, 0); + strncpy((char*)buffer + 4, waypt->shortname, 6); + buffer[10] = 0; + buffer[11] = 0; + encode_position(waypt, buffer + 12); + encode_datetime(waypt->creation_time, buffer + 22); + buffer[28] = find_icon_from_descr(waypt->icon_descr); + buffer[29] = 0; + buffer[30] = 0x00; + buffer[31] = 0x7e; } -static waypoint * -decode_trackpoint(const unsigned char *buffer) +static waypoint* +decode_trackpoint(const unsigned char* buffer) { - waypoint *waypt = waypt_new(); + waypoint* waypt = waypt_new(); - decode_position(buffer + 12, waypt); - waypt->creation_time = decode_datetime(buffer + 22); - WAYPT_SET(waypt, course, le_read16(buffer + 2)); - WAYPT_SET(waypt, speed, KPH_TO_MPS(buffer[29] * 2)); + decode_position(buffer + 12, waypt); + waypt->creation_time = decode_datetime(buffer + 22); + WAYPT_SET(waypt, course, le_read16(buffer + 2)); + WAYPT_SET(waypt, speed, KPH_TO_MPS(buffer[29] * 2)); - return waypt; + return waypt; } static void -encode_trackpoint(const waypoint *waypt, unsigned serial, unsigned char *buffer) +encode_trackpoint(const waypoint* waypt, unsigned serial, unsigned char* buffer) { - double x; - double y; - int32 z; - char zc; - - GPS_Math_WGS84_To_UTM_EN(waypt->latitude, waypt->longitude, &x, &y, &z, &zc); - - le_write16(buffer + 0, serial); - le_write16(buffer + 2, WAYPT_GET(waypt, course, 0)); - le_write32(buffer + 4, x); - le_write32(buffer + 8, y); - encode_position(waypt, buffer + 12); - encode_datetime(waypt->creation_time, buffer + 22); - buffer[28] = z; - buffer[29] = MPS_TO_KPH(WAYPT_GET(waypt, speed, 0) / 2); - buffer[30] = 0x5a; - buffer[31] = 0x7e; + double x; + double y; + int32 z; + char zc; + + GPS_Math_WGS84_To_UTM_EN(waypt->latitude, waypt->longitude, &x, &y, &z, &zc); + + le_write16(buffer + 0, serial); + le_write16(buffer + 2, WAYPT_GET(waypt, course, 0)); + le_write32(buffer + 4, x); + le_write32(buffer + 8, y); + encode_position(waypt, buffer + 12); + encode_datetime(waypt->creation_time, buffer + 22); + buffer[28] = z; + buffer[29] = MPS_TO_KPH(WAYPT_GET(waypt, speed, 0) / 2); + buffer[30] = 0x5a; + buffer[31] = 0x7e; } -static waypoint ** +static waypoint** serial_read_waypoints(void) { - waypoint **waypts = NULL; - unsigned char information[32]; - unsigned short total; - unsigned short start; + waypoint** waypts = NULL; + unsigned char information[32]; + unsigned short total; + unsigned short start; - if (global_opts.masked_objective & RTEDATAMASK) { - waypts = xcalloc(MAX_WAYPOINTS, sizeof(waypoint *)); - } + if (global_opts.masked_objective & RTEDATAMASK) { + waypts = (waypoint**) xcalloc(MAX_WAYPOINTS, sizeof(waypoint*)); + } - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); - total = le_read16(information + 0); + total = le_read16(information + 0); - for (start = 0; start < total; start += 32) { - unsigned short count = total - start; - unsigned char payload[7]; - unsigned char *waypoints; - unsigned char *w; + for (start = 0; start < total; start += 32) { + unsigned short count = total - start; + unsigned char payload[7]; + unsigned char* waypoints; + unsigned char* w; - if (count > 32) count = 32; + if (count > 32) { + count = 32; + } - le_write32(payload + 0, start); - le_write16(payload + 4, count); - payload[6] = 1; + le_write32(payload + 0, start); + le_write16(payload + 4, count); + payload[6] = 1; - write_packet(PID_QRY_WAYPOINTS, payload, sizeof(payload)); + write_packet(PID_QRY_WAYPOINTS, payload, sizeof(payload)); - waypoints = xmalloc(count * 32); + waypoints = (unsigned char*) xmalloc(count * 32); - read_packet(PID_DATA, waypoints, count * 32, count * 32, FALSE); + read_packet(PID_DATA, waypoints, count * 32, count * 32, FALSE); - for (w = waypoints; w < waypoints + count * 32; w = w + 32) { - if (global_opts.masked_objective & WPTDATAMASK) { - waypt_add(decode_waypoint(w)); - } - if (global_opts.masked_objective & RTEDATAMASK) { - waypts[decode_waypoint_id(w)] = decode_waypoint(w); - } - } + for (w = waypoints; w < waypoints + count * 32; w = w + 32) { + if (global_opts.masked_objective & WPTDATAMASK) { + waypt_add(decode_waypoint(w)); + } + if (global_opts.masked_objective & RTEDATAMASK) { + waypts[decode_waypoint_id(w)] = decode_waypoint(w); + } + } - xfree(waypoints); + xfree(waypoints); - if (global_opts.verbose_status) { - waypt_status_disp(total, start + count); - } - } + if (global_opts.verbose_status) { + waypt_status_disp(total, start + count); + } + } - return waypts; + return waypts; } static unsigned int -serial_write_waypoint_packet(const waypoint *waypt) +serial_write_waypoint_packet(const waypoint* waypt) { - unsigned char data[32]; - unsigned char id[2]; + unsigned char data[32]; + unsigned char id[2]; - encode_waypoint(waypt, data); - write_packet(PID_ADD_A_WAYPOINT, data, sizeof(data)); - if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), TRUE)) { - fatal(MYNAME ": Could not write waypoint.\n"); - } + encode_waypoint(waypt, data); + write_packet(PID_ADD_A_WAYPOINT, data, sizeof(data)); + if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), TRUE)) { + fatal(MYNAME ": Could not write waypoint.\n"); + } - return le_read16(id); + return le_read16(id); } static void -serial_write_waypoint(const waypoint *waypt) +serial_write_waypoint(const waypoint* waypt) { - serial_write_waypoint_packet(waypt); + serial_write_waypoint_packet(waypt); } static void serial_read_track(void) { - unsigned char information[32]; - unsigned int address; - unsigned short total; - route_head *track; + unsigned char information[32]; + unsigned int address; + unsigned short total; + route_head* track; - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); - address = le_read32(information + 4); - total = le_read16(information + 12); + address = le_read32(information + 4); + total = le_read16(information + 12); - track = route_head_alloc(); - track_add_head(track); + track = route_head_alloc(); + track_add_head(track); - while (total > 0) { - unsigned short count = total < MAX_READ_TRACKPOINTS ? total : MAX_READ_TRACKPOINTS; - unsigned char payload[7]; - unsigned char *trackpoints; - unsigned char *t; + while (total > 0) { + unsigned short count = total < MAX_READ_TRACKPOINTS ? total : MAX_READ_TRACKPOINTS; + unsigned char payload[7]; + unsigned char* trackpoints; + unsigned char* t; - le_write32(payload + 0, address); - le_write16(payload + 4, count * 32); - payload[6] = 0x00; + le_write32(payload + 0, address); + le_write16(payload + 4, count * 32); + payload[6] = 0x00; - write_packet(PID_READ_TRACKPOINTS, payload, sizeof(payload)); + write_packet(PID_READ_TRACKPOINTS, payload, sizeof(payload)); - trackpoints = xmalloc(count * 32); + trackpoints = (unsigned char*) xmalloc(count * 32); - read_packet(PID_DATA, trackpoints, count * 32, count * 32, FALSE); - write_packet(PID_ACK, NULL, 0); + read_packet(PID_DATA, trackpoints, count * 32, count * 32, FALSE); + write_packet(PID_ACK, NULL, 0); - for (t = trackpoints; t < trackpoints + count * 32; t = t + 32) { - track_add_wpt(track, decode_trackpoint(t)); - } + for (t = trackpoints; t < trackpoints + count * 32; t = t + 32) { + track_add_wpt(track, decode_trackpoint(t)); + } - xfree(trackpoints); + xfree(trackpoints); - address = address + count * 32; - total = total - count; - } + address = address + count * 32; + total = total - count; + } } static void serial_write_track(void) { - unsigned char information[32]; - unsigned int address; - unsigned short total; - unsigned char data[7]; + unsigned char information[32]; + unsigned int address; + unsigned short total; + unsigned char data[7]; - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); - address = le_read32(information + 4); - total = le_read16(information + 12); + address = le_read32(information + 4); + total = le_read16(information + 12); - le_write32(data + 0, address + total * 32); - le_write16(data + 4, track_data_ptr - track_data); - data[6] = 0x00; + le_write32(data + 0, address + total * 32); + le_write16(data + 4, track_data_ptr - track_data); + data[6] = 0x00; - write_packet(PID_WRITE_TRACKPOINTS, data, sizeof(data)); - gb_sleep(10000); - write_packet(PID_DATA, track_data, track_data_ptr - track_data); - read_packet(PID_CMD_OK, NULL, 0, 0, FALSE); + write_packet(PID_WRITE_TRACKPOINTS, data, sizeof(data)); + gb_sleep(10000); + write_packet(PID_DATA, track_data, track_data_ptr - track_data); + read_packet(PID_CMD_OK, NULL, 0, 0, FALSE); - track_data_ptr = track_data; + track_data_ptr = track_data; } static void -serial_write_track_start(const route_head *track) +serial_write_track_start(const route_head* track) { - track_data = xmalloc(MAX_WRITE_TRACKPOINTS * 32); - track_data_ptr = track_data; - track_data_end = track_data + MAX_WRITE_TRACKPOINTS * 32; + track_data = (unsigned char*) xmalloc(MAX_WRITE_TRACKPOINTS * 32); + track_data_ptr = track_data; + track_data_end = track_data + MAX_WRITE_TRACKPOINTS * 32; } static void -serial_write_track_point(const waypoint *waypt) +serial_write_track_point(const waypoint* waypt) { - if (track_data_ptr >= track_data_end) { - serial_write_track(); - } + if (track_data_ptr >= track_data_end) { + serial_write_track(); + } - encode_trackpoint(waypt, 0, track_data_ptr); + encode_trackpoint(waypt, 0, track_data_ptr); - track_data_ptr += 32; + track_data_ptr += 32; } static void -serial_write_track_end(const route_head *track) +serial_write_track_end(const route_head* track) { - if (track_data_ptr > track_data) { - serial_write_track(); - } + if (track_data_ptr > track_data) { + serial_write_track(); + } - xfree(track_data); + xfree(track_data); } static void -serial_read_routes(waypoint **waypts) +serial_read_routes(waypoint** waypts) { - unsigned char information[32]; - unsigned char routec; - unsigned char r; - - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); - - routec = information[2]; - - for (r = 0; r < routec; r++) { - unsigned char payload[7]; - unsigned char routedata[320]; - route_head *route; - int sr; - - le_write32(payload + 0, r); - le_write16(payload + 2, 0); - payload[6] = 0x01; - - write_packet(PID_QRY_ROUTE, payload, sizeof(payload)); - read_packet(PID_DATA, routedata, 64, sizeof(routedata), FALSE); - - route = route_head_alloc(); - route->rte_num = routedata[2]; - route->rte_name = xstrdup((char *)routedata + 4); - route_add_head(route); - - for (sr = 0; sr < MAX_SUBROUTES; sr++) { - int w; - - for (w = 0; w < MAX_SUBROUTE_LENGTH; w++) { - unsigned short id = le_read16(routedata + 34 + 32 * sr + 2 *w); - - if (id == 0xffffu) { - w = MAX_SUBROUTE_LENGTH; - sr = MAX_SUBROUTES; - } else if (id >= MAX_WAYPOINTS) { - fatal(MYNAME ": Invalid waypoint ID in route\n"); - } else if (waypts[id] == NULL) { - fatal(MYNAME ": Non-existent waypoint in route\n"); - } else { - route_add_wpt(route, waypt_dupe(waypts[id])); - } - } - } - } + unsigned char information[32]; + unsigned char routec; + unsigned char r; + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); + + routec = information[2]; + + for (r = 0; r < routec; r++) { + unsigned char payload[7]; + unsigned char routedata[320]; + route_head* route; + int sr; + + le_write32(payload + 0, r); + le_write16(payload + 2, 0); + payload[6] = 0x01; + + write_packet(PID_QRY_ROUTE, payload, sizeof(payload)); + read_packet(PID_DATA, routedata, 64, sizeof(routedata), FALSE); + + route = route_head_alloc(); + route->rte_num = routedata[2]; + route->rte_name = xstrdup((char*)routedata + 4); + route_add_head(route); + + for (sr = 0; sr < MAX_SUBROUTES; sr++) { + int w; + + for (w = 0; w < MAX_SUBROUTE_LENGTH; w++) { + unsigned short id = le_read16(routedata + 34 + 32 * sr + 2 *w); + + if (id == 0xffffu) { + w = MAX_SUBROUTE_LENGTH; + sr = MAX_SUBROUTES; + } else if (id >= MAX_WAYPOINTS) { + fatal(MYNAME ": Invalid waypoint ID in route\n"); + } else if (waypts[id] == NULL) { + fatal(MYNAME ": Non-existent waypoint in route\n"); + } else { + route_add_wpt(route, waypt_dupe(waypts[id])); + } + } + } + } } static void -serial_write_route_start(const route_head *route) +serial_write_route_start(const route_head* route) { - route_ids = xmalloc(route->rte_waypt_ct * sizeof(unsigned)); - route_id_ptr = 0; + route_ids = (unsigned int*) xmalloc(route->rte_waypt_ct * sizeof(unsigned)); + route_id_ptr = 0; } static void -serial_write_route_point(const waypoint *waypt) +serial_write_route_point(const waypoint* waypt) { - unsigned w; + unsigned w; - for (w = 0; w < MAX_WAYPOINTS; w++) { - if (route_waypts[w] && compare_waypoints(waypt, route_waypts[w])) { - break; - } - } + for (w = 0; w < MAX_WAYPOINTS; w++) { + if (route_waypts[w] && compare_waypoints(waypt, route_waypts[w])) { + break; + } + } - if (w == MAX_WAYPOINTS) { - w = serial_write_waypoint_packet(waypt); - route_waypts[w] = waypt_dupe(waypt); - } + if (w == MAX_WAYPOINTS) { + w = serial_write_waypoint_packet(waypt); + route_waypts[w] = waypt_dupe(waypt); + } - route_ids[route_id_ptr++] = w; + route_ids[route_id_ptr++] = w; } static void -serial_write_route_end(const route_head *route) +serial_write_route_end(const route_head* route) { - unsigned char *data; - unsigned src; - unsigned sr; - unsigned char id[1]; - - if (route_id_ptr > MAX_ROUTE_LENGTH) { - fatal(MYNAME ": Route %s too long\n", route->rte_name); - } - - src = (route_id_ptr + MAX_SUBROUTE_LENGTH) / MAX_SUBROUTE_LENGTH; - data = xmalloc(32 + src * 32); - - le_write16(data + 0, 0x2000); - data[2] = 0; - data[3] = 0x20; - strncpy((char *)data + 4, route->rte_name, 6); - data[18] = 0; - data[19] = 0; - le_write32(data + 20, 0); - le_write32(data + 24, 0); - le_write16(data + 28, 0); - data[30] = 0x7b; - data[31] = 0x77; - - for (sr = 0; sr < src; sr++) { - unsigned char *srdata = data + 32 + 32 * sr; - unsigned pt_offset = MAX_SUBROUTE_LENGTH * sr; - unsigned pt; - - le_write16(srdata + 0, 0x2010); - - for (pt = 0; pt < MAX_SUBROUTE_LENGTH; pt++) { - if (pt_offset + pt < route_id_ptr) { - le_write16(srdata + 2 + 2 * pt, route_ids[pt_offset + pt]); - } else { - le_write16(srdata + 2 + 2 * pt, 0xffffu); - } - } - - srdata[30] = 0x7f; - srdata[31] = 0x77; - } - - write_packet(PID_ADD_A_ROUTE, data, 32 + src * 32); - if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), TRUE)) { - fatal(MYNAME ": Could not add route.\n"); - } - - xfree(data); - xfree(route_ids); + unsigned char* data; + unsigned src; + unsigned sr; + unsigned char id[1]; + + if (route_id_ptr > MAX_ROUTE_LENGTH) { + fatal(MYNAME ": Route %s too long\n", route->rte_name); + } + + src = (route_id_ptr + MAX_SUBROUTE_LENGTH) / MAX_SUBROUTE_LENGTH; + data = (unsigned char*) xmalloc(32 + src * 32); + + le_write16(data + 0, 0x2000); + data[2] = 0; + data[3] = 0x20; + strncpy((char*)data + 4, route->rte_name, 6); + data[18] = 0; + data[19] = 0; + le_write32(data + 20, 0); + le_write32(data + 24, 0); + le_write16(data + 28, 0); + data[30] = 0x7b; + data[31] = 0x77; + + for (sr = 0; sr < src; sr++) { + unsigned char* srdata = data + 32 + 32 * sr; + unsigned pt_offset = MAX_SUBROUTE_LENGTH * sr; + unsigned pt; + + le_write16(srdata + 0, 0x2010); + + for (pt = 0; pt < MAX_SUBROUTE_LENGTH; pt++) { + if (pt_offset + pt < route_id_ptr) { + le_write16(srdata + 2 + 2 * pt, route_ids[pt_offset + pt]); + } else { + le_write16(srdata + 2 + 2 * pt, 0xffffu); + } + } + + srdata[30] = 0x7f; + srdata[31] = 0x77; + } + + write_packet(PID_ADD_A_ROUTE, data, 32 + src * 32); + if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), TRUE)) { + fatal(MYNAME ": Could not add route.\n"); + } + + xfree(data); + xfree(route_ids); } static int -decode_sbp_usec(const unsigned char *buffer) +decode_sbp_usec(const unsigned char* buffer) { - int msec = le_read16(buffer); - return (msec % 1000) * 1000; + int msec = le_read16(buffer); + return (msec % 1000) * 1000; } static time_t -decode_sbp_datetime_packed(const unsigned char *buffer) +decode_sbp_datetime_packed(const unsigned char* buffer) { - /* - * Packed_Date_Time_UTC: - * bit 31..22 :year*12+month (10 bits) : real year= year+2000 - * bit17.21: day (5bits) - * bit12.16: hour (5bits) - * bit6..11: min (6bits) - * bit0..5 : sec (6bits) - * - * 0 1 2 3 - * 01234567 01234567 01234567 01234567 - * ........ ........ ........ ........ - * SSSSSSMM MMMMHHHH Hdddddmm mmmmmmmm - */ - - int months; - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - tm.tm_sec = buffer[0] & 0x3F; - tm.tm_min = ((buffer[0] & 0xC0) >> 6) | ((buffer[1] & 0x0F) << 2); - tm.tm_hour = ((buffer[1] & 0xF0) >> 4) | ((buffer[2] & 0x01) << 4); - tm.tm_mday = (buffer[2] & 0x3E) >> 1; - months = ((buffer[2] & 0xC0) >> 6) | buffer[3] << 2; - tm.tm_mon = months % 12 - 1; - tm.tm_year = 100 + months / 12; - - return mkgmtime(&tm); + /* + * Packed_Date_Time_UTC: + * bit 31..22 :year*12+month (10 bits) : real year= year+2000 + * bit17.21: day (5bits) + * bit12.16: hour (5bits) + * bit6..11: min (6bits) + * bit0..5 : sec (6bits) + * + * 0 1 2 3 + * 01234567 01234567 01234567 01234567 + * ........ ........ ........ ........ + * SSSSSSMM MMMMHHHH Hdddddmm mmmmmmmm + */ + + int months; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + tm.tm_sec = buffer[0] & 0x3F; + tm.tm_min = ((buffer[0] & 0xC0) >> 6) | ((buffer[1] & 0x0F) << 2); + tm.tm_hour = ((buffer[1] & 0xF0) >> 4) | ((buffer[2] & 0x01) << 4); + tm.tm_mday = (buffer[2] & 0x3E) >> 1; + months = ((buffer[2] & 0xC0) >> 6) | buffer[3] << 2; + tm.tm_mon = months % 12 - 1; + tm.tm_year = 100 + months / 12; + + return mkgmtime(&tm); } static void -decode_sbp_position(const unsigned char *buffer, waypoint *waypt) +decode_sbp_position(const unsigned char* buffer, waypoint* waypt) { - waypt->latitude = le_read32(buffer + 0) / 10000000.0; - waypt->longitude = le_read32(buffer + 4) / 10000000.0; - waypt->altitude = le_read32(buffer + 8) / 100.0; + waypt->latitude = le_read32(buffer + 0) / 10000000.0; + waypt->longitude = le_read32(buffer + 4) / 10000000.0; + waypt->altitude = le_read32(buffer + 8) / 100.0; } -waypoint * -navilink_decode_logpoint(const unsigned char *buffer) +waypoint* +navilink_decode_logpoint(const unsigned char* buffer) { - waypoint *waypt = NULL; - waypt = waypt_new(); - - waypt->hdop = ((unsigned char)buffer[0]) * 0.2f; - waypt->sat = buffer[1]; - waypt->microseconds = decode_sbp_usec(buffer + 2); - waypt->creation_time = decode_sbp_datetime_packed(buffer + 4); - decode_sbp_position(buffer + 12, waypt); - WAYPT_SET(waypt, speed, le_read16(buffer + 24) * 0.01f); - WAYPT_SET(waypt, course, le_read16(buffer + 26) * 0.01f); - - return waypt; + waypoint* waypt = NULL; + waypt = waypt_new(); + + waypt->hdop = ((unsigned char)buffer[0]) * 0.2f; + waypt->sat = buffer[1]; + waypt->microseconds = decode_sbp_usec(buffer + 2); + waypt->creation_time = decode_sbp_datetime_packed(buffer + 4); + decode_sbp_position(buffer + 12, waypt); + WAYPT_SET(waypt, speed, le_read16(buffer + 24) * 0.01f); + WAYPT_SET(waypt, course, le_read16(buffer + 26) * 0.01f); + + return waypt; } /* @@ -844,386 +863,387 @@ navilink_decode_logpoint(const unsigned char *buffer) * around), then seg2_addr and seg2_len will be zero. */ static void -read_datalog_info(unsigned int *seg1_addr, unsigned int *seg1_len, - unsigned int *seg2_addr, unsigned int *seg2_len) +read_datalog_info(unsigned int* seg1_addr, unsigned int* seg1_len, + unsigned int* seg2_addr, unsigned int* seg2_len) { - unsigned char info[16]; - unsigned int flash_start_addr; - unsigned int flash_length; - unsigned int data_start_addr; - unsigned int next_blank_addr; - - write_packet(PID_INFO_DATALOG, NULL, 0); - read_packet(PID_DATA, info, sizeof(info), sizeof(info), FALSE); - - flash_start_addr = le_read32(info); - flash_length = le_read32(info + 4); - data_start_addr = le_read32(info + 8); - next_blank_addr = le_read32(info + 12); - - if (data_start_addr > next_blank_addr) { - /* usually there are two segments to be read */ - *seg1_addr = data_start_addr; - *seg1_len = flash_start_addr + flash_length - *seg1_addr; - *seg2_addr = flash_start_addr; - *seg2_len = next_blank_addr - flash_start_addr; - } else { - /* hasn't wrapped around yet, only one segment */ - *seg1_addr = data_start_addr; - *seg1_len = next_blank_addr - data_start_addr; - *seg2_addr = 0; - *seg2_len = 0; - } - - if (*seg1_len & 0x1F || *seg2_len & 0x1F) { - fatal(MYNAME ": Protocol error: datalog lengths %u, %u " - "not aligned to 32 bytes\n", *seg1_len, *seg2_len); - } + unsigned char info[16]; + unsigned int flash_start_addr; + unsigned int flash_length; + unsigned int data_start_addr; + unsigned int next_blank_addr; + + write_packet(PID_INFO_DATALOG, NULL, 0); + read_packet(PID_DATA, info, sizeof(info), sizeof(info), FALSE); + + flash_start_addr = le_read32(info); + flash_length = le_read32(info + 4); + data_start_addr = le_read32(info + 8); + next_blank_addr = le_read32(info + 12); + + if (data_start_addr > next_blank_addr) { + /* usually there are two segments to be read */ + *seg1_addr = data_start_addr; + *seg1_len = flash_start_addr + flash_length - *seg1_addr; + *seg2_addr = flash_start_addr; + *seg2_len = next_blank_addr - flash_start_addr; + } else { + /* hasn't wrapped around yet, only one segment */ + *seg1_addr = data_start_addr; + *seg1_len = next_blank_addr - data_start_addr; + *seg2_addr = 0; + *seg2_len = 0; + } + + if (*seg1_len & 0x1F || *seg2_len & 0x1F) { + fatal(MYNAME ": Protocol error: datalog lengths %u, %u " + "not aligned to 32 bytes\n", *seg1_len, *seg2_len); + } } static void -read_datalog_records(route_head *track, +read_datalog_records(route_head* track, unsigned int start_addr, unsigned int len) { - unsigned char logpoints[MAX_READ_LOGPOINTS * SBP_RECORD_LEN]; - unsigned int logpoints_len; - unsigned char payload[7]; - unsigned char *p; - - /* The protocol only supports reading 256 logpoints at once, so - * read small chunks until none left. */ - while (len > 0) { - logpoints_len = len > MAX_READ_LOGPOINTS ? MAX_READ_LOGPOINTS : len; - - le_write32(payload, start_addr); - le_write16(payload + 4, logpoints_len); - payload[6] = 0x01; - - write_packet(PID_READ_DATALOG, payload, sizeof(payload)); - read_packet(PID_DATA, logpoints, logpoints_len, logpoints_len, FALSE); - write_packet(PID_ACK, NULL, 0); - - for (p = logpoints; p < logpoints + logpoints_len; p += 32) { - track_add_wpt(track, navilink_decode_logpoint(p)); - } - - len -= logpoints_len; - start_addr += logpoints_len; - } + unsigned char logpoints[MAX_READ_LOGPOINTS * SBP_RECORD_LEN]; + unsigned int logpoints_len; + unsigned char payload[7]; + unsigned char* p; + + /* The protocol only supports reading 256 logpoints at once, so + * read small chunks until none left. */ + while (len > 0) { + logpoints_len = len > MAX_READ_LOGPOINTS ? MAX_READ_LOGPOINTS : len; + + le_write32(payload, start_addr); + le_write16(payload + 4, logpoints_len); + payload[6] = 0x01; + + write_packet(PID_READ_DATALOG, payload, sizeof(payload)); + read_packet(PID_DATA, logpoints, logpoints_len, logpoints_len, FALSE); + write_packet(PID_ACK, NULL, 0); + + for (p = logpoints; p < logpoints + logpoints_len; p += 32) { + track_add_wpt(track, navilink_decode_logpoint(p)); + } + + len -= logpoints_len; + start_addr += logpoints_len; + } } static void serial_read_datalog(void) { - route_head *track; - unsigned int seg1_addr; - unsigned int seg1_len; - unsigned int seg2_addr; - unsigned int seg2_len; - - read_datalog_info(&seg1_addr, &seg1_len, &seg2_addr, &seg2_len); - - track = route_head_alloc(); - track_add_head(track); - - if (seg1_len) { - read_datalog_records(track, seg1_addr, seg1_len); - } - - if (seg2_len) { - read_datalog_records(track, seg2_addr, seg2_len); - } + route_head* track; + unsigned int seg1_addr; + unsigned int seg1_len; + unsigned int seg2_addr; + unsigned int seg2_len; + + read_datalog_info(&seg1_addr, &seg1_len, &seg2_addr, &seg2_len); + + track = route_head_alloc(); + track_add_head(track); + + if (seg1_len) { + read_datalog_records(track, seg1_addr, seg1_len); + } + + if (seg2_len) { + read_datalog_records(track, seg2_addr, seg2_len); + } } static void file_read(void) { - unsigned char data[32]; - route_head *track = NULL; - - while (gbfread(data, sizeof(data), 1, file_handle) == 1) { - switch (le_read16(data)) { - case 0x2000: - fatal(MYNAME ": Route objects not supported in file sources\n"); - break; - case 0x2010: - fatal(MYNAME ": Subroute objects not supported in file sources\n"); - break; - case 0x4000: - if (global_opts.masked_objective & WPTDATAMASK) { - waypt_add(decode_waypoint(data)); - } - break; - default: - if (global_opts.masked_objective & TRKDATAMASK) { - if (track == NULL) { - track = route_head_alloc(); - track_add_head(track); - } - - track_add_wpt(track, decode_trackpoint(data)); - } - break; - } - } + unsigned char data[32]; + route_head* track = NULL; + + while (gbfread(data, sizeof(data), 1, file_handle) == 1) { + switch (le_read16(data)) { + case 0x2000: + fatal(MYNAME ": Route objects not supported in file sources\n"); + break; + case 0x2010: + fatal(MYNAME ": Subroute objects not supported in file sources\n"); + break; + case 0x4000: + if (global_opts.masked_objective & WPTDATAMASK) { + waypt_add(decode_waypoint(data)); + } + break; + default: + if (global_opts.masked_objective & TRKDATAMASK) { + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + } + + track_add_wpt(track, decode_trackpoint(data)); + } + break; + } + } } static void -file_write_waypoint(const waypoint *waypt) +file_write_waypoint(const waypoint* waypt) { - unsigned char data[32]; + unsigned char data[32]; - encode_waypoint(waypt, data); - gbfwrite(data, sizeof(data), 1, file_handle); + encode_waypoint(waypt, data); + gbfwrite(data, sizeof(data), 1, file_handle); } static void -file_write_track_start(const route_head *track) +file_write_track_start(const route_head* track) { - track_serial = 1; + track_serial = 1; } static void -file_write_track_point(const waypoint *waypt) +file_write_track_point(const waypoint* waypt) { - unsigned char data[32]; + unsigned char data[32]; - encode_trackpoint(waypt, track_serial++, data); - gbfwrite(data, sizeof(data), 1, file_handle); + encode_trackpoint(waypt, track_serial++, data); + gbfwrite(data, sizeof(data), 1, file_handle); } static void -file_write_track_end(const route_head *track) +file_write_track_end(const route_head* track) { } static void -file_write_route_start(const route_head *track) +file_write_route_start(const route_head* track) { - fatal(MYNAME ": Can't write routes to a file\n"); + fatal(MYNAME ": Can't write routes to a file\n"); } static void -file_write_route_point(const waypoint *waypt) +file_write_route_point(const waypoint* waypt) { } static void -file_write_route_end(const route_head *track) +file_write_route_end(const route_head* track) { } static void nuke(void) { - if (nuketrk) { - unsigned char information[32]; - unsigned char data[7]; - - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); - - le_write32(data + 0, le_read32(information + 4)); - le_write16(data + 4, 0); - data[6] = 0; - - write_packet(PID_ERASE_TRACK, data, sizeof(data)); - read_packet(PID_CMD_OK, NULL, 0, 0, FALSE); - } - - if (nukerte) { - unsigned char data[4]; - - le_write32(data, 0x00f00000); - write_packet(PID_DEL_ALL_ROUTE, data, sizeof(data)); - if (!read_packet(PID_ACK, NULL, 0, 0, TRUE)) { - fatal(MYNAME ": Could not nuke all routes.\n"); - } - } - - if (nukewpt) { - unsigned char data[4]; - - le_write32(data, 0x00f00000); - write_packet(PID_DEL_ALL_WAYPOINT, data, sizeof(data)); - if (!read_packet(PID_ACK, NULL, 0, 0, TRUE)) { - fatal(MYNAME ": You must nuke all routes before nuking waypoints.\n"); - /* perhaps a better action would be to nuke routes for user. - * i.e. set nukerte when nukewpt is set */ - } - } - - if (nukedlg) { - write_packet(PID_CLEAR_DATALOG, NULL, 0); - /* The flash erase operation is time-consuming. Each sector (64KB) - * takes around 1 second. The total sectors for SBP is 10. - * So give the device some time to clear its datalog, in addition - * to SERIAL_TIMEOUT, which applies to read_packet() */ - gb_sleep(CLEAR_DATALOG_TIME * 1000); - read_packet(PID_ACK, NULL, 0, 0, FALSE); - } + if (nuketrk) { + unsigned char information[32]; + unsigned char data[7]; + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); + + le_write32(data + 0, le_read32(information + 4)); + le_write16(data + 4, 0); + data[6] = 0; + + write_packet(PID_ERASE_TRACK, data, sizeof(data)); + read_packet(PID_CMD_OK, NULL, 0, 0, FALSE); + } + + if (nukerte) { + unsigned char data[4]; + + le_write32(data, 0x00f00000); + write_packet(PID_DEL_ALL_ROUTE, data, sizeof(data)); + if (!read_packet(PID_ACK, NULL, 0, 0, TRUE)) { + fatal(MYNAME ": Could not nuke all routes.\n"); + } + } + + if (nukewpt) { + unsigned char data[4]; + + le_write32(data, 0x00f00000); + write_packet(PID_DEL_ALL_WAYPOINT, data, sizeof(data)); + if (!read_packet(PID_ACK, NULL, 0, 0, TRUE)) { + fatal(MYNAME ": You must nuke all routes before nuking waypoints.\n"); + /* perhaps a better action would be to nuke routes for user. + * i.e. set nukerte when nukewpt is set */ + } + } + + if (nukedlg) { + write_packet(PID_CLEAR_DATALOG, NULL, 0); + /* The flash erase operation is time-consuming. Each sector (64KB) + * takes around 1 second. The total sectors for SBP is 10. + * So give the device some time to clear its datalog, in addition + * to SERIAL_TIMEOUT, which applies to read_packet() */ + gb_sleep(CLEAR_DATALOG_TIME * 1000); + read_packet(PID_ACK, NULL, 0, 0, FALSE); + } } static void -navilink_common_init(const char *name) +navilink_common_init(const char* name) { - if (gbser_is_serial(name)) { - if ((serial_handle = gbser_init(name)) == NULL) { - fatal(MYNAME ": Could not open serial port %s\n", name); - } - - if (gbser_set_port(serial_handle, 115200, 8, 0, 1) != gbser_OK) { - fatal(MYNAME ": Can't configure port\n"); - } - - write_packet(PID_SYNC, NULL, 0); - read_packet(PID_ACK, NULL, 0, 0, FALSE); - - /* nuke data before writing */ - if (operation == WRITING) - nuke(); - - write_waypoint = serial_write_waypoint; - write_track_start = serial_write_track_start; - write_track_point = serial_write_track_point; - write_track_end = serial_write_track_end; - write_route_start = serial_write_route_start; - write_route_point = serial_write_route_point; - write_route_end = serial_write_route_end; - } else { - char *mode = operation == READING ? "r" : "w+"; - file_handle = gbfopen(name, mode, MYNAME); - - write_waypoint = file_write_waypoint; - write_track_start = file_write_track_start; - write_track_point = file_write_track_point; - write_track_end = file_write_track_end; - write_route_start = file_write_route_start; - write_route_point = file_write_route_point; - write_route_end = file_write_route_end; - } - - return; + if (gbser_is_serial(name)) { + if ((serial_handle = gbser_init(name)) == NULL) { + fatal(MYNAME ": Could not open serial port %s\n", name); + } + + if (gbser_set_port(serial_handle, 115200, 8, 0, 1) != gbser_OK) { + fatal(MYNAME ": Can't configure port\n"); + } + + write_packet(PID_SYNC, NULL, 0); + read_packet(PID_ACK, NULL, 0, 0, FALSE); + + /* nuke data before writing */ + if (operation == WRITING) { + nuke(); + } + + write_waypoint = serial_write_waypoint; + write_track_start = serial_write_track_start; + write_track_point = serial_write_track_point; + write_track_end = serial_write_track_end; + write_route_start = serial_write_route_start; + write_route_point = serial_write_route_point; + write_route_end = serial_write_route_end; + } else { + const char* mode = operation == READING ? "r" : "w+"; + file_handle = gbfopen(name, mode, MYNAME); + + write_waypoint = file_write_waypoint; + write_track_start = file_write_track_start; + write_track_point = file_write_track_point; + write_track_end = file_write_track_end; + write_route_start = file_write_route_start; + write_route_point = file_write_route_point; + write_route_end = file_write_route_end; + } + + return; } static void -navilink_rd_init(const char *name) +navilink_rd_init(const char* name) { - operation = READING; - navilink_common_init(name); + operation = READING; + navilink_common_init(name); } static void -navilink_wr_init(const char *name) +navilink_wr_init(const char* name) { - operation = WRITING; - navilink_common_init(name); + operation = WRITING; + navilink_common_init(name); } static void navilink_deinit(void) { - if (serial_handle) { - /* nuke data after reading */ - if (operation == READING) - nuke(); + if (serial_handle) { + /* nuke data after reading */ + if (operation == READING) { + nuke(); + } - if (poweroff) { - write_packet(PID_QUIT, NULL, 0); - } + if (poweroff) { + write_packet(PID_QUIT, NULL, 0); + } - gbser_deinit(serial_handle); - } + gbser_deinit(serial_handle); + } - if (file_handle) { - gbfclose(file_handle); - } + if (file_handle) { + gbfclose(file_handle); + } - return; + return; } static void navilink_read(void) { - if (datalog) { - if (global_opts.masked_objective & TRKDATAMASK) { - if (serial_handle) { - serial_read_datalog(); - } else if (file_handle) { - fatal(MYNAME ": Not supported. Use SBP format.\n"); - } - } - } else { - if (serial_handle) { - waypoint **waypts = NULL; - - if (global_opts.masked_objective & (WPTDATAMASK|RTEDATAMASK)) { - waypts = serial_read_waypoints(); - } - - if (global_opts.masked_objective & TRKDATAMASK) { - serial_read_track(); - } - - if (global_opts.masked_objective & RTEDATAMASK) { - serial_read_routes(waypts); - } - - if (waypts) { - free_waypoints(waypts); - } - } else if (file_handle) { - file_read(); - } - } + if (datalog) { + if (global_opts.masked_objective & TRKDATAMASK) { + if (serial_handle) { + serial_read_datalog(); + } else if (file_handle) { + fatal(MYNAME ": Not supported. Use SBP format.\n"); + } + } + } else { + if (serial_handle) { + waypoint** waypts = NULL; + + if (global_opts.masked_objective & (WPTDATAMASK|RTEDATAMASK)) { + waypts = serial_read_waypoints(); + } + + if (global_opts.masked_objective & TRKDATAMASK) { + serial_read_track(); + } + + if (global_opts.masked_objective & RTEDATAMASK) { + serial_read_routes(waypts); + } + + if (waypts) { + free_waypoints(waypts); + } + } else if (file_handle) { + file_read(); + } + } } static void navilink_write(void) { - if (datalog) { - fatal(MYNAME ": Writing to datalog not supported.\n"); - } - - switch (global_opts.objective) - { - case trkdata: - track_disp_all(write_track_start, - write_track_end, - write_track_point); - break; - case wptdata: - waypt_disp_all(write_waypoint); - break; - case rtedata: - if (serial_handle) { - route_waypts = serial_read_waypoints(); - } - route_disp_all(write_route_start, - write_route_end, - write_route_point); - if (route_waypts) { - free_waypoints(route_waypts); - route_waypts = NULL; - } - break; - default: - fatal(MYNAME ": Unknown objective.\n"); - } + if (datalog) { + fatal(MYNAME ": Writing to datalog not supported.\n"); + } + + switch (global_opts.objective) { + case trkdata: + track_disp_all(write_track_start, + write_track_end, + write_track_point); + break; + case wptdata: + waypt_disp_all(write_waypoint); + break; + case rtedata: + if (serial_handle) { + route_waypts = serial_read_waypoints(); + } + route_disp_all(write_route_start, + write_route_end, + write_route_point); + if (route_waypts) { + free_waypoints(route_waypts); + route_waypts = NULL; + } + break; + default: + fatal(MYNAME ": Unknown objective.\n"); + } } ff_vecs_t navilink_vecs = { - ff_type_serial, - FF_CAP_RW_ALL, - navilink_rd_init, - navilink_wr_init, - navilink_deinit, - navilink_deinit, - navilink_read, - navilink_write, - NULL, - navilink_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_serial, + FF_CAP_RW_ALL, + navilink_rd_init, + navilink_wr_init, + navilink_deinit, + navilink_deinit, + navilink_read, + navilink_write, + NULL, + navilink_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/navilink.h b/gpsbabel/navilink.h index d74eaaee4..c985f0528 100644 --- a/gpsbabel/navilink.h +++ b/gpsbabel/navilink.h @@ -29,18 +29,17 @@ #define SBP_RECORD_LEN 32 /* defined in navilink.c */ -waypoint *navilink_decode_logpoint(const unsigned char *buffer); -unsigned navilink_checksum_packet(const unsigned char *packet, unsigned length); +waypoint* navilink_decode_logpoint(const unsigned char* buffer); +unsigned navilink_checksum_packet(const unsigned char* packet, unsigned length); /* defined in sbn.c */ -int locosys_decode_file_id(char *header, size_t len); +int locosys_decode_file_id(char* header, size_t len); #ifdef THIS_IS_ONLY_FOR_REFERENCE /* Locosys SBP and SBN structures */ -typedef __packed struct -{ +typedef __packed struct { UINT8 HDOP; /* HDOP [0..51] with resolution 0.2 */ UINT8 SVIDCnt; /* Number of SVs in solution [0 to 12] */ UINT16 UtcSec; /* UTC Second [0 to 59] in seconds with resolution 0.001 */ @@ -54,13 +53,12 @@ typedef __packed struct INT16 ClmbRte; /* Climb rate in m/sec with resolution 0.01 */ UINT8 bitFlags; /* bitFlags, default 0x00, bit 0=1 indicate the first point after power on */ UINT8 reserved; -} T_SBP; +} T_SBP; -typedef struct __packed -{ - UINT8 Mid; - UINT16 Valid; - UINT16 Mode; /* Nav Mode: bit map as follows: +typedef struct __packed { + UINT8 Mid; + UINT16 Valid; + UINT16 Mode; /* Nav Mode: bit map as follows: * Bits 2-0: GPS Fix Type * 000 = No Nav * 001 = 1 SV solution @@ -93,45 +91,45 @@ typedef struct __packed * 10 = DR sensor error * 11 = DR Test mode */ - UINT16 Week; /* Extended Week Number */ - UINT32 TOW; /* Time of Week [0 to 604800] in seconds with resolution 0.001 */ - UINT16 UtcYr; /* UTC Year [1980 to 3000] */ - UINT8 UtcMth; /* UTC Month [1 to 12] */ - UINT8 UtcDay; /* UTC Day [1 to 31] */ - UINT8 UtcHr; /* UTC Hour [0 to 23] */ - UINT8 UtcMin; /* UTC Minute [0 to 59] */ - UINT16 UtcSec; /* UTC Second [0 to 59] in seconds with resolution 0.001 */ - UINT32 SVIDList; /* SVs in solution: Bit 0=1: SV1, Bit 1=1: SV2, ... , Bit 31=1: SV32 */ - - INT32 Lat; /* Latitude [-90 to 90] in degrees with resolution 0.0000001 */ - INT32 Lon; /* Longitude [-180 to 180] in degrees with resolution 0.0000001 */ - INT32 AltE; /* Altitude from Ellipsoid in meters with resolution 0.01 */ - INT32 AltM; /* Altitude from Mean Sea Level in meters with resolution 0.01 */ - UINT8 Datum; /* Map datum */ - UINT16 Sog; /* Speed Over Ground in m/sec with resolution 0.01 */ - UINT16 Cog; /* Course Over Ground [0 to 360] in degrees with resolution 0.01 */ - INT16 MagVar; /* Magnetic Variation - Reserved */ - INT16 ClmbRte; /* Climb rate in m/sec with resolution 0.01 */ - INT16 HdRte; /* Heading Rate in deg/sec with resolution 0.01 (SiRFDrive only) */ - UINT32 Ehpe; /* Expected Horizontal Position Error in meters with resolution 0.01 */ - UINT32 Evpe; /* Expected Horizontal Vertical Error in meters with resolution 0.01 */ - UINT32 Ete; /* Expected Time Error in meters with resolution 0.01 (SiRFDrive only) - Reserved */ - UINT16 Ehve; /* Expected Horizontal Velocity Error in m/sec with resolution 0.01 (SiRFDrive only) */ - INT32 ClkBias; /* Clock Bias in meters with resolution 0.01 */ - UINT32 ClkBiasE; /* Clock Bias Error in meters with resolution 0.01 (SiRFDrive only) */ - INT32 ClkDrift; /* Clock Drift in m/sec with resolution 0.01 */ - UINT32 ClkDriftE; /* Clock Drift in m/sec with resolution 0.01 (SiRFDrive only) */ - UINT32 Trvled; /* Distance Traveled since reset in meters (SiRFDrive only) */ - UINT16 TrvledE; /* Distance Traveled Error in meters (SiRFDrive only) */ - UINT16 HdE; /* Heading Error [0 to 180] in degrees with resolution 0.01 (SiRFDrive only) */ - UINT8 SVIDCnt; /* Number of SVs in solution [0 to 12] */ - UINT8 HDOP; /* HDOP [0..51] with resolution 0.2 */ - UINT8 Reserved; /* Reserved */ - - UINT16 ufSog; /* Speed Over Ground in m/sec with resolution 0.01 ,unfiltered*/ - UINT16 ufCog; /* Course Over Ground [0 to 360] in degrees with resolution 0.01, unfiltered */ - -} T_SBN_REC; + UINT16 Week; /* Extended Week Number */ + UINT32 TOW; /* Time of Week [0 to 604800] in seconds with resolution 0.001 */ + UINT16 UtcYr; /* UTC Year [1980 to 3000] */ + UINT8 UtcMth; /* UTC Month [1 to 12] */ + UINT8 UtcDay; /* UTC Day [1 to 31] */ + UINT8 UtcHr; /* UTC Hour [0 to 23] */ + UINT8 UtcMin; /* UTC Minute [0 to 59] */ + UINT16 UtcSec; /* UTC Second [0 to 59] in seconds with resolution 0.001 */ + UINT32 SVIDList; /* SVs in solution: Bit 0=1: SV1, Bit 1=1: SV2, ... , Bit 31=1: SV32 */ + + INT32 Lat; /* Latitude [-90 to 90] in degrees with resolution 0.0000001 */ + INT32 Lon; /* Longitude [-180 to 180] in degrees with resolution 0.0000001 */ + INT32 AltE; /* Altitude from Ellipsoid in meters with resolution 0.01 */ + INT32 AltM; /* Altitude from Mean Sea Level in meters with resolution 0.01 */ + UINT8 Datum; /* Map datum */ + UINT16 Sog; /* Speed Over Ground in m/sec with resolution 0.01 */ + UINT16 Cog; /* Course Over Ground [0 to 360] in degrees with resolution 0.01 */ + INT16 MagVar; /* Magnetic Variation - Reserved */ + INT16 ClmbRte; /* Climb rate in m/sec with resolution 0.01 */ + INT16 HdRte; /* Heading Rate in deg/sec with resolution 0.01 (SiRFDrive only) */ + UINT32 Ehpe; /* Expected Horizontal Position Error in meters with resolution 0.01 */ + UINT32 Evpe; /* Expected Horizontal Vertical Error in meters with resolution 0.01 */ + UINT32 Ete; /* Expected Time Error in meters with resolution 0.01 (SiRFDrive only) - Reserved */ + UINT16 Ehve; /* Expected Horizontal Velocity Error in m/sec with resolution 0.01 (SiRFDrive only) */ + INT32 ClkBias; /* Clock Bias in meters with resolution 0.01 */ + UINT32 ClkBiasE; /* Clock Bias Error in meters with resolution 0.01 (SiRFDrive only) */ + INT32 ClkDrift; /* Clock Drift in m/sec with resolution 0.01 */ + UINT32 ClkDriftE; /* Clock Drift in m/sec with resolution 0.01 (SiRFDrive only) */ + UINT32 Trvled; /* Distance Traveled since reset in meters (SiRFDrive only) */ + UINT16 TrvledE; /* Distance Traveled Error in meters (SiRFDrive only) */ + UINT16 HdE; /* Heading Error [0 to 180] in degrees with resolution 0.01 (SiRFDrive only) */ + UINT8 SVIDCnt; /* Number of SVs in solution [0 to 12] */ + UINT8 HDOP; /* HDOP [0..51] with resolution 0.2 */ + UINT8 Reserved; /* Reserved */ + + UINT16 ufSog; /* Speed Over Ground in m/sec with resolution 0.01 ,unfiltered*/ + UINT16 ufCog; /* Course Over Ground [0 to 360] in degrees with resolution 0.01, unfiltered */ + +} T_SBN_REC; #endif diff --git a/gpsbabel/navitel.c b/gpsbabel/navitel.c index 7b82d5c80..7407a3e27 100644 --- a/gpsbabel/navitel.c +++ b/gpsbabel/navitel.c @@ -26,7 +26,7 @@ #define MYNAME "navitel" -static gbfile *fin, *fout; +static gbfile* fin, *fout; static char new_track; static int trkpts; @@ -35,119 +35,119 @@ static int trkpts; *******************************************************************************/ static void -navitel_rd_init(const char *fname) +navitel_rd_init(const char* fname) { - fin = gbfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } static void navitel_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void navitel_read_track(void) { - int points, i; - route_head *trk = NULL; + int points, i; + route_head* trk = NULL; - points = gbfgetint32(fin); - (void) gbfgetint32(fin); /* unknown */ + points = gbfgetint32(fin); + (void) gbfgetint32(fin); /* unknown */ - for (i = 0; i < points; i++) { - int lat, lon; - waypoint *wpt; + for (i = 0; i < points; i++) { + int lat, lon; + waypoint* wpt; - lon = gbfgetint32(fin); - lat = gbfgetint32(fin); + lon = gbfgetint32(fin); + lat = gbfgetint32(fin); - wpt = waypt_new(); - wpt->latitude = GPS_Math_Semi_To_Deg(lat & 0x7FFFFFFF); - wpt->longitude = GPS_Math_Semi_To_Deg(lon); + wpt = waypt_new(); + wpt->latitude = GPS_Math_Semi_To_Deg(lat & 0x7FFFFFFF); + wpt->longitude = GPS_Math_Semi_To_Deg(lon); - if ((lat >> 31) || (trk == NULL)) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - } + if ((lat >> 31) || (trk == NULL)) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + } } static void -navitel_wr_init(const char *fname) +navitel_wr_init(const char* fname) { - fout = gbfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); } static void navitel_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void -navitel_enum_trkpts(const waypoint *wpt) +navitel_enum_trkpts(const waypoint* wpt) { - trkpts++; + trkpts++; } static void -navitel_disp_trk_head(const route_head *trk) +navitel_disp_trk_head(const route_head* trk) { - new_track = 1; + new_track = 1; } static void -navitel_disp_trkpts(const waypoint *wpt) +navitel_disp_trkpts(const waypoint* wpt) { - int lat, lon; + int lat, lon; - lat = GPS_Math_Deg_To_Semi(wpt->latitude); - lon = GPS_Math_Deg_To_Semi(wpt->longitude); + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); - if (new_track) { - lat |= (1 << 31); - new_track = 0; - } + if (new_track) { + lat |= (1 << 31); + new_track = 0; + } - gbfputint32(lon, fout); - gbfputint32(lat, fout); + gbfputint32(lon, fout); + gbfputint32(lat, fout); } static void navitel_write_track(void) { - trkpts = 0; - track_disp_all(NULL, NULL, navitel_enum_trkpts); - if (trkpts > 10000) { - trkpts = 10000; - warning(MYNAME ": Can store only 10000 points per file!\n"); - } - - gbfputint32(trkpts, fout); - gbfputint32(1, fout); /* ? */ - track_disp_all(navitel_disp_trk_head, NULL, navitel_disp_trkpts); + trkpts = 0; + track_disp_all(NULL, NULL, navitel_enum_trkpts); + if (trkpts > 10000) { + trkpts = 10000; + warning(MYNAME ": Can store only 10000 points per file!\n"); + } + + gbfputint32(trkpts, fout); + gbfputint32(1, fout); /* ? */ + track_disp_all(navitel_disp_trk_head, NULL, navitel_disp_trkpts); } /**************************************************************************/ ff_vecs_t navitel_trk_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - navitel_rd_init, - navitel_wr_init, - navitel_rd_deinit, - navitel_wr_deinit, - navitel_read_track, - navitel_write_track, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* Nothing to convert */ + ff_type_file, + { + ff_cap_none /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + navitel_rd_init, + navitel_wr_init, + navitel_rd_deinit, + navitel_wr_deinit, + navitel_read_track, + navitel_write_track, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* Nothing to convert */ }; /**************************************************************************/ diff --git a/gpsbabel/netstumbler.c b/gpsbabel/netstumbler.c index be29aca03..f4140dc3f 100644 --- a/gpsbabel/netstumbler.c +++ b/gpsbabel/netstumbler.c @@ -24,12 +24,12 @@ #include "csv_util.h" #include -static gbfile *file_in; -static char *nseicon = NULL; -static char *nsneicon = NULL; -static char *seicon = NULL; -static char *sneicon = NULL; -static char *snmac = NULL; +static gbfile* file_in; +static char* nseicon = NULL; +static char* nsneicon = NULL; +static char* seicon = NULL; +static char* sneicon = NULL; +static char* snmac = NULL; static int macstumbler; static void fix_netstumbler_dupes(void); @@ -38,228 +38,247 @@ static void fix_netstumbler_dupes(void); static arglist_t netstumbler_args[] = { - {"nseicon", &nseicon, "Non-stealth encrypted icon name", - "Red Square", ARGTYPE_STRING, ARG_NOMINMAX }, - {"nsneicon", &nsneicon, "Non-stealth non-encrypted icon name", - "Green Square", ARGTYPE_STRING, ARG_NOMINMAX }, - {"seicon", &seicon, "Stealth encrypted icon name", - "Red Diamond", ARGTYPE_STRING, ARG_NOMINMAX }, - {"sneicon", &sneicon, "Stealth non-encrypted icon name", - "Green Diamond", ARGTYPE_STRING, ARG_NOMINMAX }, - {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - ARG_TERMINATOR + { + "nseicon", &nseicon, "Non-stealth encrypted icon name", + "Red Square", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "nsneicon", &nsneicon, "Non-stealth non-encrypted icon name", + "Green Square", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "seicon", &seicon, "Stealth encrypted icon name", + "Red Diamond", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "sneicon", &sneicon, "Stealth non-encrypted icon name", + "Green Diamond", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void -rd_init(const char *fname) +rd_init(const char* fname) { - file_in = gbfopen(fname, "rb", MYNAME); - macstumbler = 0; + file_in = gbfopen(fname, "rb", MYNAME); + macstumbler = 0; } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void data_read(void) { - char *ibuf; - char ssid[2 + 32 + 2 + 1]; /* "( " + SSID + " )" + null */ - char mac[2 + 17 + 2 + 1]; /* "( " + MAC + " )" + null */ - char desc[sizeof ssid - 1 + 15 + 1]; /* room for channel/speed */ - double lat = 0, lon = 0; - waypoint *wpt_tmp; - int line_no = 0; - int stealth_num = 0, whitespace_num = 0; - long flags = 0; - int speed = 0, channel = 0; - struct tm tm; - int line = 0; - - memset(&tm, 0, sizeof(tm)); - - while ((ibuf = gbfgetstr(file_in))) { - char *field; - int field_num, len, i, stealth = 0; - - if ((line++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - ibuf = lrtrim(ibuf); - /* A sharp in column zero might be a comment. Or it might be - * something useful, like the date. - */ - - if (ibuf[0] == '#') { - if (strncmp(&ibuf[2], "$DateGMT:", 9) == 0) { - tm.tm_year = atoi(&ibuf[12]) - 1900; - tm.tm_mon = atoi(&ibuf[17]) - 1; - tm.tm_mday = atoi(&ibuf[20]); - } - - /* - * Mac stumbler files are the same, except - * use DDMM.mmm instad of DD.DDDD. - */ - if (strstr(ibuf, "Creator: MacStumbler")) { - macstumbler = 1; - } - - continue; - } - - field_num = 0; - line_no++; - field = csv_lineparse(ibuf, "\t", "", line_no); - - while (field) { - switch (field_num) { - case 0: /* lat */ - lat = atof(&field[2]); - if (field[0] == 'S') - lat = -lat; - if (macstumbler) { - lat = ddmm2degrees(lat); - } - break; - - case 1: /* long */ - lon = atof(&field[2]); - if (field[0] == 'W') - lon = -lon; - if (macstumbler) { - lon = ddmm2degrees(lon); - } - break; - - case 2: /* ( SSID ) */ - strcpy(ssid, &field[2]); /* zap "( " */ - len = strlen(ssid) - 2; - ssid[len] = 0; /* zap " )" */ - stealth = (len == 0); - /* don't alter SSID in snmac mode */ - if (!snmac) { - int found = 0; - /* check for all whitespace */ - for (i = 0; i < len && !found; i++) { - if (!isspace(ssid[i])) - found = 1; - } - - if (!stealth && !found) - snprintf(ssid, sizeof ssid, "Whitespace/%d", ++whitespace_num); - } - break; - - case 4: /* ( MAC address ) */ - strcpy(mac, &field[2]); /* zap "( " */ - mac[strlen(mac) - 2] = 0;/* zap " )" */ - break; - - case 5: /* time */ - tm.tm_hour = atoi(field); - tm.tm_min = atoi(&field[3]); - tm.tm_sec = atoi(&field[6]); - break; - - case 8: /* flags */ - flags = strtol(field, NULL, 16); - break; - - case 11: /* data rate */ - speed = atoi(field) / 10; - break; - - case 12: /* last channel */ - channel = atoi(field); - break; - - case 3: /* type */ - case 6: /* SNR/sig/noise */ - case 7: /* name */ - case 9: /* channel bits */ - case 10: /* beacon interval */ - default: - break; - } - - field_num++; - field = csv_lineparse(NULL, "\t", "", line_no); - } - - if (lat == 0 && lon == 0) /* skip records with no GPS data */ - continue; - - wpt_tmp = waypt_new(); - - if (stealth) { - if (!snmac) - snprintf(ssid, sizeof ssid, "Stealth/%d", ++stealth_num); - - if (flags & 0x0010) /* encrypted? */ - wpt_tmp->icon_descr = seicon; - else - wpt_tmp->icon_descr = sneicon; - } else { - if (flags & 0x0010) /* encrypted? */ - wpt_tmp->icon_descr = nseicon; - else - wpt_tmp->icon_descr = nsneicon; - } - - if (snmac) { - snprintf(desc, sizeof desc, "%s/%d Mbps/Ch %d", ssid, speed, channel); - wpt_tmp->shortname = xstrdup(mac); - } else { - snprintf(desc, sizeof desc, "%d Mbps/Ch %d/%s", speed, channel, mac); - wpt_tmp->shortname = xstrdup(ssid); - } - - wpt_tmp->description = xstrdup(desc); - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - wpt_tmp->creation_time = mktime(&tm); - - waypt_add(wpt_tmp); - } - fix_netstumbler_dupes(); + char* ibuf; + char ssid[2 + 32 + 2 + 1]; /* "( " + SSID + " )" + null */ + char mac[2 + 17 + 2 + 1]; /* "( " + MAC + " )" + null */ + char desc[sizeof ssid - 1 + 15 + 1]; /* room for channel/speed */ + double lat = 0, lon = 0; + waypoint* wpt_tmp; + int line_no = 0; + int stealth_num = 0, whitespace_num = 0; + long flags = 0; + int speed = 0, channel = 0; + struct tm tm; + int line = 0; + + memset(&tm, 0, sizeof(tm)); + + while ((ibuf = gbfgetstr(file_in))) { + char* field; + int field_num, len, i, stealth = 0; + + if ((line++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + ibuf = lrtrim(ibuf); + /* A sharp in column zero might be a comment. Or it might be + * something useful, like the date. + */ + + if (ibuf[0] == '#') { + if (strncmp(&ibuf[2], "$DateGMT:", 9) == 0) { + tm.tm_year = atoi(&ibuf[12]) - 1900; + tm.tm_mon = atoi(&ibuf[17]) - 1; + tm.tm_mday = atoi(&ibuf[20]); + } + + /* + * Mac stumbler files are the same, except + * use DDMM.mmm instad of DD.DDDD. + */ + if (strstr(ibuf, "Creator: MacStumbler")) { + macstumbler = 1; + } + + continue; + } + + field_num = 0; + line_no++; + field = csv_lineparse(ibuf, "\t", "", line_no); + + while (field) { + switch (field_num) { + case 0: /* lat */ + lat = atof(&field[2]); + if (field[0] == 'S') { + lat = -lat; + } + if (macstumbler) { + lat = ddmm2degrees(lat); + } + break; + + case 1: /* long */ + lon = atof(&field[2]); + if (field[0] == 'W') { + lon = -lon; + } + if (macstumbler) { + lon = ddmm2degrees(lon); + } + break; + + case 2: /* ( SSID ) */ + strcpy(ssid, &field[2]); /* zap "( " */ + len = strlen(ssid) - 2; + ssid[len] = 0; /* zap " )" */ + stealth = (len == 0); + /* don't alter SSID in snmac mode */ + if (!snmac) { + int found = 0; + /* check for all whitespace */ + for (i = 0; i < len && !found; i++) { + if (!isspace(ssid[i])) { + found = 1; + } + } + + if (!stealth && !found) { + snprintf(ssid, sizeof ssid, "Whitespace/%d", ++whitespace_num); + } + } + break; + + case 4: /* ( MAC address ) */ + strcpy(mac, &field[2]); /* zap "( " */ + mac[strlen(mac) - 2] = 0;/* zap " )" */ + break; + + case 5: /* time */ + tm.tm_hour = atoi(field); + tm.tm_min = atoi(&field[3]); + tm.tm_sec = atoi(&field[6]); + break; + + case 8: /* flags */ + flags = strtol(field, NULL, 16); + break; + + case 11: /* data rate */ + speed = atoi(field) / 10; + break; + + case 12: /* last channel */ + channel = atoi(field); + break; + + case 3: /* type */ + case 6: /* SNR/sig/noise */ + case 7: /* name */ + case 9: /* channel bits */ + case 10: /* beacon interval */ + default: + break; + } + + field_num++; + field = csv_lineparse(NULL, "\t", "", line_no); + } + + if (lat == 0 && lon == 0) { /* skip records with no GPS data */ + continue; + } + + wpt_tmp = waypt_new(); + + if (stealth) { + if (!snmac) { + snprintf(ssid, sizeof ssid, "Stealth/%d", ++stealth_num); + } + + if (flags & 0x0010) { /* encrypted? */ + wpt_tmp->icon_descr = seicon; + } else { + wpt_tmp->icon_descr = sneicon; + } + } else { + if (flags & 0x0010) { /* encrypted? */ + wpt_tmp->icon_descr = nseicon; + } else { + wpt_tmp->icon_descr = nsneicon; + } + } + + if (snmac) { + snprintf(desc, sizeof desc, "%s/%d Mbps/Ch %d", ssid, speed, channel); + wpt_tmp->shortname = xstrdup(mac); + } else { + snprintf(desc, sizeof desc, "%d Mbps/Ch %d/%s", speed, channel, mac); + wpt_tmp->shortname = xstrdup(ssid); + } + + wpt_tmp->description = xstrdup(desc); + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + wpt_tmp->creation_time = mktime(&tm); + + waypt_add(wpt_tmp); + } + fix_netstumbler_dupes(); } -typedef struct -{ - unsigned long crc; - waypoint *wpt; +typedef struct { + unsigned long crc; + waypoint* wpt; } htable_t; static int -compare(const void *a, const void *b) +compare(const void* a, const void* b) { - unsigned long crc_a = ((const htable_t *)a)->crc; - unsigned long crc_b = ((const htable_t *)b)->crc; - - /* we can't just return crc_a - crc_b because the return type is - * signed. - * */ - - if (crc_a < crc_b) - return -1; - else if (crc_a > crc_b) - return 1; - else { - /* CRCs are equal; we need to subsort on the description (which - * includes the MAC address) to guarantee the same ordering of - * the output for any qsort() implementation. this is strictly - * to make the testo script happy. - * */ - - waypoint *wpt_a = ((const htable_t *)a)->wpt; - waypoint *wpt_b = ((const htable_t *)b)->wpt; - - return strcmp(wpt_a->description, wpt_b->description); - } + unsigned long crc_a = ((const htable_t*)a)->crc; + unsigned long crc_b = ((const htable_t*)b)->crc; + + /* we can't just return crc_a - crc_b because the return type is + * signed. + * */ + + if (crc_a < crc_b) { + return -1; + } else if (crc_a > crc_b) { + return 1; + } else { + /* CRCs are equal; we need to subsort on the description (which + * includes the MAC address) to guarantee the same ordering of + * the output for any qsort() implementation. this is strictly + * to make the testo script happy. + * */ + + waypoint* wpt_a = ((const htable_t*)a)->wpt; + waypoint* wpt_b = ((const htable_t*)b)->wpt; + + return strcmp(wpt_a->description, wpt_b->description); + } } /* netstumbler data will have a lot of duplicate shortnames if the SSID @@ -271,55 +290,56 @@ static void fix_netstumbler_dupes(void) { - int i, ct = waypt_count(), serial = 0; - htable_t *htable, *bh; - queue *elem, *tmp; - extern queue waypt_head; - const char *snptr; - char *tmp_sn; - unsigned long last_crc; - char ssid[32 + 5 + 1]; - - htable = (htable_t *) xmalloc(ct * sizeof *htable); - bh = htable; - - i = 0; - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - bh->wpt = (waypoint *) elem; - snptr = bh->wpt->shortname; - tmp_sn = strlower(xstrdup(snptr)); - bh->crc = get_crc32(tmp_sn, strlen(snptr)); - xfree(tmp_sn); - i ++; - bh ++; - } - - qsort(htable, ct, sizeof *htable, compare); - - last_crc = htable[0].crc + 1; /* force mismatch */ - - for (i = 0, bh = htable; i < ct; i++, bh++) { - if (last_crc == bh->crc) { - snprintf(ssid, sizeof ssid, "%s/%d", bh->wpt->shortname, ++serial); - xfree(bh->wpt->shortname); - bh->wpt->shortname = xstrdup(ssid); - } else - last_crc = bh->crc; - } - - xfree(htable); + int i, ct = waypt_count(), serial = 0; + htable_t* htable, *bh; + queue* elem, *tmp; + extern queue waypt_head; + const char* snptr; + char* tmp_sn; + unsigned long last_crc; + char ssid[32 + 5 + 1]; + + htable = (htable_t*) xmalloc(ct * sizeof *htable); + bh = htable; + + i = 0; + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + bh->wpt = (waypoint*) elem; + snptr = bh->wpt->shortname; + tmp_sn = strlower(xstrdup(snptr)); + bh->crc = get_crc32(tmp_sn, strlen(snptr)); + xfree(tmp_sn); + i ++; + bh ++; + } + + qsort(htable, ct, sizeof *htable, compare); + + last_crc = htable[0].crc + 1; /* force mismatch */ + + for (i = 0, bh = htable; i < ct; i++, bh++) { + if (last_crc == bh->crc) { + snprintf(ssid, sizeof ssid, "%s/%d", bh->wpt->shortname, ++serial); + xfree(bh->wpt->shortname); + bh->wpt->shortname = xstrdup(ssid); + } else { + last_crc = bh->crc; + } + } + + xfree(htable); } ff_vecs_t netstumbler_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_none, ff_cap_none }, - rd_init, - NULL, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - netstumbler_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + netstumbler_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/nmea.c b/gpsbabel/nmea.c index df3da62bd..f0bc5119a 100644 --- a/gpsbabel/nmea.c +++ b/gpsbabel/nmea.c @@ -107,12 +107,12 @@ ****************************************/ /* - * An input file may have both GGA and GLL and RMC sentences for the exact + * An input file may have both GGA and GLL and RMC sentences for the exact * same position fix. If we see a single GGA, start ignoring GLL's and RMC's. * GLL's will also be ignored if RMC's are found and GGA's not found. */ -/* +/* Zmarties notes: In practice, all fields of the NMEA sentences should be treated as optional - @@ -135,27 +135,27 @@ sentence is truncated - and missing part of the line, including the checksum. */ typedef enum { - gp_unknown = 0, - gpgga, - gplgll, - gprmc + gp_unknown = 0, + gpgga, + gplgll, + gprmc } preferred_posn_type; enum { - rm_unknown = 0, - rm_serial, - rm_file + rm_unknown = 0, + rm_serial, + rm_file } read_mode; -static gbfile *file_in, *file_out; -static route_head *trk_head; +static gbfile* file_in, *file_out; +static route_head* trk_head; static short_handle mkshort_handle; static preferred_posn_type posn_type; static struct tm tm; -static waypoint *curr_waypt; -static waypoint *last_waypt; -static void * gbser_handle; -static const char *posn_fname; +static waypoint* curr_waypt; +static waypoint* last_waypt; +static void* gbser_handle; +static const char* posn_fname; static queue pcmpt_head; static int without_date; /* number of created trackpoints without a valid date */ @@ -163,17 +163,17 @@ static struct tm opt_tm; /* converted "date" parameter */ #define MYNAME "nmea" -static char *opt_gprmc; -static char *opt_gpgga; -static char *opt_gpvtg; -static char *opt_gpgsa; -static char *snlenopt; -static char *optdate; -static char *getposnarg; -static char *opt_sleep; -static char *opt_baud; -static char *opt_append; -static char *opt_gisteq; +static char* opt_gprmc; +static char* opt_gpgga; +static char* opt_gpvtg; +static char* opt_gpgsa; +static char* snlenopt; +static char* optdate; +static char* getposnarg; +static char* opt_sleep; +static char* opt_baud; +static char* opt_append; +static char* opt_gisteq; static long sleepus; static int getposn; @@ -185,23 +185,25 @@ static double last_read_time; /* Last timestamp of GGA or PRMC */ static int datum; static int had_checksum; -static waypoint * nmea_rd_posn(posn_status *); -static void nmea_rd_posn_init(const char *fname); +static waypoint* nmea_rd_posn(posn_status*); +static void nmea_rd_posn_init(const char* fname); arglist_t nmea_args[] = { - {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64" }, - {"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"gpgga", &opt_gpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"gpvtg", &opt_gpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"gpgsa", &opt_gpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - { "get_posn", &getposnarg, "Return current position as a waypoint", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - {"append_positioning", &opt_append, "Append realtime positioning data to the output file instead of truncating", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - {"gisteq", &opt_gisteq, "Write tracks for Gisteq Phototracker", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64" }, + {"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpgga", &opt_gpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpvtg", &opt_gpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpgsa", &opt_gpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + { + "get_posn", &getposnarg, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"append_positioning", &opt_append, "Append realtime positioning data to the output file instead of truncating", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"gisteq", &opt_gisteq, "Write tracks for Gisteq Phototracker", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define CHECK_BOOL(a) if (a && (*a == '0')) a = NULL @@ -210,1145 +212,1171 @@ arglist_t nmea_args[] = { * Slightly different than the Magellan checksum fn. */ int -nmea_cksum(const char *const buf) +nmea_cksum(const char* const buf) { - int x = 0 ; - const char *p; + int x = 0 ; + const char* p; - for (p = buf; *p; p++) { - x ^= *p; - } - return x; + for (p = buf; *p; p++) { + x ^= *p; + } + return x; } static void -nmea_add_wpt(waypoint *wpt, route_head *trk) +nmea_add_wpt(waypoint* wpt, route_head* trk) { - if (datum != DATUM_WGS84) { - double lat, lon, alt; - GPS_Math_Known_Datum_To_WGS84_M( - wpt->latitude, wpt->longitude, 0, - &lat, &lon, &alt, datum); - wpt->latitude = lat; - wpt->longitude = lon; - } - if (trk != NULL) track_add_wpt(trk, wpt); - else waypt_add(wpt); + if (datum != DATUM_WGS84) { + double lat, lon, alt; + GPS_Math_Known_Datum_To_WGS84_M( + wpt->latitude, wpt->longitude, 0, + &lat, &lon, &alt, datum); + wpt->latitude = lat; + wpt->longitude = lon; + } + if (trk != NULL) { + track_add_wpt(trk, wpt); + } else { + waypt_add(wpt); + } } static void -nmea_release_wpt(waypoint *wpt) +nmea_release_wpt(waypoint* wpt) { - if (wpt && ((wpt->Q.next == NULL) || (wpt->Q.next == &wpt->Q))) { - /* This waypoint isn't queued. - Release it, because we don't have any reference to this - waypoint (! memory leak !) */ - waypt_free(wpt); - } + if (wpt && ((wpt->Q.next == NULL) || (wpt->Q.next == &wpt->Q))) { + /* This waypoint isn't queued. + Release it, because we don't have any reference to this + waypoint (! memory leak !) */ + waypt_free(wpt); + } } static void -nmea_rd_init(const char *fname) +nmea_rd_init(const char* fname) { - curr_waypt = NULL; - last_waypt = NULL; - last_time = -1; - datum = DATUM_WGS84; - had_checksum = 0; - - CHECK_BOOL(opt_gprmc); - CHECK_BOOL(opt_gpgga); - CHECK_BOOL(opt_gpvtg); - CHECK_BOOL(opt_gpgsa); - CHECK_BOOL(opt_gisteq); - - QUEUE_INIT(&pcmpt_head); - - if (getposnarg) { - getposn = 1; - } - - /* A special case hack that gets our current position and returns - * it as one waypoint. - */ - if (getposn) { - waypoint *wpt; - posn_status st; - nmea_rd_posn_init(fname); - wpt = nmea_rd_posn(&st); - if (!wpt) { - return; - } - if (wpt->shortname) { - xfree(wpt->shortname); - } - wpt->shortname = xstrdup("Position"); - nmea_add_wpt(wpt, NULL); - return; - } - - read_mode = rm_file; - file_in = gbfopen(fname, "rb", MYNAME); + curr_waypt = NULL; + last_waypt = NULL; + last_time = -1; + datum = DATUM_WGS84; + had_checksum = 0; + + CHECK_BOOL(opt_gprmc); + CHECK_BOOL(opt_gpgga); + CHECK_BOOL(opt_gpvtg); + CHECK_BOOL(opt_gpgsa); + CHECK_BOOL(opt_gisteq); + + QUEUE_INIT(&pcmpt_head); + + if (getposnarg) { + getposn = 1; + } + + /* A special case hack that gets our current position and returns + * it as one waypoint. + */ + if (getposn) { + waypoint* wpt; + posn_status st; + nmea_rd_posn_init(fname); + wpt = nmea_rd_posn(&st); + if (!wpt) { + return; + } + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("Position"); + nmea_add_wpt(wpt, NULL); + return; + } + + read_mode = rm_file; + file_in = gbfopen(fname, "rb", MYNAME); } static void nmea_rd_deinit(void) { - switch(read_mode) { - case rm_serial: - gbser_deinit(gbser_handle); - break; - case rm_file: - gbfclose(file_in); - file_in = NULL; - break; - default: - fatal("nmea_rd_deinit: illegal read_mode.\n"); - break; - } + switch (read_mode) { + case rm_serial: + gbser_deinit(gbser_handle); + break; + case rm_file: + gbfclose(file_in); + file_in = NULL; + break; + default: + fatal("nmea_rd_deinit: illegal read_mode.\n"); + break; + } } static void -nmea_wr_init(const char *portname) +nmea_wr_init(const char* portname) { - CHECK_BOOL(opt_gprmc); - CHECK_BOOL(opt_gpgga); - CHECK_BOOL(opt_gpvtg); - CHECK_BOOL(opt_gpgsa); - CHECK_BOOL(opt_gisteq); - - append_output = atoi(opt_append); - - file_out = gbfopen(portname, append_output ? "a+" : "w+", MYNAME); - - sleepus = -1; - if ( opt_sleep ) { - if ( *opt_sleep ) { - sleepus = 1e6 * atof(opt_sleep); - } - else { - sleepus = -1; - } - } - - mkshort_handle = (struct short_handle*) mkshort_new_handle(); - setshort_length(mkshort_handle, atoi(snlenopt)); - - if (opt_gisteq) { - opt_gpgga = NULL; - opt_gpvtg = NULL; - opt_gpgsa = NULL; - } + CHECK_BOOL(opt_gprmc); + CHECK_BOOL(opt_gpgga); + CHECK_BOOL(opt_gpvtg); + CHECK_BOOL(opt_gpgsa); + CHECK_BOOL(opt_gisteq); + + append_output = atoi(opt_append); + + file_out = gbfopen(portname, append_output ? "a+" : "w+", MYNAME); + + sleepus = -1; + if (opt_sleep) { + if (*opt_sleep) { + sleepus = 1e6 * atof(opt_sleep); + } else { + sleepus = -1; + } + } + + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, atoi(snlenopt)); + + if (opt_gisteq) { + opt_gpgga = NULL; + opt_gpvtg = NULL; + opt_gpgsa = NULL; + } } static void nmea_wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void -nmea_set_waypoint_time(waypoint *wpt, struct tm *time, int microseconds) +nmea_set_waypoint_time(waypoint* wpt, struct tm* time, int microseconds) { - if (time->tm_year == 0) - { - wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; - wpt->microseconds = microseconds; - if (wpt->wpt_flags.fmt_use == 0) - { - wpt->wpt_flags.fmt_use = 1; - without_date++; - } - } - else - { - wpt->creation_time = mkgmtime(time); - wpt->microseconds = microseconds; - if (wpt->wpt_flags.fmt_use != 0) - { - wpt->wpt_flags.fmt_use = 0; - without_date--; - } - } + if (time->tm_year == 0) { + wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use == 0) { + wpt->wpt_flags.fmt_use = 1; + without_date++; + } + } else { + wpt->creation_time = mkgmtime(time); + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use != 0) { + wpt->wpt_flags.fmt_use = 0; + without_date--; + } + } } static void -gpgll_parse(char *ibuf) +gpgll_parse(char* ibuf) { - double latdeg, lngdeg, microseconds; - char lngdir, latdir; - double hmsd; - int hms; - char valid = 0; - waypoint *waypt; - - if (trk_head == NULL) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - } - - sscanf(ibuf,"$GPGLL,%lf,%c,%lf,%c,%lf,%c,", - &latdeg,&latdir, - &lngdeg,&lngdir, - &hmsd,&valid); - - if (valid != 'A') - return; - - hms = (int) hmsd; - microseconds = MILLI_TO_MICRO(1000 * (hmsd - hms)); - - tm.tm_sec = hms % 100; - hms = hms / 100; - tm.tm_min = hms % 100; - hms = hms / 100; - tm.tm_hour = hms % 100; - - last_read_time = hms; - - waypt = waypt_new(); - - nmea_set_waypoint_time(waypt, &tm, microseconds); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - nmea_release_wpt(curr_waypt); - curr_waypt = waypt; + double latdeg, lngdeg, microseconds; + char lngdir, latdir; + double hmsd; + int hms; + char valid = 0; + waypoint* waypt; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + sscanf(ibuf,"$GPGLL,%lf,%c,%lf,%c,%lf,%c,", + &latdeg,&latdir, + &lngdeg,&lngdir, + &hmsd,&valid); + + if (valid != 'A') { + return; + } + + hms = (int) hmsd; + microseconds = MILLI_TO_MICRO(1000 * (hmsd - hms)); + + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + + last_read_time = hms; + + waypt = waypt_new(); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; } static void -gpgga_parse(char *ibuf) +gpgga_parse(char* ibuf) { - double latdeg, lngdeg; - char lngdir, latdir; - double hms; - double alt; - int fix = fix_unknown; - int nsats = 0; - double hdop; - char altunits; - waypoint *waypt; - double microseconds; - - if (trk_head == NULL) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - } - - sscanf(ibuf,"$GPGGA,%lf,%lf,%c,%lf,%c,%d,%d,%lf,%lf,%c", - &hms, &latdeg,&latdir, - &lngdeg,&lngdir, - &fix,&nsats,&hdop,&alt,&altunits); - - /* - * In serial mode, allow the fix with an invalid position through - * as serial units will often spit a remembered position up and - * that is more comfortable than nothing at all... - */ - if ((fix <= 0) && (read_mode != rm_serial)) { - return; - } - - last_read_time = hms; - microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); - - tm.tm_sec = (long) hms % 100; - hms = hms / 100; - tm.tm_min = (long) hms % 100; - hms = hms / 100; - tm.tm_hour = (long) hms % 100; - - waypt = waypt_new(); - - nmea_set_waypoint_time(waypt, &tm, microseconds); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - waypt->altitude = alt; - - waypt->sat = nsats; - - waypt->hdop = hdop; - - switch (fix) { - case 0: - waypt->fix = fix_none; - break; - case 1: - waypt->fix = (nsats>3)?(fix_3d):(fix_2d); - break; - case 2: - waypt->fix = fix_dgps; - break; - case 3: - waypt->fix = fix_pps; - break; - } - - nmea_release_wpt(curr_waypt); - curr_waypt = waypt; + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + double alt; + int fix = fix_unknown; + int nsats = 0; + double hdop; + char altunits; + waypoint* waypt; + double microseconds; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + sscanf(ibuf,"$GPGGA,%lf,%lf,%c,%lf,%c,%d,%d,%lf,%lf,%c", + &hms, &latdeg,&latdir, + &lngdeg,&lngdir, + &fix,&nsats,&hdop,&alt,&altunits); + + /* + * In serial mode, allow the fix with an invalid position through + * as serial units will often spit a remembered position up and + * that is more comfortable than nothing at all... + */ + if ((fix <= 0) && (read_mode != rm_serial)) { + return; + } + + last_read_time = hms; + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + waypt = waypt_new(); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + + waypt->sat = nsats; + + waypt->hdop = hdop; + + switch (fix) { + case 0: + waypt->fix = fix_none; + break; + case 1: + waypt->fix = (nsats>3)?(fix_3d):(fix_2d); + break; + case 2: + waypt->fix = fix_dgps; + break; + case 3: + waypt->fix = fix_pps; + break; + } + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; } static void -gprmc_parse(char *ibuf) +gprmc_parse(char* ibuf) { - double latdeg, lngdeg; - char lngdir, latdir; - double hms; - char fix; - unsigned int dmy; - double speed,course; - waypoint *waypt; - double microseconds; - char *dmybuf; - int i; - - if (trk_head == NULL) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - } - - /* - * Read everything except the dmy, in case lngdeg - * and lngdir are missing. - */ - sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf", - &hms, &fix, &latdeg, &latdir, - &lngdeg, &lngdir, - &speed, &course); - - if (fix != 'A') { - /* ignore this fix - it is invalid */ - return; - } - - /* Skip past nine commas in ibuf to reach the dmy value */ - for (dmybuf=ibuf,i=0; i<9 && dmybuf != NULL; i++) { - dmybuf= strchr(dmybuf, ','); - dmybuf++; - } - - /* Now read dmy from the correct position */ - sscanf(dmybuf,"%u", &dmy); - - last_read_time = hms; - microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); - - tm.tm_sec = (long) hms % 100; - hms = hms / 100; - tm.tm_min = (long) hms % 100; - hms = hms / 100; - tm.tm_hour = (long) hms % 100; - - tm.tm_year = dmy % 100 + 100; - dmy = dmy / 100; - tm.tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm.tm_mday = dmy; - - if (posn_type == gpgga) { - /* capture useful data update and exit */ - if (curr_waypt) { - if (! WAYPT_HAS(curr_waypt, speed)) - WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed)); - if (! WAYPT_HAS(curr_waypt, course)) - WAYPT_SET(curr_waypt, course, course); - /* The change of date wasn't recorded when - * going from 235959 to 000000. */ - nmea_set_waypoint_time(curr_waypt, &tm, microseconds); - } - /* This point is both a waypoint and a trackpoint. */ - if (amod_waypoint) { - waypt_add(waypt_dupe(curr_waypt)); - amod_waypoint = 0; - } - return; - } - - waypt = waypt_new(); - - WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); - - WAYPT_SET(waypt, course, course); - - nmea_set_waypoint_time(waypt, &tm, microseconds); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - nmea_release_wpt(curr_waypt); - curr_waypt = waypt; - - /* This point is both a waypoint and a trackpoint. */ - if (amod_waypoint) { - waypt_add(waypt_dupe(waypt)); - amod_waypoint = 0; - } + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + char fix; + unsigned int dmy; + double speed,course; + waypoint* waypt; + double microseconds; + char* dmybuf; + int i; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + /* + * Read everything except the dmy, in case lngdeg + * and lngdir are missing. + */ + sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf", + &hms, &fix, &latdeg, &latdir, + &lngdeg, &lngdir, + &speed, &course); + + if (fix != 'A') { + /* ignore this fix - it is invalid */ + return; + } + + /* Skip past nine commas in ibuf to reach the dmy value */ + for (dmybuf=ibuf,i=0; i<9; i++) { + dmybuf= strchr(dmybuf, ','); + if (dmybuf==NULL) { + /* If we run out of commas, the sentence is invalid. */ + return; + } + dmybuf++; + } + + /* Now read dmy from the correct position */ + sscanf(dmybuf,"%u", &dmy); + + last_read_time = hms; + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + tm.tm_year = dmy % 100 + 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; + + if (posn_type == gpgga) { + /* capture useful data update and exit */ + if (curr_waypt) { + if (! WAYPT_HAS(curr_waypt, speed)) { + WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed)); + } + if (! WAYPT_HAS(curr_waypt, course)) { + WAYPT_SET(curr_waypt, course, course); + } + /* The change of date wasn't recorded when + * going from 235959 to 000000. */ + nmea_set_waypoint_time(curr_waypt, &tm, microseconds); + } + /* This point is both a waypoint and a trackpoint. */ + if (amod_waypoint) { + waypt_add(waypt_dupe(curr_waypt)); + amod_waypoint = 0; + } + return; + } + + waypt = waypt_new(); + + WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); + + WAYPT_SET(waypt, course, course); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; + + /* This point is both a waypoint and a trackpoint. */ + if (amod_waypoint) { + waypt_add(waypt_dupe(waypt)); + amod_waypoint = 0; + } } static void -gpwpl_parse(char *ibuf) +gpwpl_parse(char* ibuf) { - waypoint *waypt; - double latdeg, lngdeg; - char latdir, lngdir; - char sname[99]; - - sscanf(ibuf,"$GPWPL,%lf,%c,%lf,%c,%[^*]", - &latdeg,&latdir, - &lngdeg,&lngdir, - sname); - - waypt = waypt_new(); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - waypt->shortname = xstrdup(sname); - - curr_waypt = NULL; /* waypoints won't be updated with GPS fixes */ - nmea_add_wpt(waypt, NULL); + waypoint* waypt; + double latdeg, lngdeg; + char latdir, lngdir; + char sname[99]; + + sscanf(ibuf,"$GPWPL,%lf,%c,%lf,%c,%[^*]", + &latdeg,&latdir, + &lngdeg,&lngdir, + sname); + + waypt = waypt_new(); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->shortname = xstrdup(sname); + + curr_waypt = NULL; /* waypoints won't be updated with GPS fixes */ + nmea_add_wpt(waypt, NULL); } static void -gpzda_parse(char *ibuf) +gpzda_parse(char* ibuf) { - double hms; - int dd, mm, yy, lclhrs, lclmins; - - sscanf(ibuf,"$GPZDA,%lf,%d,%d,%d,%d,%d", - &hms, &dd, &mm, &yy, &lclhrs, &lclmins); - tm.tm_sec = (int) hms % 100; - tm.tm_min = (((int) hms - tm.tm_sec) / 100) % 100; - tm.tm_hour = (int) hms / 10000; - tm.tm_mday = dd; - tm.tm_mon = mm - 1; - tm.tm_year = yy - 1900; + double hms; + int dd, mm, yy, lclhrs, lclmins; + + sscanf(ibuf,"$GPZDA,%lf,%d,%d,%d,%d,%d", + &hms, &dd, &mm, &yy, &lclhrs, &lclmins); + tm.tm_sec = (int) hms % 100; + tm.tm_min = (((int) hms - tm.tm_sec) / 100) % 100; + tm.tm_hour = (int) hms / 10000; + tm.tm_mday = dd; + tm.tm_mon = mm - 1; + tm.tm_year = yy - 1900; } static void -gpgsa_parse(char *ibuf) +gpgsa_parse(char* ibuf) { - char fixauto; - char fix; - int prn[12]; - int scn,cnt; - float pdop=0,hdop=0,vdop=0; - char* tok=0; - - memset(prn,0xff,sizeof(prn)); - - scn = sscanf(ibuf,"$GPGSA,%c,%c,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", - &fixauto, &fix, - &prn[0],&prn[1],&prn[2],&prn[3],&prn[4],&prn[5], - &prn[6],&prn[7],&prn[8],&prn[9],&prn[10],&prn[11]); - - /* - sscanf has scanned all the leftmost elements - we'll rescan by skipping 15 commas to the dops - */ - tok = ibuf; - for (cnt=0;(tok)&&(cnt<15);cnt++) - { - tok = strchr(tok,','); - if (!tok) break; - tok++; - } - if (tok) sscanf(tok,"%f,%f,%f",&pdop,&hdop,&vdop); - - - if (curr_waypt) { - - if (curr_waypt->fix!=fix_dgps) { - if (fix=='3') curr_waypt->fix=fix_3d; - else if (fix=='2') curr_waypt->fix=fix_2d; - } - - curr_waypt->pdop = pdop; - curr_waypt->hdop = hdop; - curr_waypt->vdop = vdop; - - if (curr_waypt->sat <= 0) { - for (cnt=0;cnt<12;cnt++) - curr_waypt->sat += (prn[cnt]>0)?(1):(0); - } - } - + char fixauto; + char fix; + int prn[12]; + int scn,cnt; + float pdop=0,hdop=0,vdop=0; + char* tok=0; + + memset(prn,0xff,sizeof(prn)); + + scn = sscanf(ibuf,"$GPGSA,%c,%c,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + &fixauto, &fix, + &prn[0],&prn[1],&prn[2],&prn[3],&prn[4],&prn[5], + &prn[6],&prn[7],&prn[8],&prn[9],&prn[10],&prn[11]); + + /* + sscanf has scanned all the leftmost elements + we'll rescan by skipping 15 commas to the dops + */ + tok = ibuf; + for (cnt=0; (tok)&&(cnt<15); cnt++) { + tok = strchr(tok,','); + if (!tok) { + break; + } + tok++; + } + if (tok) { + sscanf(tok,"%f,%f,%f",&pdop,&hdop,&vdop); + } + + + if (curr_waypt) { + + if (curr_waypt->fix!=fix_dgps) { + if (fix=='3') { + curr_waypt->fix=fix_3d; + } else if (fix=='2') { + curr_waypt->fix=fix_2d; + } + } + + curr_waypt->pdop = pdop; + curr_waypt->hdop = hdop; + curr_waypt->vdop = vdop; + + if (curr_waypt->sat <= 0) { + for (cnt=0; cnt<12; cnt++) { + curr_waypt->sat += (prn[cnt]>0)?(1):(0); + } + } + } + } static void -gpvtg_parse(char *ibuf) +gpvtg_parse(char* ibuf) { - float course; - char ct; - float magcourse; - char cm; - double speed_n; - char cn; - double speed_k; - char ck; - - sscanf(ibuf,"$GPVTG,%f,%c,%f,%c,%lf,%c,%lf,%c", - &course,&ct,&magcourse,&cm,&speed_n,&cn,&speed_k,&ck); - - if (curr_waypt) { - WAYPT_SET(curr_waypt, course, course); - - if (speed_k>0) - WAYPT_SET(curr_waypt, speed, KPH_TO_MPS(speed_k)) - else - WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed_n)); - - } - + float course; + char ct; + float magcourse; + char cm; + double speed_n; + char cn; + double speed_k; + char ck; + + sscanf(ibuf,"$GPVTG,%f,%c,%f,%c,%lf,%c,%lf,%c", + &course,&ct,&magcourse,&cm,&speed_n,&cn,&speed_k,&ck); + + if (curr_waypt) { + WAYPT_SET(curr_waypt, course, course); + + if (speed_k>0) + WAYPT_SET(curr_waypt, speed, KPH_TO_MPS(speed_k)) + else { + WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed_n)); + } + + } + } /* * AVMAP EKP-IV Tracks - a proprietary (and very weird) extended NMEA. - * https://sourceforge.net/tracker/?func=detail&atid=489478&aid=1640814&group_id=58972 + * https://sourceforge.net/tracker/?func=detail&atid=489478&aid=1640814&group_id=58972 */ -static +static double pcmpt_deg(int d) { - int deg; - double minutes; + int deg; + double minutes; - deg = d / 100000; - minutes = (((d / 100000.0) - deg) * 100) / 60.0; - return (double) deg + minutes; + deg = d / 100000; + minutes = (((d / 100000.0) - deg) * 100) / 60.0; + return (double) deg + minutes; } void -pcmpt_parse(char *ibuf) +pcmpt_parse(char* ibuf) { - int i, j1, j2, j3, j4, j5, j6; - int lat, lon; - char altflag, u1, u2; - float alt, f1, f2; - char coords[20] = {0}; - int dmy, hms; - - dmy = hms = 0; - - sscanf(ibuf,"$PCMPT,%d,%d,%d,%c,%f,%d,%[^,],%d,%f,%d,%f,%c,%d,%c,%d", - &j1, &j2, &j3, &altflag, &alt, &j4, (char *) &coords, - &j5, &f1, &j6, &f2, &u1, &dmy, &u2, &hms); - - if (altflag == 'D' && curr_waypt && alt > 0) { - curr_waypt->altitude = alt /*+ 500*/; - return; - } - - /* - * There are a couple of different second line records, but we - * don't care about them. - */ - if (j2 != 1) { - return; - } - - sscanf(coords, "%d%n", &lat, &i); - if (coords[i] == 'S') lat = -lat; - sscanf(coords + i + 1, "%d%n", &lon, &i); - if (coords[i] == 'W') lon= -lon; - - if (lat || lon) { - curr_waypt = waypt_new(); - curr_waypt->longitude = pcmpt_deg(lon); - curr_waypt->latitude = pcmpt_deg(lat); - - tm.tm_sec = (long) hms % 100; - hms = hms / 100; - tm.tm_min = (long) hms % 100; - hms = hms / 100; - tm.tm_hour = (long) hms % 100; - - tm.tm_year = dmy % 10000 - 1900; - dmy = dmy / 10000; - tm.tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm.tm_mday = dmy; - nmea_set_waypoint_time(curr_waypt, &tm, 0); - ENQUEUE_HEAD(&pcmpt_head, &curr_waypt->Q); - } else { - queue *elem, *tmp; - route_head *trk_head; - - if (QUEUE_EMPTY(&pcmpt_head)) { - return; - } - - /* - * Since we oh-so-cleverly inserted points at the head, - * we can rip through the queue forward now to get our -` * handy-dandy reversing effect. - */ - trk_head = route_head_alloc(); - track_add_head(trk_head); - QUEUE_FOR_EACH(&pcmpt_head, elem, tmp) { - waypoint *wpt = (waypoint *) dequeue(elem); - nmea_add_wpt(wpt, trk_head); - } - } + int i, j1, j2, j3, j4, j5, j6; + int lat, lon; + char altflag, u1, u2; + float alt, f1, f2; + char coords[20] = {0}; + int dmy, hms; + + dmy = hms = 0; + + sscanf(ibuf,"$PCMPT,%d,%d,%d,%c,%f,%d,%[^,],%d,%f,%d,%f,%c,%d,%c,%d", + &j1, &j2, &j3, &altflag, &alt, &j4, (char*) &coords, + &j5, &f1, &j6, &f2, &u1, &dmy, &u2, &hms); + + if (altflag == 'D' && curr_waypt && alt > 0) { + curr_waypt->altitude = alt /*+ 500*/; + return; + } + + /* + * There are a couple of different second line records, but we + * don't care about them. + */ + if (j2 != 1) { + return; + } + + sscanf(coords, "%d%n", &lat, &i); + if (coords[i] == 'S') { + lat = -lat; + } + sscanf(coords + i + 1, "%d%n", &lon, &i); + if (coords[i] == 'W') { + lon= -lon; + } + + if (lat || lon) { + curr_waypt = waypt_new(); + curr_waypt->longitude = pcmpt_deg(lon); + curr_waypt->latitude = pcmpt_deg(lat); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + tm.tm_year = dmy % 10000 - 1900; + dmy = dmy / 10000; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; + nmea_set_waypoint_time(curr_waypt, &tm, 0); + ENQUEUE_HEAD(&pcmpt_head, &curr_waypt->Q); + } else { + queue* elem, *tmp; + route_head* trk_head; + + if (QUEUE_EMPTY(&pcmpt_head)) { + return; + } + + /* + * Since we oh-so-cleverly inserted points at the head, + * we can rip through the queue forward now to get our + ` * handy-dandy reversing effect. + */ + trk_head = route_head_alloc(); + track_add_head(trk_head); + QUEUE_FOR_EACH(&pcmpt_head, elem, tmp) { + waypoint* wpt = (waypoint*) dequeue(elem); + nmea_add_wpt(wpt, trk_head); + } + } } static void -nmea_fix_timestamps(route_head *track) +nmea_fix_timestamps(route_head* track) { - if ((trk_head == NULL) || (without_date == 0)) return; - - if (tm.tm_year == 0) - { - queue *elem, *temp; - waypoint *prev = NULL; - time_t delta_tm; - - if (optdate == NULL) - { - warning(MYNAME ": No date found within track (all points dropped)!\n"); - warning(MYNAME ": Please use option \"date\" to preset a valid date for thoose tracks.\n"); - track_del_head(track); - return; - } - delta_tm = mkgmtime(&opt_tm); - - QUEUE_FOR_EACH(&track->waypoint_list, elem, temp) - { - waypoint *wpt = (waypoint *)elem; - - wpt->creation_time += delta_tm; - if ((prev != NULL) && (prev->creation_time > wpt->creation_time)) /* go over midnight ? */ - { - delta_tm += SECONDS_PER_DAY; - wpt->creation_time += SECONDS_PER_DAY; - } - prev = wpt; - } - } - else - { - time_t prev; - queue *elem; - - tm.tm_hour = 23; /* last date found */ - tm.tm_min = 59; - tm.tm_sec = 59; - - prev = mkgmtime(&tm); - - /* go backward through the track and complete timestamps */ - - for (elem = QUEUE_LAST(&track->waypoint_list); elem != &track->waypoint_list; elem=elem->prev) - { - waypoint *wpt = (waypoint *)elem; - - if (wpt->wpt_flags.fmt_use != 0) - { - time_t dt; - - wpt->wpt_flags.fmt_use = 0; /* reset flag */ - - dt = (prev / SECONDS_PER_DAY) * SECONDS_PER_DAY; - wpt->creation_time += dt; - if (wpt->creation_time > prev) - wpt->creation_time+=SECONDS_PER_DAY; - } - prev = wpt->creation_time; - } - } + if ((trk_head == NULL) || (without_date == 0)) { + return; + } + + if (tm.tm_year == 0) { + queue* elem, *temp; + waypoint* prev = NULL; + time_t delta_tm; + + if (optdate == NULL) { + warning(MYNAME ": No date found within track (all points dropped)!\n"); + warning(MYNAME ": Please use option \"date\" to preset a valid date for thoose tracks.\n"); + track_del_head(track); + return; + } + delta_tm = mkgmtime(&opt_tm); + + QUEUE_FOR_EACH(&track->waypoint_list, elem, temp) { + waypoint* wpt = (waypoint*)elem; + + wpt->creation_time += delta_tm; + if ((prev != NULL) && (prev->creation_time > wpt->creation_time)) { /* go over midnight ? */ + delta_tm += SECONDS_PER_DAY; + wpt->creation_time += SECONDS_PER_DAY; + } + prev = wpt; + } + } else { + time_t prev; + queue* elem; + + tm.tm_hour = 23; /* last date found */ + tm.tm_min = 59; + tm.tm_sec = 59; + + prev = mkgmtime(&tm); + + /* go backward through the track and complete timestamps */ + + for (elem = QUEUE_LAST(&track->waypoint_list); elem != &track->waypoint_list; elem=elem->prev) { + waypoint* wpt = (waypoint*)elem; + + if (wpt->wpt_flags.fmt_use != 0) { + time_t dt; + + wpt->wpt_flags.fmt_use = 0; /* reset flag */ + + dt = (prev / SECONDS_PER_DAY) * SECONDS_PER_DAY; + wpt->creation_time += dt; + if (wpt->creation_time > prev) { + wpt->creation_time+=SECONDS_PER_DAY; + } + } + prev = wpt->creation_time; + } + } } void -nmea_parse_one_line(char *ibuf) +nmea_parse_one_line(char* ibuf) { - char *ck; - int ckval, ckcmp; - char *tbuf = lrtrim(ibuf); - - /* - * GISTEQ PhotoTracker (stupidly) puts a bogus field in front - * of the line. Look for it and toss it. - */ - if (0 == strncmp(tbuf, "---,", 4)) tbuf += 4; - - if (*tbuf != '$') return; - - ck = strrchr(tbuf, '*'); - if (ck != NULL) { - *ck = '\0'; - ckval = nmea_cksum(&tbuf[1]); - *ck = '*'; - ck++; - sscanf(ck, "%2X", &ckcmp); - if (ckval != ckcmp) { + char* ck; + int ckval, ckcmp; + char* tbuf = lrtrim(ibuf); + + /* + * GISTEQ PhotoTracker (stupidly) puts a bogus field in front + * of the line. Look for it and toss it. + */ + if (0 == strncmp(tbuf, "---,", 4)) { + tbuf += 4; + } + + if (*tbuf != '$') { + return; + } + + ck = strrchr(tbuf, '*'); + if (ck != NULL) { + *ck = '\0'; + ckval = nmea_cksum(&tbuf[1]); + *ck = '*'; + ck++; + sscanf(ck, "%2X", &ckcmp); + if (ckval != ckcmp) { #if 0 - printf("ckval %X, %X, %s\n", ckval, ckcmp, ck); - printf("NMEA %s\n", tbuf); + printf("ckval %X, %X, %s\n", ckval, ckcmp, ck); + printf("NMEA %s\n", tbuf); #endif - return; - } - - had_checksum = 1; - } - else if (had_checksum) { - /* we have had a checksum on all previous sentences, but not on this - one, which probably indicates this line is truncated */ - had_checksum = 0; - return; - } - - /* @@@ zmarties: The parse routines all assume all fields are present, but - the NMEA format allows any field to be missed out if there is no data - for that field. Rather than change all the parse routines, we first - substitute a default value of zero for any missing field. - */ - if (strstr(tbuf, ",,")) - { - tbuf = gstrsub(tbuf, ",,", ",0,"); - } - - if (0 == strncmp(tbuf, "$GPWPL,", 7)) { - gpwpl_parse(tbuf); - } else - if (opt_gpgga && (0 == strncmp(tbuf, "$GPGGA,", 7))) { - posn_type = gpgga; - gpgga_parse(tbuf); - } else - if (opt_gprmc && (0 == strncmp(tbuf, "$GPRMC,", 7))) { - if (posn_type != gpgga) { - posn_type = gprmc; - } - /* - * Always call gprmc_parse() because like GPZDA - * it contains the full date. - */ - gprmc_parse(tbuf); - } else - if (0 == strncmp(tbuf, "$GPGLL,", 7)) { - if ((posn_type != gpgga) && (posn_type != gprmc)) { - gpgll_parse(tbuf); - } - } else - if (0 == strncmp(tbuf, "$GPZDA,",7)) { - gpzda_parse(tbuf); - } else - if (0 == strncmp(tbuf, "$PCMPT,", 7)) { - pcmpt_parse(tbuf); - } else - if (opt_gpvtg && (0 == strncmp(tbuf, "$GPVTG,",7))) { - gpvtg_parse(tbuf); /* speed and course */ - } else - if (opt_gpgsa && (0 == strncmp(tbuf, "$GPGSA,",7))) { - gpgsa_parse(tbuf); /* GPS fix */ - } else - if (0 == strncmp(tbuf, "$ADPMB,5,0", 10)) { - amod_waypoint = 1; - } - - if (tbuf != ibuf) { - /* clear up the dynamic buffer we used because substition was required */ - xfree(tbuf); - } + return; + } + + had_checksum = 1; + } else if (had_checksum) { + /* we have had a checksum on all previous sentences, but not on this + one, which probably indicates this line is truncated */ + had_checksum = 0; + return; + } + + if (strstr(tbuf+1,"$")!=NULL) { + /* If line has more than one $, there is probably an error in it. */ + return; + } + + /* @@@ zmarties: The parse routines all assume all fields are present, but + the NMEA format allows any field to be missed out if there is no data + for that field. Rather than change all the parse routines, we first + substitute a default value of zero for any missing field. + */ + if (strstr(tbuf, ",,")) { + tbuf = gstrsub(tbuf, ",,", ",0,"); + } + + if (0 == strncmp(tbuf, "$GPWPL,", 7)) { + gpwpl_parse(tbuf); + } else if (opt_gpgga && (0 == strncmp(tbuf, "$GPGGA,", 7))) { + posn_type = gpgga; + gpgga_parse(tbuf); + } else if (opt_gprmc && (0 == strncmp(tbuf, "$GPRMC,", 7))) { + if (posn_type != gpgga) { + posn_type = gprmc; + } + /* + * Always call gprmc_parse() because like GPZDA + * it contains the full date. + */ + gprmc_parse(tbuf); + } else if (0 == strncmp(tbuf, "$GPGLL,", 7)) { + if ((posn_type != gpgga) && (posn_type != gprmc)) { + gpgll_parse(tbuf); + } + } else if (0 == strncmp(tbuf, "$GPZDA,",7)) { + gpzda_parse(tbuf); + } else if (0 == strncmp(tbuf, "$PCMPT,", 7)) { + pcmpt_parse(tbuf); + } else if (opt_gpvtg && (0 == strncmp(tbuf, "$GPVTG,",7))) { + gpvtg_parse(tbuf); /* speed and course */ + } else if (opt_gpgsa && (0 == strncmp(tbuf, "$GPGSA,",7))) { + gpgsa_parse(tbuf); /* GPS fix */ + } else if (0 == strncmp(tbuf, "$ADPMB,5,0", 10)) { + amod_waypoint = 1; + } + + if (tbuf != ibuf) { + /* clear up the dynamic buffer we used because substition was required */ + xfree(tbuf); + } } static void nmea_read(void) { - char *ibuf; - char *ck; - double lt = -1; - int line = -1; - - posn_type = gp_unknown; - trk_head = NULL; - without_date = 0; - memset(&tm, 0, sizeof(tm)); - opt_tm = tm; - - /* This was done in rd_init() */ - if (getposn) { - return; - } - - if (optdate) - { - memset(&opt_tm, 0, sizeof(opt_tm)); - - ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); - if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) - fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); - else if (opt_tm.tm_year < 70) - fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); - } - - curr_waypt = NULL; - - while ((ibuf = gbfgetstr(file_in))) { - char *sdatum, *cx; - - line++; - - if ((line == 0) & file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - if ((line == 0) && (case_ignore_strncmp(ibuf, "@SonyGPS/ver", 12) == 0)) { - /* special hack for Sony GPS-CS1 files: - they are fully (?) nmea compatible, but come with a header line like - "@Sonygps/ver1.0/wgs-84". */ - /* The Sony GPS-CS3KA extends that line even further - so we now look for the second field to be / - delimited. - @Sonygps/ver1.0/wgs-84/gps-cs3.0 - */ - - /* Check the GPS datum */ - cx = strchr(&ibuf[12], '/'); - if (cx != NULL) { - char *edatum; - sdatum = cx + 1; - edatum = strchr(sdatum, '/'); - if (edatum) { - *edatum = 0; - } - datum = GPS_Lookup_Datum_Index(sdatum); - if (datum < 0) - fatal(MYNAME "/SonyGPS: Unsupported datum \"%s\" in source data!\n", sdatum); - } - continue; - } - - nmea_parse_one_line(ibuf); - if (lt != last_read_time && curr_waypt && trk_head) { - if (curr_waypt != last_waypt) { - nmea_add_wpt(curr_waypt, trk_head); - last_waypt = curr_waypt; - } - lt = last_read_time; - } - } - - /* try to complete date-less trackpoints */ - nmea_fix_timestamps(trk_head); + char* ibuf; + char* ck; + double lt = -1; + int line = -1; + + posn_type = gp_unknown; + trk_head = NULL; + without_date = 0; + memset(&tm, 0, sizeof(tm)); + opt_tm = tm; + + /* This was done in rd_init() */ + if (getposn) { + return; + } + + if (optdate) { + memset(&opt_tm, 0, sizeof(opt_tm)); + + ck = (char*)strptime(optdate, "%Y%m%d", &opt_tm); + if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) { + fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); + } else if (opt_tm.tm_year < 70) { + fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); + } + } + + curr_waypt = NULL; + + while ((ibuf = gbfgetstr(file_in))) { + char* sdatum, *cx; + + line++; + + if ((line == 0) & file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + if ((line == 0) && (case_ignore_strncmp(ibuf, "@SonyGPS/ver", 12) == 0)) { + /* special hack for Sony GPS-CS1 files: + they are fully (?) nmea compatible, but come with a header line like + "@Sonygps/ver1.0/wgs-84". */ + /* The Sony GPS-CS3KA extends that line even further + so we now look for the second field to be / + delimited. + @Sonygps/ver1.0/wgs-84/gps-cs3.0 + */ + + /* Check the GPS datum */ + cx = strchr(&ibuf[12], '/'); + if (cx != NULL) { + char* edatum; + sdatum = cx + 1; + edatum = strchr(sdatum, '/'); + if (edatum) { + *edatum = 0; + } + datum = GPS_Lookup_Datum_Index(sdatum); + if (datum < 0) { + fatal(MYNAME "/SonyGPS: Unsupported datum \"%s\" in source data!\n", sdatum); + } + } + continue; + } + + nmea_parse_one_line(ibuf); + if (lt != last_read_time && curr_waypt && trk_head) { + if (curr_waypt != last_waypt) { + nmea_add_wpt(curr_waypt, trk_head); + last_waypt = curr_waypt; + } + lt = last_read_time; + } + } + + /* try to complete date-less trackpoints */ + nmea_fix_timestamps(trk_head); } void -nmea_rd_posn_init(const char *fname) +nmea_rd_posn_init(const char* fname) { - if ((gbser_handle = gbser_init(fname)) != NULL) { - read_mode = rm_serial; - gbser_set_speed(gbser_handle, 4800); - } else { - fatal(MYNAME ": Could not open '%s' for position tracking.\n", fname); - } - - gbser_flush(gbser_handle); - - if (opt_baud) { - if (!gbser_set_speed(gbser_handle, atoi(opt_baud))) { - fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud); - } - } - posn_fname = fname; + if ((gbser_handle = gbser_init(fname)) != NULL) { + read_mode = rm_serial; + gbser_set_speed(gbser_handle, 4800); + } else { + fatal(MYNAME ": Could not open '%s' for position tracking.\n", fname); + } + + gbser_flush(gbser_handle); + + if (opt_baud) { + if (!gbser_set_speed(gbser_handle, atoi(opt_baud))) { + fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud); + } + } + posn_fname = fname; } static void -safe_print(int cnt, const char *b) +safe_print(int cnt, const char* b) { - int i; - for (i = 0; i < cnt; i++) { - char c = isprint(b[i]) ? b[i] : '.'; - fputc(c, stderr); - } + int i; + for (i = 0; i < cnt; i++) { + char c = isprint(b[i]) ? b[i] : '.'; + fputc(c, stderr); + } } static void reset_sirf_to_nmea(int br); -static +static int hunt_sirf(void) { - /* Try to place the common BR's first to speed searching */ - static int br[] = {38400, 9600, 57600, 115200, 19200, 4800, -1}; - static int *brp = &br[0]; - char ibuf[1024]; - - for (brp = br; *brp > 0; brp++) { - int rv; - if (global_opts.debug_level > 1) { - fprintf(stderr, "Trying %d\n", *brp); - } - - /* - * Cycle our port's data speed and spray the "change to NMEA - * mode to the device. - */ - gbser_set_speed(gbser_handle, *brp); - reset_sirf_to_nmea(*brp); - - rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), - 1000, 0x0a, 0x0d); - /* - * If we didn't get a read error but did get a string that - * started with a dollar sign, we're probably in NMEA mode - * now. - */ - if ((rv > -1) && (strlen(ibuf) > 0) && ibuf[0] == '$') { - return 1; - } - - /* - * If nothing was received, it's not a sirf part. Fast exit. - */ - if (rv < 0) { - return 0; - } - } - return 0; + /* Try to place the common BR's first to speed searching */ + static int br[] = {38400, 9600, 57600, 115200, 19200, 4800, -1}; + static int* brp = &br[0]; + char ibuf[1024]; + + for (brp = br; *brp > 0; brp++) { + int rv; + if (global_opts.debug_level > 1) { + fprintf(stderr, "Trying %d\n", *brp); + } + + /* + * Cycle our port's data speed and spray the "change to NMEA + * mode to the device. + */ + gbser_set_speed(gbser_handle, *brp); + reset_sirf_to_nmea(*brp); + + rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), + 1000, 0x0a, 0x0d); + /* + * If we didn't get a read error but did get a string that + * started with a dollar sign, we're probably in NMEA mode + * now. + */ + if ((rv > -1) && (strlen(ibuf) > 0) && ibuf[0] == '$') { + return 1; + } + + /* + * If nothing was received, it's not a sirf part. Fast exit. + */ + if (rv < 0) { + return 0; + } + } + return 0; } -static waypoint * -nmea_rd_posn(posn_status *posn_status) +static waypoint* +nmea_rd_posn(posn_status* posn_status) { - char ibuf[1024]; - static double lt = -1; - int i; - int am_sirf = 0; - - /* - * Read a handful of sentences, collecting the best info we - * can. If the timestamp changes (indicating the sequence is - * about to restart and thus the one we're collecting isn't going - * to get any better than we now have) hand that back to the caller. - */ - - for (i = 0; i < 10; i++) { - int rv; - ibuf[0] = 0; - rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), 2000, 0x0a, 0x0d); - if (global_opts.debug_level > 1) { - safe_print(strlen(ibuf), ibuf); - } - if (rv < 0) { - if (am_sirf == 0) { - if (global_opts.debug_level > 1) { - warning(MYNAME ": Attempting sirf mode.\n"); - } - /* This is tacky, we have to change speed - * to 9600bps to tell it to speak NMEA at - * 4800. - */ - am_sirf = hunt_sirf(); - if (am_sirf) { - i = 0; - continue; - } - } - fatal(MYNAME ": No data received on %s.\n", posn_fname); - } - nmea_parse_one_line(ibuf); - if (lt != last_read_time) { - if (last_read_time) { - waypoint *w = curr_waypt; - - lt = last_read_time; - curr_waypt = NULL; - - return w; - } - } - } - return NULL; + char ibuf[1024]; + static double lt = -1; + int i; + int am_sirf = 0; + + /* + * Read a handful of sentences, collecting the best info we + * can. If the timestamp changes (indicating the sequence is + * about to restart and thus the one we're collecting isn't going + * to get any better than we now have) hand that back to the caller. + */ + + for (i = 0; i < 10; i++) { + int rv; + ibuf[0] = 0; + rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), 2000, 0x0a, 0x0d); + if (global_opts.debug_level > 1) { + safe_print(strlen(ibuf), ibuf); + } + if (rv < 0) { + if (am_sirf == 0) { + if (global_opts.debug_level > 1) { + warning(MYNAME ": Attempting sirf mode.\n"); + } + /* This is tacky, we have to change speed + * to 9600bps to tell it to speak NMEA at + * 4800. + */ + am_sirf = hunt_sirf(); + if (am_sirf) { + i = 0; + continue; + } + } + fatal(MYNAME ": No data received on %s.\n", posn_fname); + } + nmea_parse_one_line(ibuf); + if (lt != last_read_time) { + if (last_read_time) { + waypoint* w = curr_waypt; + + lt = last_read_time; + curr_waypt = NULL; + + return w; + } + } + } + return NULL; } static void -nmea_wayptpr(const waypoint *wpt) +nmea_wayptpr(const waypoint* wpt) { - char obuf[200]; - double lat,lon; - char *s; - int cksum; - - lat = degrees2ddmm(wpt->latitude); - lon = degrees2ddmm(wpt->longitude); - if (global_opts.synthesize_shortnames) - s = mkshort_from_wpt(mkshort_handle, wpt); - else { - s = mkshort(mkshort_handle, wpt->shortname); - } - - snprintf(obuf, sizeof(obuf), "GPWPL,%08.3f,%c,%09.3f,%c,%s", - fabs(lat), lat < 0 ? 'S' : 'N', - fabs(lon), lon < 0 ? 'W' : 'E', s - - ); - cksum = nmea_cksum(obuf); - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - if (sleepus >= 0) { - gbfflush(file_out); - gb_sleep(sleepus); - } - - xfree(s); - + char obuf[200]; + double lat,lon; + char* s; + int cksum; + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + if (global_opts.synthesize_shortnames) { + s = mkshort_from_wpt(mkshort_handle, wpt); + } else { + s = mkshort(mkshort_handle, wpt->shortname); + } + + snprintf(obuf, sizeof(obuf), "GPWPL,%08.3f,%c,%09.3f,%c,%s", + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', s + + ); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + if (sleepus >= 0) { + gbfflush(file_out); + gb_sleep(sleepus); + } + + xfree(s); + } -void -nmea_track_init(const route_head *rte) +void +nmea_track_init(const route_head* rte) { - last_time = -1; + last_time = -1; } void -nmea_trackpt_pr(const waypoint *wpt) +nmea_trackpt_pr(const waypoint* wpt) { - char obuf[200]; - char fix='0'; - double lat,lon; - int cksum; - struct tm *tm; - time_t hms; - time_t ymd; - - if ( opt_sleep ) { - gbfflush( file_out ); - if ( last_time > 0 ) { - if ( sleepus >= 0 ) { - gb_sleep( sleepus ); - } - else { - long wait_time = wpt->creation_time - last_time; - if ( wait_time > 0 ) { - gb_sleep( wait_time * 1000000 ); - } - } - } - last_time = wpt->creation_time; - } - - lat = degrees2ddmm(wpt->latitude); - lon = degrees2ddmm(wpt->longitude); - - tm = gmtime(&wpt->creation_time); - if ( tm ) { - hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; - ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; - } else { - hms = 0; - ymd = 0; - } - - switch (wpt->fix) - { - case fix_dgps: - fix='2'; - /* or */ - case fix_3d: - case fix_2d: - fix='1'; - break; - case fix_pps: - fix='3'; - break; - default: - fix='0'; - } - - if (opt_gprmc) { - snprintf(obuf, sizeof(obuf), "GPRMC,%010.3f,%c,%08.3f,%c,%09.3f,%c,%.2f,%.2f,%06d,,", - (double) hms + (wpt->microseconds / 1000000.0), - fix=='0' ? 'V' : 'A', - fabs(lat), lat < 0 ? 'S' : 'N', - fabs(lon), lon < 0 ? 'W' : 'E', - WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), - WAYPT_HAS(wpt, course) ? (wpt->course):(0), - (int) ymd); - cksum = nmea_cksum(obuf); - - /* GISTeq doesn't care about the checksum, but wants this prefixed, so - * we can write it with abandon. - */ - if (opt_gisteq) { - gbfprintf(file_out, "---,"); - } - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - } - if (opt_gpgga) { - snprintf(obuf, sizeof(obuf), "GPGGA,%010.3f,%08.3f,%c,%09.3f,%c,%c,%02d,%.1f,%.3f,M,0.0,M,,", - (double) hms + (wpt->microseconds / 1000000.0), - fabs(lat), lat < 0 ? 'S' : 'N', - fabs(lon), lon < 0 ? 'W' : 'E', - fix, - (wpt->sat>0)?(wpt->sat):(0), - (wpt->hdop>0)?(wpt->hdop):(0.0), - wpt->altitude == unknown_alt ? 0 : wpt->altitude); - cksum = nmea_cksum(obuf); - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - } - if ((opt_gpvtg) && (WAYPT_HAS(wpt, course) || WAYPT_HAS(wpt, speed))) { - snprintf(obuf,sizeof(obuf),"GPVTG,%.3f,T,0,M,%.3f,N,%.3f,K", - WAYPT_HAS(wpt, course) ? (wpt->course):(0), - WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), - WAYPT_HAS(wpt, speed) ? MPS_TO_KPH(wpt->speed):(0) ); - - cksum = nmea_cksum(obuf); - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - } - - if ((opt_gpgsa) && (wpt->fix!=fix_unknown)) { - - switch (wpt->fix) - { - case fix_dgps: - /* or */ - case fix_3d: - fix='3'; - break; - case fix_2d: - fix='2'; - break; - default: - fix=0; - } - snprintf(obuf,sizeof(obuf),"GPGSA,A,%c,,,,,,,,,,,,,%.1f,%.1f,%.1f", - fix, - (wpt->pdop>0)?(wpt->pdop):(0), - (wpt->hdop>0)?(wpt->hdop):(0), - (wpt->vdop>0)?(wpt->vdop):(0) ); - cksum = nmea_cksum(obuf); - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - } - gbfflush(file_out); + char obuf[200]; + char fix='0'; + double lat,lon; + int cksum; + struct tm* tm; + time_t hms; + time_t ymd; + + if (opt_sleep) { + gbfflush(file_out); + if (last_time > 0) { + if (sleepus >= 0) { + gb_sleep(sleepus); + } else { + long wait_time = wpt->creation_time - last_time; + if (wait_time > 0) { + gb_sleep(wait_time * 1000000); + } + } + } + last_time = wpt->creation_time; + } + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + + tm = gmtime(&wpt->creation_time); + if (tm) { + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; + } else { + hms = 0; + ymd = 0; + } + + switch (wpt->fix) { + case fix_dgps: + fix='2'; + /* or */ + case fix_3d: + case fix_2d: + fix='1'; + break; + case fix_pps: + fix='3'; + break; + default: + fix='0'; + } + + if (opt_gprmc) { + snprintf(obuf, sizeof(obuf), "GPRMC,%010.3f,%c,%08.3f,%c,%09.3f,%c,%.2f,%.2f,%06d,,", + (double) hms + (wpt->microseconds / 1000000.0), + fix=='0' ? 'V' : 'A', + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), + WAYPT_HAS(wpt, course) ? (wpt->course):(0), + (int) ymd); + cksum = nmea_cksum(obuf); + + /* GISTeq doesn't care about the checksum, but wants this prefixed, so + * we can write it with abandon. + */ + if (opt_gisteq) { + gbfprintf(file_out, "---,"); + } + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + if (opt_gpgga) { + snprintf(obuf, sizeof(obuf), "GPGGA,%010.3f,%08.3f,%c,%09.3f,%c,%c,%02d,%.1f,%.3f,M,0.0,M,,", + (double) hms + (wpt->microseconds / 1000000.0), + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + fix, + (wpt->sat>0)?(wpt->sat):(0), + (wpt->hdop>0)?(wpt->hdop):(0.0), + wpt->altitude == unknown_alt ? 0 : wpt->altitude); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + if ((opt_gpvtg) && (WAYPT_HAS(wpt, course) || WAYPT_HAS(wpt, speed))) { + snprintf(obuf,sizeof(obuf),"GPVTG,%.3f,T,0,M,%.3f,N,%.3f,K", + WAYPT_HAS(wpt, course) ? (wpt->course):(0), + WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), + WAYPT_HAS(wpt, speed) ? MPS_TO_KPH(wpt->speed):(0)); + + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + + if ((opt_gpgsa) && (wpt->fix!=fix_unknown)) { + + switch (wpt->fix) { + case fix_dgps: + /* or */ + case fix_3d: + fix='3'; + break; + case fix_2d: + fix='2'; + break; + default: + fix=0; + } + snprintf(obuf,sizeof(obuf),"GPGSA,A,%c,,,,,,,,,,,,,%.1f,%.1f,%.1f", + fix, + (wpt->pdop>0)?(wpt->pdop):(0), + (wpt->hdop>0)?(wpt->hdop):(0), + (wpt->vdop>0)?(wpt->vdop):(0)); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + gbfflush(file_out); } static void nmea_write(void) { - waypt_disp_all(nmea_wayptpr); - track_disp_all(nmea_track_init, NULL, nmea_trackpt_pr); + waypt_disp_all(nmea_wayptpr); + track_disp_all(nmea_track_init, NULL, nmea_trackpt_pr); } static void -nmea_wr_posn_init(const char *fname) +nmea_wr_posn_init(const char* fname) { - nmea_wr_init(fname); + nmea_wr_init(fname); } static void -nmea_wr_posn(waypoint *wpt) +nmea_wr_posn(waypoint* wpt) { - nmea_trackpt_pr(wpt); + nmea_trackpt_pr(wpt); } static void @@ -1359,21 +1387,25 @@ nmea_wr_posn_deinit(void) ff_vecs_t nmea_vecs = { - ff_type_file, - { (ff_cap)(ff_cap_read | ff_cap_write), - (ff_cap)(ff_cap_read | ff_cap_write), - ff_cap_none}, - nmea_rd_init, - nmea_wr_init, - nmea_rd_deinit, - nmea_wr_deinit, - nmea_read, - nmea_write, - NULL, - nmea_args, - CET_CHARSET_ASCII, 0, /* CET-REVIEW */ - { nmea_rd_posn_init, nmea_rd_posn, nmea_rd_deinit, - nmea_wr_posn_init, nmea_wr_posn, nmea_wr_posn_deinit } + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write), + (ff_cap)(ff_cap_read | ff_cap_write), + ff_cap_none + }, + nmea_rd_init, + nmea_wr_init, + nmea_rd_deinit, + nmea_wr_deinit, + nmea_read, + nmea_write, + NULL, + nmea_args, + CET_CHARSET_ASCII, 0, /* CET-REVIEW */ + { + nmea_rd_posn_init, nmea_rd_posn, nmea_rd_deinit, + nmea_wr_posn_init, nmea_wr_posn, nmea_wr_posn_deinit + } }; /* @@ -1384,45 +1416,46 @@ ff_vecs_t nmea_vecs = { */ static void -sirf_write(unsigned char *buf) +sirf_write(unsigned char* buf) { - int i, chksum = 0; - int len = buf[2] << 8 | buf[3]; + int i, chksum = 0; + int len = buf[2] << 8 | buf[3]; - for (i = 0; i < len; i++) { - chksum += buf[4 + i]; - } - chksum &= 0x7fff; + for (i = 0; i < len; i++) { + chksum += buf[4 + i]; + } + chksum &= 0x7fff; - buf[len + 4] = chksum >> 8; - buf[len + 5] = chksum & 0xff; + buf[len + 4] = chksum >> 8; + buf[len + 5] = chksum & 0xff; - gbser_write(gbser_handle, buf, len + 8); /* 4 at front, 4 at back */ + gbser_write(gbser_handle, buf, len + 8); /* 4 at front, 4 at back */ } static void reset_sirf_to_nmea(int br) { - static unsigned char pkt[] = {0xa0, 0xa2, 0x00, 0x18, - 0x81, 0x02, - 0x01, 0x01, /* GGA */ - 0x00, 0x00, /* suppress GLL */ - 0x01, 0x00, /* suppress GSA */ - 0x05, 0x00, /* suppress GSV */ - 0x01, 0x01, /* use RMC for date*/ - 0x00, 0x00, /* suppress VTG */ - 0x00, 0x01, /* output rate */ - 0x00, 0x01, /* unused recommended values */ - 0x00, 0x01, - 0x00, 0x01, /* ZDA */ - 0x12, 0xc0, /* 4800 bps */ - 0x00, 0x00, /* checksum */ - 0xb0, 0xb3}; /* packet end */ - /* repopulate bit rate */ - pkt[26] = br >> 8; - pkt[27] = br & 0xff; - - sirf_write(pkt); - gb_sleep(250 * 1000); - gbser_flush(gbser_handle); + static unsigned char pkt[] = {0xa0, 0xa2, 0x00, 0x18, + 0x81, 0x02, + 0x01, 0x01, /* GGA */ + 0x00, 0x00, /* suppress GLL */ + 0x01, 0x00, /* suppress GSA */ + 0x05, 0x00, /* suppress GSV */ + 0x01, 0x01, /* use RMC for date*/ + 0x00, 0x00, /* suppress VTG */ + 0x00, 0x01, /* output rate */ + 0x00, 0x01, /* unused recommended values */ + 0x00, 0x01, + 0x00, 0x01, /* ZDA */ + 0x12, 0xc0, /* 4800 bps */ + 0x00, 0x00, /* checksum */ + 0xb0, 0xb3 + }; /* packet end */ + /* repopulate bit rate */ + pkt[26] = br >> 8; + pkt[27] = br & 0xff; + + sirf_write(pkt); + gb_sleep(250 * 1000); + gbser_flush(gbser_handle); } diff --git a/gpsbabel/nmn4.c b/gpsbabel/nmn4.c index bb02c00be..1aac5346d 100644 --- a/gpsbabel/nmn4.c +++ b/gpsbabel/nmn4.c @@ -1,22 +1,22 @@ - /* +/* - Support for Navigon Mobile Navigator .rte files. + Support for Navigon Mobile Navigator .rte files. - Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ /* @@ -33,292 +33,297 @@ #include #include -static gbfile *fin, *fout; +static gbfile* fin, *fout; static int curr_rte_num, target_rte_num; #define MYNAME "navigon" -static char *index_opt; +static char* index_opt; static arglist_t nmn4_args[] = { - {"index", &index_opt, "Index of route to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR + {"index", &index_opt, "Index of route to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR }; /* helpers */ -static char * -nmn4_concat(char *arg0, ...) +static char* +nmn4_concat(char* arg0, ...) { - va_list args; - char *src, *res; - - res = NULL; - va_start(args, arg0); - src = (char *)arg0; - - while (src != NULL) - { - char *c = lrtrim(src); - - if (*c != '\0') - { - if (res == NULL) - res = xstrdup(c); - else - { - res = xstrappend(res, " "); - res = xstrappend(res, c); - } - } - xfree(src); - src = va_arg(args, char *); - } - va_end(args); - - return res; + va_list args; + char* src, *res; + + res = NULL; + va_start(args, arg0); + src = (char*)arg0; + + while (src != NULL) { + char* c = lrtrim(src); + + if (*c != '\0') { + if (res == NULL) { + res = xstrdup(c); + } else { + res = xstrappend(res, " "); + res = xstrappend(res, c); + } + } + xfree(src); + src = va_arg(args, char*); + } + va_end(args); + + return res; } static void -nmn4_check_line(char *line) +nmn4_check_line(char* line) { - char *c = line; - int i = 0; - while ((c = strchr(c, '|'))) - { - c++; - i++; - } - is_fatal((i != 15), - MYNAME ": Invalid or unknown structure!"); + char* c = line; + int i = 0; + while ((c = strchr(c, '|'))) { + c++; + i++; + } + is_fatal((i != 15), + MYNAME ": Invalid or unknown structure!"); } static void nmn4_read_data(void) { - char *buff; - char *str, *c; - int column; - int line = 0; - - char *zip1, *zip2, *city, *street, *number; - route_head *route; - waypoint *wpt; - - route = route_head_alloc(); - route_add_head(route); - - while ((buff = gbfgetstr(fin))) - { - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - str = buff = lrtrim(buff); - if (*buff == '\0') continue; - - nmn4_check_line(buff); - - /* for a quiet compiler */ - zip1 = zip2 = city = street = number = NULL; - - wpt = waypt_new(); - - column = -1; - c = csv_lineparse(str, "|", "", column++); - while (c != NULL) - { - switch(column) - { - case 0: /* "-" */ /* unknown fields for the moment */ - case 1: /* "-" */ - case 2: /* "-" */ - case 3: /* "-" */ - case 9: /* "-" */ - case 10: /* "-" */ - case 13: /* "-" */ - case 14: /* "-" */ - case 15: /* "" */ - break; - - case 4: /* ZIP Code */ - if (*c != '-') - zip1 = xstrdup(c); - else - zip1 = xstrdup(""); - break; - - case 5: /* City */ - if (*c != '-') - city = xstrdup(c); - else - city = xstrdup(""); - break; - - case 6: /* ZIP Code -2- */ - if (*c != '-') - zip2 = xstrdup(c); - else - zip2 = xstrdup(""); - break; - - case 7: /* Street */ - if (*c != '-') - street = xstrdup(c); - else - street = xstrdup(""); - break; - - case 8: /* Number */ - if (*c != '-') - number = xstrdup(c); - else - number = xstrdup(""); - - /* - This is our final index - All stuff for generating names or comments - is hold locally. - - We don't have fields for street, city or zip-code. - Instead we construct a description from that. - */ - - if (strcmp(zip1, zip2) == 0) *zip2 = '\0'; - if (*city != '\0') - { - /* - if any field following city has a value, add a comma to city - */ - if ((*street != '\0') || (*number != '\0') || (*zip2 != '\0')) - city = xstrappend(city, ","); - } - - /* concats all fields to one string and release */ - wpt->description = nmn4_concat(zip1, city, street, number, zip2, NULL); - break; - - case 11: /* longitude */ - sscanf(c, "%lf", &wpt->longitude); - break; - - case 12: /* latitude */ - sscanf(c, "%lf", &wpt->latitude); - break; - - } - c = csv_lineparse(NULL, "|", "", column++); - } - route_add_wpt(route, wpt); - } + char* buff; + char* str, *c; + int column; + int line = 0; + + char* zip1, *zip2, *city, *street, *number; + route_head* route; + waypoint* wpt; + + route = route_head_alloc(); + route_add_head(route); + + while ((buff = gbfgetstr(fin))) { + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + str = buff = lrtrim(buff); + if (*buff == '\0') { + continue; + } + + nmn4_check_line(buff); + + /* for a quiet compiler */ + zip1 = zip2 = city = street = number = NULL; + + wpt = waypt_new(); + + column = -1; + c = csv_lineparse(str, "|", "", column++); + while (c != NULL) { + switch (column) { + case 0: /* "-" */ /* unknown fields for the moment */ + case 1: /* "-" */ + case 2: /* "-" */ + case 3: /* "-" */ + case 9: /* "-" */ + case 10: /* "-" */ + case 13: /* "-" */ + case 14: /* "-" */ + case 15: /* "" */ + break; + + case 4: /* ZIP Code */ + if (*c != '-') { + zip1 = xstrdup(c); + } else { + zip1 = xstrdup(""); + } + break; + + case 5: /* City */ + if (*c != '-') { + city = xstrdup(c); + } else { + city = xstrdup(""); + } + break; + + case 6: /* ZIP Code -2- */ + if (*c != '-') { + zip2 = xstrdup(c); + } else { + zip2 = xstrdup(""); + } + break; + + case 7: /* Street */ + if (*c != '-') { + street = xstrdup(c); + } else { + street = xstrdup(""); + } + break; + + case 8: /* Number */ + if (*c != '-') { + number = xstrdup(c); + } else { + number = xstrdup(""); + } + + /* + This is our final index + All stuff for generating names or comments + is hold locally. + + We don't have fields for street, city or zip-code. + Instead we construct a description from that. + */ + + if (strcmp(zip1, zip2) == 0) { + *zip2 = '\0'; + } + if (*city != '\0') { + /* + if any field following city has a value, add a comma to city + */ + if ((*street != '\0') || (*number != '\0') || (*zip2 != '\0')) { + city = xstrappend(city, ","); + } + } + + /* concats all fields to one string and release */ + wpt->description = nmn4_concat(zip1, city, street, number, zip2, NULL); + break; + + case 11: /* longitude */ + sscanf(c, "%lf", &wpt->longitude); + break; + + case 12: /* latitude */ + sscanf(c, "%lf", &wpt->latitude); + break; + + } + c = csv_lineparse(NULL, "|", "", column++); + } + route_add_wpt(route, wpt); + } } -static void -nmn4_route_hdr(const route_head *route) +static void +nmn4_route_hdr(const route_head* route) { - curr_rte_num++; + curr_rte_num++; } -static void -nmn4_route_tlr(const route_head *rte) +static void +nmn4_route_tlr(const route_head* rte) { } static void -nmn4_write_waypt(const waypoint *wpt) +nmn4_write_waypt(const waypoint* wpt) { - char city[128], street[128], zipc[32], number[32]; - - if (curr_rte_num != target_rte_num) return; - - strncpy(city, "-", sizeof(city)); - strncpy(street, "-", sizeof(street)); - strncpy(zipc, "-", sizeof(zipc)); - strncpy(number, "-", sizeof(number)); - - /* - Population of specific data used by Navigon may come in the - future or it may be impossible. We currently output only the - coordinates in the output, but this is sufficient for Navigon. - - The coordinates are the only item we are about guaranteed to have - when converting to any from any format, so we leave the other - fields unpopulated. So i have to pay Navigon a compliment for - implementing a simple data exchange. - */ - - gbfprintf(fout, "-|-|-|-|%s|%s|%s|%s|%s|-|-|%.5f|%.5f|-|-|\r\n", - zipc, city, zipc, street, number, - wpt->longitude, wpt->latitude); + char city[128], street[128], zipc[32], number[32]; + + if (curr_rte_num != target_rte_num) { + return; + } + + strncpy(city, "-", sizeof(city)); + strncpy(street, "-", sizeof(street)); + strncpy(zipc, "-", sizeof(zipc)); + strncpy(number, "-", sizeof(number)); + + /* + Population of specific data used by Navigon may come in the + future or it may be impossible. We currently output only the + coordinates in the output, but this is sufficient for Navigon. + + The coordinates are the only item we are about guaranteed to have + when converting to any from any format, so we leave the other + fields unpopulated. So i have to pay Navigon a compliment for + implementing a simple data exchange. + */ + + gbfprintf(fout, "-|-|-|-|%s|%s|%s|%s|%s|-|-|%.5f|%.5f|-|-|\r\n", + zipc, city, zipc, street, number, + wpt->longitude, wpt->latitude); } static void nmn4_write_data(void) { - - target_rte_num = 1; - - if (index_opt != NULL) - { - target_rte_num = atoi(index_opt); - is_fatal(((target_rte_num > (int) route_count()) || (target_rte_num < 1)), - MYNAME ": invalid route number %d (1..%d))!\n", target_rte_num, route_count()); - } - - curr_rte_num = 0; - route_disp_all(nmn4_route_hdr, nmn4_route_tlr, nmn4_write_waypt); + + target_rte_num = 1; + + if (index_opt != NULL) { + target_rte_num = atoi(index_opt); + is_fatal(((target_rte_num > (int) route_count()) || (target_rte_num < 1)), + MYNAME ": invalid route number %d (1..%d))!\n", target_rte_num, route_count()); + } + + curr_rte_num = 0; + route_disp_all(nmn4_route_hdr, nmn4_route_tlr, nmn4_write_waypt); } /* %%% global callbacks %%% */ static void -nmn4_rd_init(const char *fname) +nmn4_rd_init(const char* fname) { - fin = gbfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } static void nmn4_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void nmn4_read(void) { - nmn4_read_data(); + nmn4_read_data(); } static void -nmn4_wr_init(const char *fname) +nmn4_wr_init(const char* fname) { - fout = gbfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); } static void nmn4_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void nmn4_write(void) { - nmn4_write_data(); + nmn4_write_data(); } /* --------------------------------------------------------------------------- */ ff_vecs_t nmn4_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, - nmn4_rd_init, - nmn4_wr_init, - nmn4_rd_deinit, - nmn4_wr_deinit, - nmn4_read, - nmn4_write, - NULL, - nmn4_args, - CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write)}, + nmn4_rd_init, + nmn4_wr_init, + nmn4_rd_deinit, + nmn4_wr_deinit, + nmn4_read, + nmn4_write, + NULL, + nmn4_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ }; diff --git a/gpsbabel/nukedata.c b/gpsbabel/nukedata.c index 6dc8fccbb..7dffca1c3 100644 --- a/gpsbabel/nukedata.c +++ b/gpsbabel/nukedata.c @@ -1,7 +1,7 @@ /* nukedata: remove all (waypoint|tracks|routes) from the stream. - + Copyright (C) 2005 Robert Lipe robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -19,46 +19,52 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include "filterdefs.h" #if FILTERS_ENABLED #define MYNAME "nukedata" -static char *nukewpts, *nuketrks, *nukertes; +static char* nukewpts, *nuketrks, *nukertes; static arglist_t nuke_args[] = { - {"waypoints", &nukewpts, "Remove all waypoints from data stream", - "0", ARGTYPE_BOOL, ARG_NOMINMAX} , - {"tracks", &nuketrks, "Remove all tracks from data stream", - "0", ARGTYPE_BOOL, ARG_NOMINMAX} , - {"routes", &nukertes, "Remove all routes from data stream", - "0", ARGTYPE_BOOL, ARG_NOMINMAX} , - ARG_TERMINATOR + { + "waypoints", &nukewpts, "Remove all waypoints from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + } , + { + "tracks", &nuketrks, "Remove all tracks from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + } , + { + "routes", &nukertes, "Remove all routes from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + } , + ARG_TERMINATOR }; -static void +static void nuke_process(void) { - if (*nukewpts != '0') { - waypt_flush_all(); - } - if (*nuketrks != '0') { - route_flush_all_tracks(); - } - if (*nukertes != '0') { - route_flush_all_routes(); - } + if (*nukewpts != '0') { + waypt_flush_all(); + } + if (*nuketrks != '0') { + route_flush_all_tracks(); + } + if (*nukertes != '0') { + route_flush_all_routes(); + } } filter_vecs_t nuke_vecs = { - NULL, - nuke_process, - NULL, - NULL, - nuke_args + NULL, + nuke_process, + NULL, + NULL, + nuke_args }; #endif diff --git a/gpsbabel/osm.c b/gpsbabel/osm.c index f96871998..0ed51f384 100644 --- a/gpsbabel/osm.c +++ b/gpsbabel/osm.c @@ -1,4 +1,4 @@ -/* +/* Support for "OpenStreetMap" data files (.xml) @@ -24,77 +24,76 @@ #include "avltree.h" #include "xmlgeneric.h" -static char *opt_tag, *opt_tagnd, *created_by; +static char* opt_tag, *opt_tagnd, *created_by; -static arglist_t osm_args[] = -{ - { "tag", &opt_tag, "Write additional way tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "tagnd", &opt_tagnd, "Write additional node tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "created_by", &created_by, "Use this value as custom created_by value","GPSBabel", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR +static arglist_t osm_args[] = { + { "tag", &opt_tag, "Write additional way tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "tagnd", &opt_tagnd, "Write additional node tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "created_by", &created_by, "Use this value as custom created_by value","GPSBabel", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define MYNAME "osm" -static avltree_t *waypoints; /* AVL tree */ +static avltree_t* waypoints; /* AVL tree */ -static avltree_t *keys = NULL; -static avltree_t *values = NULL; -static avltree_t *icons = NULL; +static avltree_t* keys = NULL; +static avltree_t* values = NULL; +static avltree_t* icons = NULL; -static gbfile *fout; +static gbfile* fout; static int node_id; static int skip_rte; #if HAVE_LIBEXPAT -static route_head *rte; -static waypoint *wpt; +static route_head* rte; +static waypoint* wpt; static int wpt_loaded, rte_loaded; static xg_callback osm_node, osm_node_tag, osm_node_end; static xg_callback osm_way, osm_way_nd, osm_way_tag, osm_way_end; -static +static xg_tag_mapping osm_map[] = { - { osm_node, cb_start, "/osm/node" }, - { osm_node_tag, cb_start, "/osm/node/tag" }, - { osm_node_end, cb_end, "/osm/node" }, - { osm_way, cb_start, "/osm/way" }, - { osm_way_nd, cb_start, "/osm/way/nd" }, - { osm_way_tag, cb_start, "/osm/way/tag" }, - { osm_way_end, cb_end, "/osm/way" }, - { NULL, 0, NULL } + { osm_node, cb_start, "/osm/node" }, + { osm_node_tag, cb_start, "/osm/node/tag" }, + { osm_node_end, cb_end, "/osm/node" }, + { osm_way, cb_start, "/osm/way" }, + { osm_way_nd, cb_start, "/osm/way/nd" }, + { osm_way_tag, cb_start, "/osm/way/tag" }, + { osm_way_end, cb_end, "/osm/way" }, + { NULL, (xg_cb_type)0, NULL } }; #endif // HAVE_LIBEXPAT -static const char *osm_features[] = { - "- dummy -", /* 0 */ - "aeroway", /* 1 */ - "amenity", /* 2 */ - "building", /* 3 */ - "cycleway", /* 4 */ - "railway", /* 5 */ - "highway", /* 6 */ - "historic", /* 7 */ - "landuse", /* 8 */ - "leisure", /* 9 */ - "man_made", /* 10 */ - "military", /* 11 */ - "natural", /* 12 */ - "place", /* 13 */ - "power", /* 14 */ - "shop", /* 15 */ - "sport", /* 16 */ - "tourism", /* 17 */ - "waterway", /* 18 */ - "aerialway", /* 19 */ - NULL +static const char* osm_features[] = { + "- dummy -", /* 0 */ + "aeroway", /* 1 */ + "amenity", /* 2 */ + "building", /* 3 */ + "cycleway", /* 4 */ + "railway", /* 5 */ + "highway", /* 6 */ + "historic", /* 7 */ + "landuse", /* 8 */ + "leisure", /* 9 */ + "man_made", /* 10 */ + "military", /* 11 */ + "natural", /* 12 */ + "place", /* 13 */ + "power", /* 14 */ + "shop", /* 15 */ + "sport", /* 16 */ + "tourism", /* 17 */ + "waterway", /* 18 */ + "aerialway", /* 19 */ + NULL }; typedef struct osm_icon_mapping_s { - const int key; - const char *value; - const char *icon; + const int key; + const char* value; + const char* icon; } osm_icon_mapping_t; @@ -102,9 +101,9 @@ typedef struct osm_icon_mapping_s { static osm_icon_mapping_t osm_icon_mappings[] = { - /* cycleway ...*/ + /* cycleway ...*/ - /* highway ...*/ + /* highway ...*/ // { 6, "mini_roundabout", "?" }, // { 6, "stop", "?" }, @@ -124,9 +123,9 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 6, "turning_circle", "?" }, // { 6, "User Defined", "?" }, - /* waterway ... */ + /* waterway ... */ - { 18, "dock", "Dock" }, + { 18, "dock", "Dock" }, // { 18, "lock_gate", "?" }, // { 18, "turning_point", "?" }, // { 18, "aqueduct", "?" }, @@ -137,36 +136,36 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 18, "weir", "?" }, // { 18, "User Defined", "?" }, - /* railway ... */ + /* railway ... */ // { 5, "station", "?" }, // { 5, "halt", "?" }, // { 5, "tram_stop", "?" }, // { 5, "viaduct", "?" }, - { 5, "crossing", "Crossing" }, + { 5, "crossing", "Crossing" }, // { 5, "level_crossing", "?" }, // { 5, "subway_entrance", "?" }, // { 5, "turntable", "?" }, // { 5, "User Defined", "?" }, - /* aeroway ... */ + /* aeroway ... */ - { 1, "aerodrome", "Airport" }, - { 1, "terminal", "Airport" }, - { 1, "helipad", "Heliport" }, + { 1, "aerodrome", "Airport" }, + { 1, "terminal", "Airport" }, + { 1, "helipad", "Heliport" }, // { 1, "User Defined", "?" }, - /* aerialway ... */ + /* aerialway ... */ // { 19, "User Defined", "?" }, - /* power ... */ + /* power ... */ // { 14, "tower", "?" }, // { 14, "sub_station", "?" }, // { 14, "generator", "?" }, - /* man_made ... */ + /* man_made ... */ // { 10, "works", "?" }, // { 10, "beacon", "?" }, @@ -185,60 +184,60 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 10, "crane", "?" }, // { 10, "User Defined", "?" }, - /* building ... */ + /* building ... */ - { 3, "yes", "Building" }, + { 3, "yes", "Building" }, // { 3, "User Defined", "?" }, - /* leisure ... */ + /* leisure ... */ // { 9, "sports_centre", "?" }, - { 9, "golf_course", "Golf Course" }, - { 9, "stadium", "Stadium" }, + { 9, "golf_course", "Golf Course" }, + { 9, "stadium", "Stadium" }, // { 9, "track", "?" }, // { 9, "pitch", "?" }, // { 9, "water_park", "?" }, - { 9, "marina", "Marina" }, + { 9, "marina", "Marina" }, // { 9, "slipway", "?" }, - { 9, "fishing", "Fishing Area" }, + { 9, "fishing", "Fishing Area" }, // { 9, "nature_reserve", "?" }, - { 9, "park", "Park" }, + { 9, "park", "Park" }, // { 9, "playground", "?" }, // { 9, "garden", "?" }, // { 9, "common", "?" }, // { 9, "User Defined", "?" }, - /* amenity ... */ + /* amenity ... */ - { 2, "pub", "Bar" }, + { 2, "pub", "Bar" }, // { 2, "biergarten", "?" }, - { 2, "nightclub", "Bar" }, + { 2, "nightclub", "Bar" }, // { 2, "cafe", "?" }, - { 2, "restaurant", "Restaurant" }, - { 2, "fast_food", "Fast Food" }, - { 2, "parking", "Parking Area" }, + { 2, "restaurant", "Restaurant" }, + { 2, "fast_food", "Fast Food" }, + { 2, "parking", "Parking Area" }, // { 2, "bicycle_parking", "?" }, // { 2, "bicycle_rental", "?" }, - { 2, "car_rental", "Car Rental" }, + { 2, "car_rental", "Car Rental" }, // { 2, "car_sharing", "?" }, // { 2, "taxi", "?" }, - { 2, "fuel", "Gas Station" }, - { 2, "telephone", "Telephone" }, - { 2, "toilets", "Restroom" }, + { 2, "fuel", "Gas Station" }, + { 2, "telephone", "Telephone" }, + { 2, "toilets", "Restroom" }, // { 2, "recycling", "?" }, // { 2, "public_building", "?" }, - { 2, "townhall", "City Hall" }, + { 2, "townhall", "City Hall" }, // { 2, "place_of_worship", "?" }, // { 2, "grave_yard", "?" }, - { 2, "post_office", "Post Office" }, + { 2, "post_office", "Post Office" }, // { 2, "post_box", "?" }, - { 2, "school", "School" }, + { 2, "school", "School" }, // { 2, "university", "?" }, // { 2, "college", "?" }, - { 2, "pharmacy", "Pharmacy" }, - { 2, "hospital", "Medical Facility" }, + { 2, "pharmacy", "Pharmacy" }, + { 2, "hospital", "Medical Facility" }, // { 2, "library", "?" }, - { 2, "police", "Police Station" }, + { 2, "police", "Police Station" }, // { 2, "fire_station", "?" }, // { 2, "bus_station", "?" }, // { 2, "theatre", "?" }, @@ -246,16 +245,16 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 2, "arts_centre", "?" }, // { 2, "courthouse", "?" }, // { 2, "prison", "?" }, - { 2, "bank", "Bank" }, + { 2, "bank", "Bank" }, // { 2, "bureau_de_change", "?" }, // { 2, "atm", "?" }, // { 2, "fountain", "?" }, // { 2, "User Defined", "?" }, - /* shop ... */ + /* shop ... */ // { 15, "supermarket", "?" }, - { 15, "convenience", "Convenience Store" }, + { 15, "convenience", "Convenience Store" }, // { 15, "butcher", "?" }, // { 15, "bicycle", "?" }, // { 15, "doityourself", "?" }, @@ -265,25 +264,25 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 15, "kiosk", "?" }, // { 15, "User Defined", "?" }, - /* tourism ... */ - - { 17, "information", "Information" }, - { 17, "hotel", "Hotel" }, - { 17, "motel", "Lodging" }, - { 17, "guest_house", "Lodging" }, - { 17, "hostel", "Lodging" }, - { 17, "camp_site", "Campground" }, - { 17, "caravan_site", "RV Park" }, - { 17, "picnic_site", "Picnic Area" }, - { 17, "viewpoint", "Scenic Area" }, + /* tourism ... */ + + { 17, "information", "Information" }, + { 17, "hotel", "Hotel" }, + { 17, "motel", "Lodging" }, + { 17, "guest_house", "Lodging" }, + { 17, "hostel", "Lodging" }, + { 17, "camp_site", "Campground" }, + { 17, "caravan_site", "RV Park" }, + { 17, "picnic_site", "Picnic Area" }, + { 17, "viewpoint", "Scenic Area" }, // { 17, "theme_park", "?" }, // { 17, "attraction", "?" }, - { 17, "zoo", "Zoo" }, + { 17, "zoo", "Zoo" }, // { 17, "artwork", "?" }, - { 17, "museum", "Museum" }, + { 17, "museum", "Museum" }, // { 17, "User Defined", "?" }, - /* historic ... */ + /* historic ... */ // { 7, "castle", "?" }, // { 7, "monument", "?" }, @@ -293,14 +292,14 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 7, "battlefield", "?" }, // { 7, "User Defined", "?" }, - /* landuse ... */ + /* landuse ... */ // { 8, "farm", "?" }, // { 8, "quarry", "?" }, // { 8, "landfill", "?" }, // { 8, "basin", "?" }, // { 8, "reservoir", "?" }, - { 8, "forest", "Forest" }, + { 8, "forest", "Forest" }, // { 8, "allotments", "?" }, // { 8, "residential", "?" }, // { 8, "retail", "?" }, @@ -310,13 +309,13 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 8, "greenfield", "?" }, // { 8, "railway", "?" }, // { 8, "construction", "?" }, - { 8, "military", "Military" }, - { 8, "cemetery", "Cemetery" }, + { 8, "military", "Military" }, + { 8, "cemetery", "Cemetery" }, // { 8, "village_green", "?" }, // { 8, "recreation_ground", "?" }, // { 8, "User Defined", "?" }, - /* military ... */ + /* military ... */ // { 11, "airfield", "?" }, // { 11, "bunker", "?" }, @@ -326,7 +325,7 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 11, "naval_base", "?" }, // { 11, "User Defined", "?" }, - /* natural ... */ + /* natural ... */ // { 12, "spring", "?" }, // { 12, "peak", "?" }, @@ -342,13 +341,13 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 12, "water", "?" }, // { 12, "coastline", "?" }, // { 12, "mud", "?" }, - { 12, "beach", "Beach" }, + { 12, "beach", "Beach" }, // { 12, "bay", "?" }, // { 12, "land", "?" }, // { 12, "cave_entrance", "?" }, // { 12, "User Defined", "?" }, - /* sport ... */ + /* sport ... */ // { 16, "10pin", "?" }, // { 16, "athletics", "?" }, @@ -377,38 +376,38 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 16, "skating", "?" }, // { 16, "skateboard", "?" }, // { 16, "soccer", "?" }, - { 16, "swimming", "Swimming Area" }, - { 16, "skiing", "Skiing Area" }, + { 16, "swimming", "Swimming Area" }, + { 16, "skiing", "Skiing Area" }, // { 16, "table_tennis", "?" }, // { 16, "tennis", "?" }, // { 16, "orienteering", "?" }, // { 16, "User Defined", "?" }, - /* place ... */ + /* place ... */ // { 13, "continent", "?" }, // { 13, "country", "?" }, // { 13, "state", "?" }, // { 13, "region", "?" }, // { 13, "county", "?" }, - { 13, "city", "City (Large)" }, - { 13, "town", "City (Medium)" }, - { 13, "village", "City (Small)" }, + { 13, "city", "City (Large)" }, + { 13, "town", "City (Medium)" }, + { 13, "village", "City (Small)" }, // { 13, "hamlet", "?" }, // { 13, "suburb", "?" }, // { 13, "locality", "?" }, // { 13, "island", "?" }, // { 13, "User Defined", "?" }, - { -1, NULL, NULL } + { -1, NULL, NULL } }; #if ! HAVE_LIBEXPAT void -osm_rd_init(const char *fname) +osm_rd_init(const char* fname) { - fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); } void @@ -426,287 +425,286 @@ osm_read(void) static void osm_features_init(void) { - int i; - - keys = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); - values = avltree_init(0, MYNAME); - - /* the first of osm_features is a place holder */ - for (i = 1; osm_features[i]; i++) - avltree_insert(keys, osm_features[i], gb_int2ptr(i)); - - for (i = 0; osm_icon_mappings[i].value; i++) { - char buff[128]; - - buff[0] = osm_icon_mappings[i].key; - strncpy(&buff[1], osm_icon_mappings[i].value, sizeof(buff) - 1); - avltree_insert(values, buff, (const void *)&osm_icon_mappings[i]); - } + int i; + + keys = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); + values = avltree_init(0, MYNAME); + + /* the first of osm_features is a place holder */ + for (i = 1; osm_features[i]; i++) { + avltree_insert(keys, osm_features[i], gb_int2ptr(i)); + } + + for (i = 0; osm_icon_mappings[i].value; i++) { + char buff[128]; + + buff[0] = osm_icon_mappings[i].key; + strncpy(&buff[1], osm_icon_mappings[i].value, sizeof(buff) - 1); + avltree_insert(values, buff, (const void*)&osm_icon_mappings[i]); + } } static char -osm_feature_ikey(const char *key) +osm_feature_ikey(const char* key) { - int result; - const void *p; - - if (avltree_find(keys, key, &p)) - result = gb_ptr2int(p); - else - result = -1; - - return result; + int result; + const void* p; + + if (avltree_find(keys, key, &p)) { + result = gb_ptr2int(p); + } else { + result = -1; + } + + return result; } -static char * -osm_feature_symbol(const int ikey, const char *value) +static char* +osm_feature_symbol(const int ikey, const char* value) { - char *result; - char buff[128]; - osm_icon_mapping_t *data; + char* result; + char buff[128]; + osm_icon_mapping_t* data; - buff[0] = ikey; - strncpy(&buff[1], value, sizeof(buff) - 1); + buff[0] = ikey; + strncpy(&buff[1], value, sizeof(buff) - 1); - if (avltree_find(values, buff, (void *)&data)) - result = xstrdup(data->icon); - else - xasprintf(&result, "%s:%s", osm_features[ikey], value); + if (avltree_find(values, buff, (const void**)&data)) { + result = xstrdup(data->icon); + } else { + xasprintf(&result, "%s:%s", osm_features[ikey], value); + } - return result; + return result; } -static char * -osm_strip_html(const char *str) +static char* +osm_strip_html(const char* str) { - utf_string utf; - utf.is_html = 1; - utf.utfstring = (char *)str; + utf_string utf; + utf.is_html = 1; + utf.utfstring = (char*)str; - return strip_html(&utf); // util.c + return strip_html(&utf); // util.c } -static void -osm_node_end(const char *args, const char **unused) +static void +osm_node_end(const char* args, const char** unused) { - if (wpt) { - if (wpt->wpt_flags.fmt_use) - waypt_add(wpt); - else - waypt_free(wpt); - wpt = NULL; - } + if (wpt) { + if (wpt->wpt_flags.fmt_use) { + waypt_add(wpt); + } else { + waypt_free(wpt); + } + wpt = NULL; + } } -static void -osm_node(const char *args, const char **attrv) +static void +osm_node(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - - wpt = waypt_new(); - - while (*avp) { - if (strcmp(avp[0], "id") == 0) { - xasprintf(&wpt->description, "osm-id %s", avp[1]); - if (! avltree_insert(waypoints, avp[1], (void *)wpt)) - warning(MYNAME ": Duplicate osm-id %s!\n", avp[1]); - else - wpt->wpt_flags.fmt_use = 1; - } - else if (strcmp(avp[0], "user") == 0) ; - else if (strcmp(avp[0], "lat") == 0) - wpt->latitude = atof(avp[1]); - else if (strcmp(avp[0], "lon") == 0) - wpt->longitude = atof(avp[1]); - else if (strcmp(avp[0], "timestamp") == 0) - wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); - - avp += 2; - } + const char** avp = &attrv[0]; + + wpt = waypt_new(); + + while (*avp) { + if (strcmp(avp[0], "id") == 0) { + xasprintf(&wpt->description, "osm-id %s", avp[1]); + if (! avltree_insert(waypoints, avp[1], (void*)wpt)) { + warning(MYNAME ": Duplicate osm-id %s!\n", avp[1]); + } else { + wpt->wpt_flags.fmt_use = 1; + } + } else if (strcmp(avp[0], "user") == 0) ; + else if (strcmp(avp[0], "lat") == 0) { + wpt->latitude = atof(avp[1]); + } else if (strcmp(avp[0], "lon") == 0) { + wpt->longitude = atof(avp[1]); + } else if (strcmp(avp[0], "timestamp") == 0) { + wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); + } + + avp += 2; + } } -static void -osm_node_tag(const char *args, const char **attrv) +static void +osm_node_tag(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - const char *key = "", *value = ""; - char *str; - signed char ikey; - - while (*avp) { - if (strcmp(avp[0], "k") == 0) - key = avp[1]; - else if (strcmp(avp[0], "v") == 0) - value = avp[1]; - avp+=2; - } - - str = osm_strip_html(value); - - if (strcmp(key, "name") == 0) { - if (! wpt->shortname) - wpt->shortname = xstrdup(str); - } - else if (strcmp(key, "name:en") == 0) { - if (wpt->shortname) - xfree(wpt->shortname); - wpt->shortname = xstrdup(str); - } - else if ((ikey = osm_feature_ikey(key)) >= 0) { - wpt->icon_descr = osm_feature_symbol(ikey, value); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - } - else if (strcmp(key, "note") == 0) { - if (wpt->notes) { - char *tmp; - xasprintf(&tmp, "%s; %s", wpt->notes, str); - xfree(wpt->notes); - wpt->notes = tmp; - } - else - wpt->notes = xstrdup(str); - } - else if (strcmp(key, "gps:hdop") == 0) { - wpt->hdop = atof(str); - } - else if (strcmp(key, "gps:vdop") == 0) { - wpt->vdop = atof(str); - } - else if (strcmp(key, "gps:pdop") == 0) { - wpt->pdop = atof(str); - } - else if (strcmp(key, "gps:sat") == 0) { - wpt->sat = atoi(str); - } - else if (strcmp(key, "gps:fix") == 0) { - if (strcmp(str, "2d") == 0) { - wpt->fix = fix_2d; - } - else if (strcmp(str, "3d") == 0) { - wpt->fix = fix_3d; - } - else if (strcmp(str, "dgps") == 0) { - wpt->fix = fix_dgps; - } - else if (strcmp(str, "pps") == 0) { - wpt->fix = fix_pps; - } - else if (strcmp(str, "none") == 0) { - wpt->fix = fix_none; - } - } - - xfree(str); + const char** avp = &attrv[0]; + const char* key = "", *value = ""; + char* str; + signed char ikey; + + while (*avp) { + if (strcmp(avp[0], "k") == 0) { + key = avp[1]; + } else if (strcmp(avp[0], "v") == 0) { + value = avp[1]; + } + avp+=2; + } + + str = osm_strip_html(value); + + if (strcmp(key, "name") == 0) { + if (! wpt->shortname) { + wpt->shortname = xstrdup(str); + } + } else if (strcmp(key, "name:en") == 0) { + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup(str); + } else if ((ikey = osm_feature_ikey(key)) >= 0) { + wpt->icon_descr = osm_feature_symbol(ikey, value); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + } else if (strcmp(key, "note") == 0) { + if (wpt->notes) { + char* tmp; + xasprintf(&tmp, "%s; %s", wpt->notes, str); + xfree(wpt->notes); + wpt->notes = tmp; + } else { + wpt->notes = xstrdup(str); + } + } else if (strcmp(key, "gps:hdop") == 0) { + wpt->hdop = atof(str); + } else if (strcmp(key, "gps:vdop") == 0) { + wpt->vdop = atof(str); + } else if (strcmp(key, "gps:pdop") == 0) { + wpt->pdop = atof(str); + } else if (strcmp(key, "gps:sat") == 0) { + wpt->sat = atoi(str); + } else if (strcmp(key, "gps:fix") == 0) { + if (strcmp(str, "2d") == 0) { + wpt->fix = fix_2d; + } else if (strcmp(str, "3d") == 0) { + wpt->fix = fix_3d; + } else if (strcmp(str, "dgps") == 0) { + wpt->fix = fix_dgps; + } else if (strcmp(str, "pps") == 0) { + wpt->fix = fix_pps; + } else if (strcmp(str, "none") == 0) { + wpt->fix = fix_none; + } + } + + xfree(str); } -static void -osm_way(const char *args, const char **attrv) +static void +osm_way(const char* args, const char** attrv) { - const char **avp = &attrv[0]; + const char** avp = &attrv[0]; - rte = route_head_alloc(); + rte = route_head_alloc(); - while (*avp) { - if (strcmp(avp[0], "id") == 0) { - xasprintf(&rte->rte_desc, "osm-id %s", avp[1]); - } - avp += 2; - } + while (*avp) { + if (strcmp(avp[0], "id") == 0) { + xasprintf(&rte->rte_desc, "osm-id %s", avp[1]); + } + avp += 2; + } } -static void -osm_way_nd(const char *args, const char **attrv) +static void +osm_way_nd(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - - while (*avp) { - if (strcmp(avp[0], "ref") == 0) { - waypoint *tmp; - if (avltree_find(waypoints, avp[1], (void *)&tmp)) { - tmp = waypt_dupe(tmp); - route_add_wpt(rte, tmp); - } - else - warning(MYNAME ": Way reference id \"%s\" wasn't listed under nodes!\n", avp[1]); - } - avp += 2; - } + const char** avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "ref") == 0) { + waypoint* tmp; + if (avltree_find(waypoints, avp[1], (const void**)&tmp)) { + tmp = waypt_dupe(tmp); + route_add_wpt(rte, tmp); + } else { + warning(MYNAME ": Way reference id \"%s\" wasn't listed under nodes!\n", avp[1]); + } + } + avp += 2; + } } -static void -osm_way_tag(const char *args, const char **attrv) +static void +osm_way_tag(const char* args, const char** attrv) { - const char **avp = &attrv[0]; - const char *key = "", *value = ""; - char *str; - - while (*avp) { - if (strcmp(avp[0], "k") == 0) - key = avp[1]; - else if (strcmp(avp[0], "v") == 0) - value = avp[1]; - avp += 2; - } - - str = osm_strip_html(value); - - if (strcmp(key, "name") == 0) { - if (! rte->rte_name) - rte->rte_name = xstrdup(str); - } - else if (strcmp(key, "name:en") == 0) { - if (rte->rte_name) - xfree(rte->rte_name); - rte->rte_name = xstrdup(str); - } - - xfree(str); + const char** avp = &attrv[0]; + const char* key = "", *value = ""; + char* str; + + while (*avp) { + if (strcmp(avp[0], "k") == 0) { + key = avp[1]; + } else if (strcmp(avp[0], "v") == 0) { + value = avp[1]; + } + avp += 2; + } + + str = osm_strip_html(value); + + if (strcmp(key, "name") == 0) { + if (! rte->rte_name) { + rte->rte_name = xstrdup(str); + } + } else if (strcmp(key, "name:en") == 0) { + if (rte->rte_name) { + xfree(rte->rte_name); + } + rte->rte_name = xstrdup(str); + } + + xfree(str); } -static void -osm_way_end(const char *args, const char **unused) +static void +osm_way_end(const char* args, const char** unused) { - if (rte) { - route_add_head(rte); - rte = NULL; - } + if (rte) { + route_add_head(rte); + rte = NULL; + } } -static void -osm_rd_init(const char *fname) +static void +osm_rd_init(const char* fname) { - wpt = NULL; - rte = NULL; - wpt_loaded = 0; - rte_loaded = 0; + wpt = NULL; + rte = NULL; + wpt_loaded = 0; + rte_loaded = 0; - waypoints = avltree_init(0, MYNAME); - if (! keys) - osm_features_init(); + waypoints = avltree_init(0, MYNAME); + if (! keys) { + osm_features_init(); + } - xml_init(fname, osm_map, NULL); + xml_init(fname, osm_map, NULL); } -static void +static void osm_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void osm_rd_deinit(void) { - xml_deinit(); - avltree_done(waypoints); + xml_deinit(); + avltree_done(waypoints); } /*******************************************************************************/ @@ -716,269 +714,291 @@ osm_rd_deinit(void) static void osm_init_icons(void) { - int i; + int i; - if (icons) return; + if (icons) { + return; + } - icons = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); + icons = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); - for (i = 0; osm_icon_mappings[i].value; i++) - avltree_insert(icons, osm_icon_mappings[i].icon, (const void *)&osm_icon_mappings[i]); + for (i = 0; osm_icon_mappings[i].value; i++) { + avltree_insert(icons, osm_icon_mappings[i].icon, (const void*)&osm_icon_mappings[i]); + } } static void -osm_write_tag(const char *key, const char *value) +osm_write_tag(const char* key, const char* value) { - if (value && *value) { - char *str = xml_entitize(value); - gbfprintf(fout, " \n", key, str); - xfree(str); - } + if (value && *value) { + char* str = xml_entitize(value); + gbfprintf(fout, " \n", key, str); + xfree(str); + } } static void -osm_disp_feature(const waypoint *wpt) +osm_disp_feature(const waypoint* wpt) { - osm_icon_mapping_t *map; - - if (avltree_find(icons, wpt->icon_descr, (void *) &map)) - osm_write_tag(osm_features[map->key], map->value); + osm_icon_mapping_t* map; + + if (avltree_find(icons, wpt->icon_descr, (const void**) &map)) { + osm_write_tag(osm_features[map->key], map->value); + } } static void -osm_write_opt_tag(const char *atag) +osm_write_opt_tag(const char* atag) { - char *tag, *cin, *ce; - - if (!atag) return; - - tag = cin = xstrdup(atag); - ce = cin + strlen(cin); - - while (cin < ce) { - char *sc, *dp; - - if ((sc = strchr(cin, ';'))) *sc = '\0'; - - if ((dp = strchr(cin, ':'))) { - *dp++ = '\0'; - osm_write_tag(cin, dp); - } - cin += strlen(cin) + 1; - } - - xfree(tag); + char* tag, *cin, *ce; + + if (!atag) { + return; + } + + tag = cin = xstrdup(atag); + ce = cin + strlen(cin); + + while (cin < ce) { + char* sc, *dp; + + if ((sc = strchr(cin, ';'))) { + *sc = '\0'; + } + + if ((dp = strchr(cin, ':'))) { + *dp++ = '\0'; + osm_write_tag(cin, dp); + } + cin += strlen(cin) + 1; + } + + xfree(tag); } static void -osm_release_ids(const waypoint *wpt) +osm_release_ids(const waypoint* wpt) { - if (wpt && wpt->extra_data) { - waypoint *tmp = (waypoint *)wpt; - xfree(tmp->extra_data); - tmp->extra_data = NULL; - } + if (wpt && wpt->extra_data) { + waypoint* tmp = (waypoint*)wpt; + xfree(tmp->extra_data); + tmp->extra_data = NULL; + } } static void -osm_waypt_disp(const waypoint *wpt) +osm_waypt_disp(const waypoint* wpt) { - char *buff; - - xasprintf(&buff, "%s\01%f\01%f", (wpt->shortname) ? wpt->shortname : "", - wpt->latitude, wpt->longitude); - - if (avltree_insert(waypoints, buff, (const void *) wpt)) { - int *id; - - id = xmalloc(sizeof(*id)); - *id = --node_id; - ((waypoint *)(wpt))->extra_data = id; - - gbfprintf(fout, " latitude, wpt->longitude); - if (wpt->creation_time) { - char time_string[64]; - xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); - gbfprintf(fout, " timestamp='%s'", time_string); - } - gbfprintf(fout, ">\n"); - - if (wpt->hdop) { - gbfprintf(fout, " \n", wpt->hdop); - } - if (wpt->vdop) { - gbfprintf(fout, " \n", wpt->vdop); - } - if (wpt->pdop) { - gbfprintf(fout, " \n", wpt->pdop); - } - if (wpt->sat > 0) { - gbfprintf(fout, " \n", wpt->sat); - } - - switch (wpt->fix) { - case fix_2d: - gbfprintf(fout, " \n"); - break; - case fix_3d: - gbfprintf(fout, " \n"); - break; - case fix_dgps: - gbfprintf(fout, " \n"); - break; - case fix_pps: - gbfprintf(fout, " \n"); - break; - case fix_none: - gbfprintf(fout, " \n"); - break; - case fix_unknown: - default: - break; - } - - if (strlen(created_by) !=0) { - gbfprintf(fout, " \n"); - } - - osm_write_tag("name", wpt->shortname); - osm_write_tag("note", (wpt->notes) ? wpt->notes : wpt->description); - if (wpt->icon_descr) - osm_disp_feature(wpt); - - osm_write_opt_tag(opt_tagnd); - - gbfprintf(fout, " \n"); - } - - xfree(buff); + char* buff; + + xasprintf(&buff, "%s\01%f\01%f", (wpt->shortname) ? wpt->shortname : "", + wpt->latitude, wpt->longitude); + + if (avltree_insert(waypoints, buff, (const void*) wpt)) { + int* id; + + id = (int*) xmalloc(sizeof(*id)); + *id = --node_id; + ((waypoint*)(wpt))->extra_data = id; + + gbfprintf(fout, " latitude, wpt->longitude); + if (wpt->creation_time) { + char time_string[64]; + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); + gbfprintf(fout, " timestamp='%s'", time_string); + } + gbfprintf(fout, ">\n"); + + if (wpt->hdop) { + gbfprintf(fout, " \n", wpt->hdop); + } + if (wpt->vdop) { + gbfprintf(fout, " \n", wpt->vdop); + } + if (wpt->pdop) { + gbfprintf(fout, " \n", wpt->pdop); + } + if (wpt->sat > 0) { + gbfprintf(fout, " \n", wpt->sat); + } + + switch (wpt->fix) { + case fix_2d: + gbfprintf(fout, " \n"); + break; + case fix_3d: + gbfprintf(fout, " \n"); + break; + case fix_dgps: + gbfprintf(fout, " \n"); + break; + case fix_pps: + gbfprintf(fout, " \n"); + break; + case fix_none: + gbfprintf(fout, " \n"); + break; + case fix_unknown: + default: + break; + } + + if (strlen(created_by) !=0) { + gbfprintf(fout, " \n"); + } + + osm_write_tag("name", wpt->shortname); + osm_write_tag("note", (wpt->notes) ? wpt->notes : wpt->description); + if (wpt->icon_descr) { + osm_disp_feature(wpt); + } + + osm_write_opt_tag(opt_tagnd); + + gbfprintf(fout, " \n"); + } + + xfree(buff); } static void -osm_rte_disp_head(const route_head *rte) +osm_rte_disp_head(const route_head* rte) { - skip_rte = (rte->rte_waypt_ct <= 0); - - if (skip_rte) return; + skip_rte = (rte->rte_waypt_ct <= 0); - gbfprintf(fout, " \n", --node_id); -} + if (skip_rte) { + return; + } -static void -osm_rtept_disp(const waypoint *wpt_ref) -{ - char *buff; - waypoint *wpt; - - if (skip_rte) return; - - xasprintf(&buff, "%s\01%f\01%f", (wpt_ref->shortname) ? wpt_ref->shortname : "", - wpt_ref->latitude, wpt_ref->longitude); - - if (avltree_find(waypoints, buff, (void *) &wpt)) { - int *id = wpt->extra_data; - gbfprintf(fout, " \n", *id); - } - - xfree(buff); + gbfprintf(fout, " \n", --node_id); } static void -osm_rte_disp_trail(const route_head *rte) +osm_rtept_disp(const waypoint* wpt_ref) { - if (skip_rte) return; + char* buff; + waypoint* wpt; - if (strlen(created_by) !=0) { - gbfprintf(fout, " \n"); - } + if (skip_rte) { + return; + } - osm_write_tag("name", rte->rte_name); - osm_write_tag("note", rte->rte_desc); + xasprintf(&buff, "%s\01%f\01%f", (wpt_ref->shortname) ? wpt_ref->shortname : "", + wpt_ref->latitude, wpt_ref->longitude); - if (opt_tag && (case_ignore_strncmp(opt_tag, "tagnd", 5) != 0)) - osm_write_opt_tag(opt_tag); + if (avltree_find(waypoints, buff, (const void**) &wpt)) { + int* id = (int*) wpt->extra_data; + gbfprintf(fout, " \n", *id); + } - gbfprintf(fout, " \n"); + xfree(buff); +} + +static void +osm_rte_disp_trail(const route_head* rte) +{ + if (skip_rte) { + return; + } + + if (strlen(created_by) !=0) { + gbfprintf(fout, " \n"); + } + + osm_write_tag("name", rte->rte_name); + osm_write_tag("note", rte->rte_desc); + + if (opt_tag && (case_ignore_strncmp(opt_tag, "tagnd", 5) != 0)) { + osm_write_opt_tag(opt_tag); + } + + gbfprintf(fout, " \n"); } /*-----------------------------------------------------------------------------*/ -static void -osm_wr_init(const char *fname) +static void +osm_wr_init(const char* fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); - osm_init_icons(); - waypoints = avltree_init(0, MYNAME); - node_id = 0; + osm_init_icons(); + waypoints = avltree_init(0, MYNAME); + node_id = 0; } -static void +static void osm_write(void) { - gbfprintf(fout, "\n"); - gbfprintf(fout, "\n"); - - waypt_disp_all(osm_waypt_disp); - route_disp_all(NULL, NULL, osm_waypt_disp); - track_disp_all(NULL, NULL, osm_waypt_disp); - - route_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); - track_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); - - gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + + waypt_disp_all(osm_waypt_disp); + route_disp_all(NULL, NULL, osm_waypt_disp); + track_disp_all(NULL, NULL, osm_waypt_disp); + + route_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); + track_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); + + gbfprintf(fout, "\n"); } -static void +static void osm_wr_deinit(void) { - gbfclose(fout); - - waypt_disp_all(osm_release_ids); - route_disp_all(NULL, NULL, osm_release_ids); - track_disp_all(NULL, NULL, osm_release_ids); + gbfclose(fout); + + waypt_disp_all(osm_release_ids); + route_disp_all(NULL, NULL, osm_release_ids); + track_disp_all(NULL, NULL, osm_release_ids); - avltree_done(waypoints); + avltree_done(waypoints); } static void osm_exit(void) { - if (keys) - avltree_done(keys); - if (values) - avltree_done(values); - if (icons) - avltree_done(icons); + if (keys) { + avltree_done(keys); + } + if (values) { + avltree_done(values); + } + if (icons) { + avltree_done(icons); + } } /*-----------------------------------------------------------------------------*/ ff_vecs_t osm_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_write /* tracks */, - ff_cap_read | ff_cap_write /* routes */, - }, - osm_rd_init, - osm_wr_init, - osm_rd_deinit, - osm_wr_deinit, - osm_read, - osm_write, - osm_exit, - osm_args, - CET_CHARSET_UTF8, 0 + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + ff_cap_write /* tracks */, + (ff_cap)(ff_cap_read | ff_cap_write) /* routes */, + }, + osm_rd_init, + osm_wr_init, + osm_rd_deinit, + osm_wr_deinit, + osm_read, + osm_write, + osm_exit, + osm_args, + CET_CHARSET_UTF8, 0 }; diff --git a/gpsbabel/overlay.c b/gpsbabel/overlay.c index 20b92674c..93999596c 100644 --- a/gpsbabel/overlay.c +++ b/gpsbabel/overlay.c @@ -38,8 +38,8 @@ static short_handle mkshort_handle; #undef MAPNAME #define MAPNAME "Top. Karte 1:50.000 Nieders." -static gbfile *fpout; -static gbfile *fpin; +static gbfile* fpout; +static gbfile* fpin; static int govl_cnt; static double govl_sum_e=0.0; static double govl_sum_n=0.0; @@ -52,16 +52,16 @@ static double govl_last_north=0.0; */ static int govl_col=1; -static char *govl_col_s = NULL; +static char* govl_col_s = NULL; static int govl_size=101; -static char *govl_size_s = NULL; +static char* govl_size_s = NULL; static double govl_dir=0.0; -static char *govl_mapname = NULL; +static char* govl_mapname = NULL; static int govl_zoomfc = 100; -static char *govl_zoomfc_s = NULL; +static char* govl_zoomfc_s = NULL; static int govl_dimmfc = 100; -static char *govl_dimmfc_s = NULL; +static char* govl_dimmfc_s = NULL; static int govl_txtcol=1; @@ -69,57 +69,77 @@ static int govl_txtsize=120; static int govl_font=1; static int govl_txttrans=0; -static char *govl_txtcol_s = NULL; -static char *govl_txtsize_s = NULL; -static char *govl_font_s = NULL; -static char *govl_txttrans_s = NULL; +static char* govl_txtcol_s = NULL; +static char* govl_txtsize_s = NULL; +static char* govl_font_s = NULL; +static char* govl_txttrans_s = NULL; -static char *govl_file_s = NULL; +static char* govl_file_s = NULL; static arglist_t ovl_args[] = { - { "col", &govl_col_s, "color index [1-9] for routes", - NULL, ARGTYPE_INT, "1", "9" }, - { "size", &govl_size_s, "size index [101-] for routes", - NULL, ARGTYPE_INT, "101", NULL }, - { "mapname", &govl_mapname, "name of map", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "zoomfc", &govl_zoomfc_s, "zoom factor of map in %", - NULL, ARGTYPE_INT, ARG_NOMINMAX }, - { "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %", - NULL, ARGTYPE_INT, ARG_NOMINMAX }, - { "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names", - NULL, ARGTYPE_INT, "1", "9" }, - { "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names", - NULL, ARGTYPE_INT, "101", NULL }, - { "font", &govl_font_s, "font index [1-] for waypoint names", - NULL, ARGTYPE_INT, "1", NULL }, - { "txttrans", &govl_txttrans_s, "set text background to transparent", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "col", &govl_col_s, "color index [1-9] for routes", + NULL, ARGTYPE_INT, "1", "9" + }, + { + "size", &govl_size_s, "size index [101-] for routes", + NULL, ARGTYPE_INT, "101", NULL + }, + { + "mapname", &govl_mapname, "name of map", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "zoomfc", &govl_zoomfc_s, "zoom factor of map in %", + NULL, ARGTYPE_INT, ARG_NOMINMAX + }, + { + "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %", + NULL, ARGTYPE_INT, ARG_NOMINMAX + }, + { + "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names", + NULL, ARGTYPE_INT, "1", "9" + }, + { + "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names", + NULL, ARGTYPE_INT, "101", NULL + }, + { + "font", &govl_font_s, "font index [1-] for waypoint names", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "txttrans", &govl_txttrans_s, "set text background to transparent", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static char *Keywords[]={ - "Typ", - "Group", - "Col", - "Zoom", - "Size", - "Art", - "Punkte", - "Path", - "Dir", - "Font", - "Area", - "Text", - "Width", - "Height", - "Trans", - "TransByte", - NULL - }; +static char* Keywords[]= { + "Typ", + "Group", + "Col", + "Zoom", + "Size", + "Art", + "Punkte", + "Path", + "Dir", + "Font", + "Area", + "Text", + "Width", + "Height", + "Trans", + "TransByte", + NULL +}; #define KEY_TYP 0 #define KEY_GROUP 1 @@ -138,19 +158,21 @@ static char *Keywords[]={ #define KEY_TRANS 14 #define KEY_TRANSBYTE 15 -static int isKeyword(char *str,char **keys) +static int isKeyword(char* str,char** keys) { int i; i = 0; - while(keys[i]!=NULL && strcmp(str,keys[i])) i++; + while (keys[i]!=NULL && strcmp(str,keys[i])) { + i++; + } return(keys[i]==NULL ? -1 : i); } /*----------------------------------------------*/ static -void ovl_rd_init(char const *fname) +void ovl_rd_init(char const* fname) { fpin = gbfopen(fname, "r", MYNAME); } @@ -163,69 +185,69 @@ void ovl_rd_init(char const *fname) #define MAXLINE 512 static struct _group { - int group; - char *name; - } *groups; + int group; + char* name; +}* groups; static int groups_cnt; -static void ovl_add_group(int aktgrp,char *akttxt) +static void ovl_add_group(int aktgrp,char* akttxt) { int i; i = 0; - while (irte_name); i = 0; - while (irte_name = (char *) xrealloc(route->rte_name,(strlen(name)+1)*sizeof(char)); + route->rte_name = (char*) xrealloc(route->rte_name,(strlen(name)+1)*sizeof(char)); strcpy(route->rte_name,name); } static void ovl_read(void) { - char *line; + char* line; int isSection; int aktTyp,aktCol,aktSize,aktArt,aktGroup; int aktArea,aktWidth,aktHeight,aktTrans,aktTransByte,aktDir; double aktX,aktY; - char *aktPath; - char *aktText; - char *pstr; + char* aktPath; + char* aktText; + char* pstr; int keyw,i; double rwert; - route_head *route_head = NULL; - waypoint *wpt; + route_head* route_head = NULL; + waypoint* wpt; int sym_cnt; int lineno = 0; @@ -238,160 +260,151 @@ static void ovl_read(void) aktPath = NULL; sym_cnt = 0; isSection = SECTION_NONE; - while ((line = gbfgetstr(fpin))) - { - if ((lineno == 0) && fpin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); + while ((line = gbfgetstr(fpin))) { + if ((lineno == 0) && fpin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } lineno++; line = lrtrim(line); - if( (pstr = strstr(line,"[Symbol "))!= NULL) - { + if ((pstr = strstr(line,"[Symbol "))!= NULL) { sym_cnt++; isSection = SECTION_SYMBOL; - } - else if( (pstr = strstr(line,"[Overlay]"))!= NULL) - { + } else if ((pstr = strstr(line,"[Overlay]"))!= NULL) { isSection = SECTION_OVERLAY; - } - else if (isSection==SECTION_SYMBOL) - { + } else if (isSection==SECTION_SYMBOL) { pstr = strtok(line,"="); - if (pstr!=NULL) - { + if (pstr!=NULL) { keyw = isKeyword(pstr,Keywords); pstr = strtok(NULL,"\n"); - if (pstr!=NULL) - { - switch(keyw) - { - case KEY_TYP : - aktTyp = atoi(pstr); - break; - case KEY_GROUP : - aktGroup = atoi(pstr); - ovl_add_group(aktGroup,"?"); /* 'Group' without relation to 'Text'-Symbol */ - switch(aktTyp) - { - case 3: // Linie - route_head = route_head_alloc(); - route_head->rte_num = sym_cnt; - route_head->rte_name = xstrdup(pstr); /* use group-number for the moment */ - route_add_head(route_head); - break; - } - break; - case KEY_COL : - aktCol = atoi(pstr); - break; - case KEY_ZOOM : - break; - case KEY_SIZE : - aktSize = atoi(pstr); - break; - case KEY_ART : - aktArt = atoi(pstr); - break; - case KEY_AREA : - aktArea = atoi(pstr); - if (aktTyp==5 || aktTyp==5 || aktTyp==7) isSection = SECTION_PUNKTE; // Rechteck, Kreis, Dreieck - break; - case KEY_PUNKTE : - isSection = SECTION_PUNKTE; // Linie, Fläche + if (pstr!=NULL) { + switch (keyw) { + case KEY_TYP : + aktTyp = atoi(pstr); + break; + case KEY_GROUP : + aktGroup = atoi(pstr); + ovl_add_group(aktGroup,"?"); /* 'Group' without relation to 'Text'-Symbol */ + switch (aktTyp) { + case 3: // Linie + route_head = route_head_alloc(); + route_head->rte_num = sym_cnt; + route_head->rte_name = xstrdup(pstr); /* use group-number for the moment */ + route_add_head(route_head); break; + } + break; + case KEY_COL : + aktCol = atoi(pstr); + break; + case KEY_ZOOM : + break; + case KEY_SIZE : + aktSize = atoi(pstr); + break; + case KEY_ART : + aktArt = atoi(pstr); + break; + case KEY_AREA : + aktArea = atoi(pstr); + if (aktTyp==5 || aktTyp==5 || aktTyp==7) { + isSection = SECTION_PUNKTE; // Rechteck, Kreis, Dreieck + } + break; + case KEY_PUNKTE : + isSection = SECTION_PUNKTE; // Linie, Fläche + break; #ifdef WITH_BITMAP - case KEY_PATH : - aktPath = xstrdup(pstr); - isSection = SECTION_PUNKTE; // Bitmap - break; - case KEY_TRANS : - aktTrans = atoi(pstr); - break; - case KEY_TRANSBYTE : - aktTransByte = atoi(pstr); - break; + case KEY_PATH : + aktPath = xstrdup(pstr); + isSection = SECTION_PUNKTE; // Bitmap + break; + case KEY_TRANS : + aktTrans = atoi(pstr); + break; + case KEY_TRANSBYTE : + aktTransByte = atoi(pstr); + break; #endif - case KEY_TEXT : - aktText = xstrdup(pstr); - /* The last 'Text'-symbol wins as a information block for - waypoint/route description. - Infos from previous symbols get overwrited. - */ - ovl_add_group(aktGroup,aktText); - break; - case KEY_WIDTH : - aktWidth = atoi(pstr); - break; - case KEY_HEIGHT : - aktHeight = atoi(pstr); - break; - case KEY_DIR : - aktDir = atoi(pstr); - if (aktTyp==2) isSection = SECTION_PUNKTE; // Text - break; + case KEY_TEXT : + aktText = xstrdup(pstr); + /* The last 'Text'-symbol wins as a information block for + waypoint/route description. + Infos from previous symbols get overwrited. + */ + ovl_add_group(aktGroup,aktText); + break; + case KEY_WIDTH : + aktWidth = atoi(pstr); + break; + case KEY_HEIGHT : + aktHeight = atoi(pstr); + break; + case KEY_DIR : + aktDir = atoi(pstr); + if (aktTyp==2) { + isSection = SECTION_PUNKTE; // Text + } + break; } } } - } - else if (isSection==SECTION_PUNKTE) - { + } else if (isSection==SECTION_PUNKTE) { pstr = strtok(line,"="); - if (strstr(pstr,"XKoord")!=NULL || strstr(pstr,"YKoord")!=NULL) - { - if ((pstr = strtok(NULL,"\n"))!=NULL) - { + if (strstr(pstr,"XKoord")!=NULL || strstr(pstr,"YKoord")!=NULL) { + if ((pstr = strtok(NULL,"\n"))!=NULL) { rwert = atof(pstr); - if (line[0]=='X') - { + if (line[0]=='X') { aktX = rwert; - } - else if (line[0]=='Y') - { + } else if (line[0]=='Y') { aktY = rwert; - switch(aktTyp) - { + switch (aktTyp) { #ifdef WITH_BITMAP - case 1: // Bitmap - wpt = waypt_new(); - wpt->latitude = aktY; - wpt->longitude = aktX; - wpt->altitude = 0.0; - wpt->shortname = strdup(aktPath); - waypt_add(wpt); - break; + case 1: // Bitmap + wpt = waypt_new(); + wpt->latitude = aktY; + wpt->longitude = aktX; + wpt->altitude = 0.0; + wpt->shortname = strdup(aktPath); + waypt_add(wpt); + break; #endif - case 2: // Text - isSection = SECTION_SYMBOL; - break; - case 3: // Linie - wpt = waypt_new(); - wpt->latitude = aktY; - wpt->longitude = aktX; - wpt->altitude = 0.0; - route_add_wpt(route_head, wpt); - break; - case 4: // Fläche - break; - case 5: // Rechteck - break; - case 6: // Kreis - break; - case 7: // Dreieck - break; + case 2: // Text + isSection = SECTION_SYMBOL; + break; + case 3: // Linie + wpt = waypt_new(); + wpt->latitude = aktY; + wpt->longitude = aktX; + wpt->altitude = 0.0; + route_add_wpt(route_head, wpt); + break; + case 4: // Fläche + break; + case 5: // Rechteck + break; + case 6: // Kreis + break; + case 7: // Dreieck + break; } } } } - } - else if (isSection==SECTION_OVERLAY) - { + } else if (isSection==SECTION_OVERLAY) { isSection = SECTION_NONE; } } route_disp_all(route_add_name,NULL,NULL); - if (aktText!=NULL) xfree(aktText); - if (aktPath!=NULL) xfree(aktPath); - for (i=0;iargstring!=NULL) - { - if (strcmp(pstr,p->argstring)==0) - { + if (pstr!=NULL) { + while (p->argstring!=NULL) { + if (strcmp(pstr,p->argstring)==0) { pstr = strtok(NULL,"\n"); - if (p->argtype==ARGTYPE_BOOL) - { + if (p->argtype==ARGTYPE_BOOL) { *(p->argval) = atoi(pstr) ? xstrdup(pstr) : NULL; - } - else - { + } else { *(p->argval) = xstrdup(pstr); } break; @@ -445,7 +449,7 @@ void ovl_read_parameter(char *fname) } } -static void ovl_wr_init(const char *fname) +static void ovl_wr_init(const char* fname) { fpout = gbfopen(fname, "w", MYNAME); govl_sum_n = 0.0; @@ -456,40 +460,31 @@ static void ovl_wr_init(const char *fname) ovl_read_parameter(govl_file_s!=NULL ? govl_file_s : PARAMETER_FILE); - if (govl_col_s!=NULL) - { + if (govl_col_s!=NULL) { govl_col = atoi(govl_col_s); } - if (govl_size_s!=NULL) - { + if (govl_size_s!=NULL) { govl_size = atoi(govl_size_s); } - if (govl_mapname==NULL) - { + if (govl_mapname==NULL) { govl_mapname = xstrdup(MAPNAME); } - if (govl_zoomfc_s!=NULL) - { + if (govl_zoomfc_s!=NULL) { govl_zoomfc = atoi(govl_zoomfc_s); } - if (govl_dimmfc_s!=NULL) - { + if (govl_dimmfc_s!=NULL) { govl_dimmfc = atoi(govl_dimmfc_s); } - if (govl_txtcol_s!=NULL) - { + if (govl_txtcol_s!=NULL) { govl_txtcol = atoi(govl_txtcol_s); } - if (govl_txtsize_s!=NULL) - { + if (govl_txtsize_s!=NULL) { govl_txtsize = atoi(govl_txtsize_s); } - if (govl_font_s!=NULL) - { + if (govl_font_s!=NULL) { govl_font = atoi(govl_font_s); } - if (govl_txttrans_s!=NULL) - { + if (govl_txttrans_s!=NULL) { govl_txttrans = 1; } } @@ -502,13 +497,10 @@ static void ovl_wr_deinit(void) gbfprintf(fpout,"MapName=%s\n",govl_mapname); gbfprintf(fpout,"DimmFc=%d\n",govl_dimmfc); gbfprintf(fpout,"ZoomFc=%d\n",govl_zoomfc); - if (govl_symbol_cnt) - { + if (govl_symbol_cnt) { gbfprintf(fpout,"CenterLat=%.8lf\n",govl_sum_n/govl_sumcnt); // precision 8 = better than 1mm gbfprintf(fpout,"CenterLong=%.8lf\n",govl_sum_e/govl_sumcnt); - } - else - { + } else { gbfprintf(fpout,"CenterLong=10.52374295\n"); // Braunschweiger Löwe, Mittelpunkt der Welt :-) gbfprintf(fpout,"CenterLat=52.26474445\n"); } @@ -517,7 +509,7 @@ static void ovl_wr_deinit(void) gbfclose(fpout); } -static void symbol_init(const route_head *hd) +static void symbol_init(const route_head* hd) { gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1); gbfprintf(fpout,"Typ=3\n"); // Linie @@ -532,7 +524,7 @@ static void symbol_init(const route_head *hd) govl_group_cnt++; } -static void symbol_text(double east,double north,char *text,int group) +static void symbol_text(double east,double north,char* text,int group) { gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1); gbfprintf(fpout,"Typ=2\n"); // Text @@ -549,7 +541,7 @@ static void symbol_text(double east,double north,char *text,int group) govl_symbol_cnt++; } -static void symbol_point(const waypoint *wpt) +static void symbol_point(const waypoint* wpt) { double east,north; @@ -561,17 +553,17 @@ static void symbol_point(const waypoint *wpt) govl_sum_e += east; govl_sum_n += north; govl_sumcnt += 1.0; -/* - govl_last_east = east; - govl_last_north = north; -*/ + /* + govl_last_east = east; + govl_last_north = north; + */ } -static void symbol_deinit(const route_head *hd) +static void symbol_deinit(const route_head* hd) { - queue *elem, *tmp; - waypoint *waypointp; + queue* elem, *tmp; + waypoint* waypointp; int i; double lat1,lon1,lat2,lon2; double lats,lons,late,lone; @@ -581,18 +573,14 @@ static void symbol_deinit(const route_head *hd) lats = lons = late = lone = 0.0; dist = 0.0; i = 0; - QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp) - { - waypointp = (waypoint *) elem; + QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp) { + waypointp = (waypoint*) elem; lat2 = RAD(waypointp->latitude); lon2 = RAD(waypointp->longitude); - if (i) - { - d = gcdist(lat1, lon1, lat2, lon2 ); + if (i) { + d = gcdist(lat1, lon1, lat2, lon2); dist += d; - } - else - { + } else { lats = lat2; // start point lons = lon2; } @@ -605,14 +593,12 @@ static void symbol_deinit(const route_head *hd) dd = 0; i = 0; elem = QUEUE_FIRST(&(hd->waypoint_list)); - while (elem!=&(hd->waypoint_list) && ddwaypoint_list) && ddlatitude); lon2 = RAD(waypointp->longitude); - if (i) - { - d = gcdist(lat1, lon1, lat2, lon2 ); + if (i) { + d = gcdist(lat1, lon1, lat2, lon2); dd += d; } lat1 = lat2; @@ -623,8 +609,10 @@ static void symbol_deinit(const route_head *hd) d = gcdist(lats,lons,late,lone); // d = acos( sin(lats)*sin(late)+cos(lats)*cos(late)*cos(lone-lons) ); - dd = acos( (sin(late) - sin(lats)*cos(d))/(cos(lats)*sin(d)) ); - if (loneshortname; } oname = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, odesc) : - waypointp->shortname; + mkshort(mkshort_handle, odesc) : + waypointp->shortname; gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1); gbfprintf(fpout,"Typ=1\n"); @@ -680,28 +668,28 @@ static void ovl_write(void) waypt_disp_all(overlay_waypt_pr); track_disp_all(symbol_init, symbol_deinit, symbol_point); route_disp_all(symbol_init, symbol_deinit, symbol_point); -/* - switch(global_opts.objective) - { - case wptdata: - break; - case trkdata: - break; - } -*/ + /* + switch(global_opts.objective) + { + case wptdata: + break; + case trkdata: + break; + } + */ } ff_vecs_t overlay_vecs = { - ff_type_internal, - FF_CAP_RW_ALL, - ovl_rd_init, - ovl_wr_init, - ovl_rd_deinit, - ovl_wr_deinit, - ovl_read, - ovl_write, - NULL, - ovl_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_internal, + FF_CAP_RW_ALL, + ovl_rd_init, + ovl_wr_init, + ovl_rd_deinit, + ovl_wr_deinit, + ovl_read, + ovl_write, + NULL, + ovl_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/ozi.c b/gpsbabel/ozi.c index 2e8fc68b3..d5f6e7a79 100644 --- a/gpsbabel/ozi.c +++ b/gpsbabel/ozi.c @@ -1,6 +1,6 @@ /* OziExplorer Waypoints/Tracks/Routes - Comma Delimited + Comma Delimited As described in OziExplorer Help File @@ -33,9 +33,9 @@ #define DAYS_SINCE_1990 25569 typedef struct { - format_specific_data fs; - int fgcolor; - int bgcolor; + format_specific_data fs; + int fgcolor; + int bgcolor; } ozi_fsdata; @@ -68,27 +68,47 @@ static double prox_scale; static arglist_t ozi_args[] = { - {"pack", &pack_opt, "Write all tracks into one file", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snlen", &snlenopt, "Max synthesized shortname length", - "32", ARGTYPE_INT, "1", NULL}, - {"snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snupper", &snupperopt, "UPPERCASE synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snunique", &snuniqueopt, "Make synth. shortnames unique", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"wptfgcolor", &wptfgcolor, "Waypoint foreground color", - "black", ARGTYPE_STRING, ARG_NOMINMAX}, - {"wptbgcolor", &wptbgcolor, "Waypoint background color", - "yellow", ARGTYPE_STRING, ARG_NOMINMAX}, - {"proximity", &proximityarg, "Proximity distance", - "0", ARGTYPE_STRING, ARG_NOMINMAX}, - {"altunit", &altunit_opt, "Unit used in altitude values", - "feet", ARGTYPE_STRING, ARG_NOMINMAX}, - {"proxunit", &proxunit_opt, "Unit used in proximity values", - "miles", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "pack", &pack_opt, "Write all tracks into one file", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snlen", &snlenopt, "Max synthesized shortname length", + "32", ARGTYPE_INT, "1", NULL + }, + { + "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snupper", &snupperopt, "UPPERCASE synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snunique", &snuniqueopt, "Make synth. shortnames unique", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "wptfgcolor", &wptfgcolor, "Waypoint foreground color", + "black", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "wptbgcolor", &wptbgcolor, "Waypoint background color", + "yellow", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "proximity", &proximityarg, "Proximity distance", + "0", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "altunit", &altunit_opt, "Unit used in altitude values", + "feet", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "proxunit", &proxunit_opt, "Unit used in proximity values", + "miles", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static gpsdata_type ozi_objective; @@ -96,169 +116,177 @@ static gpsdata_type ozi_objective; static char *ozi_ofname = NULL; static void -ozi_copy_fsdata(ozi_fsdata **dest, ozi_fsdata *src) +ozi_copy_fsdata(ozi_fsdata **dest, ozi_fsdata *src) { - /* No strings to mess with. Straight forward copy. */ - *dest = (void *)xmalloc(sizeof(*src)); - **dest = *src; - (*dest)->fs.next = NULL; + /* No strings to mess with. Straight forward copy. */ + *dest = (ozi_fsdata *)xmalloc(sizeof(*src)); + **dest = *src; + (*dest)->fs.next = NULL; } static void ozi_free_fsdata(void *fsdata) { - xfree(fsdata); + xfree(fsdata); } static ozi_fsdata * -ozi_alloc_fsdata(void) +ozi_alloc_fsdata(void) { - ozi_fsdata *fsdata = xcalloc(sizeof(*fsdata), 1); - fsdata->fs.type = FS_OZI; - fsdata->fs.copy = (fs_copy) ozi_copy_fsdata; - fsdata->fs.destroy = ozi_free_fsdata; - fsdata->fs.convert = NULL; + ozi_fsdata *fsdata = (ozi_fsdata*) xcalloc(sizeof(*fsdata), 1); + fsdata->fs.type = FS_OZI; + fsdata->fs.copy = (fs_copy) ozi_copy_fsdata; + fsdata->fs.destroy = ozi_free_fsdata; + fsdata->fs.convert = NULL; - /* Provide defaults via command line defaults */ - fsdata->fgcolor = color_to_bbggrr(wptfgcolor); - fsdata->bgcolor = color_to_bbggrr(wptbgcolor); + /* Provide defaults via command line defaults */ + fsdata->fgcolor = color_to_bbggrr(wptfgcolor); + fsdata->bgcolor = color_to_bbggrr(wptbgcolor); - return fsdata; + return fsdata; } void ozi_get_time_str(const waypoint *waypointp, char *buff, gbsize_t buffsz) { - if (waypointp->creation_time) { - double time = (waypt_time(waypointp) / SECONDS_PER_DAY) + DAYS_SINCE_1990; - snprintf(buff, buffsz, "%.7f", time); - } - else *buff = '\0'; + if (waypointp->creation_time) { + double time = (waypt_time(waypointp) / SECONDS_PER_DAY) + DAYS_SINCE_1990; + snprintf(buff, buffsz, "%.7f", time); + } else { + *buff = '\0'; + } } void ozi_set_time_str(const char *str, waypoint *waypointp) { - double ozi_time; - char *dot; - int len; - - ozi_time = atof(str); - waypointp->creation_time = (ozi_time - DAYS_SINCE_1990) * SECONDS_PER_DAY; - - dot = strchr(str, '.'); - /* get number of characters after dot */ - len = (dot) ? strlen(str) - (dot - str) - 1 : 0; - if (len >= 7) { - /* with default ozi time precision (%.7f) we can only handle tenths of second */ - ozi_time -= ((double)waypointp->creation_time / SECONDS_PER_DAY ) + DAYS_SINCE_1990; - ozi_time *= SECONDS_PER_DAY; - waypointp->microseconds = (ozi_time * 10) + 0.5; - if (waypointp->microseconds == 10) { - waypointp->creation_time++; - waypointp->microseconds = 0; - } - waypointp->microseconds *= 100000; - } + double ozi_time; + char *dot; + int len; + + ozi_time = atof(str); + waypointp->creation_time = (ozi_time - DAYS_SINCE_1990) * SECONDS_PER_DAY; + + dot = strchr(str, '.'); + /* get number of characters after dot */ + len = (dot) ? strlen(str) - (dot - str) - 1 : 0; + if (len >= 7) { + /* with default ozi time precision (%.7f) we can only handle tenths of second */ + ozi_time -= ((double)waypointp->creation_time / SECONDS_PER_DAY) + DAYS_SINCE_1990; + ozi_time *= SECONDS_PER_DAY; + waypointp->microseconds = (ozi_time * 10) + 0.5; + if (waypointp->microseconds == 10) { + waypointp->creation_time++; + waypointp->microseconds = 0; + } + waypointp->microseconds *= 100000; + } } static void ozi_convert_datum(waypoint *wpt) { - if (datum != DATUM_WGS84) { - double lat, lon, alt; - GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, 0.0, - &lat, &lon, &alt, datum); - wpt->latitude = lat; - wpt->longitude = lon; - } + if (datum != DATUM_WGS84) { + double lat, lon, alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, 0.0, + &lat, &lon, &alt, datum); + wpt->latitude = lat; + wpt->longitude = lon; + } } static void -ozi_openfile(char *fname) { - char *c, *cx, *tmpname; - char *ozi_extensions[] = {0, "plt", "wpt", "rte"}; - char buff[32]; - - /* if we're doing multi-track output, sequence the filenames like: - * mytrack.plt, mytrack-1.plt...unless we're writing to stdout. - */ - - if (0 == strcmp(fname, "-")) { - if (! file_out) { - file_out = gbfopen(fname, "wb", MYNAME); - } - return; - } +ozi_openfile(char *fname) +{ + char *c, *cx, *tmpname; + char *ozi_extensions[] = {0, "plt", "wpt", "rte"}; + char buff[32]; - if ((track_out_count) && (ozi_objective == trkdata)) { - sprintf(buff, "-%d", track_out_count); - } else { - buff[0] = '\0'; - } + /* if we're doing multi-track output, sequence the filenames like: + * mytrack.plt, mytrack-1.plt...unless we're writing to stdout. + */ - /* remove extension and add buff + ozi's extension */ - c = strrchr(fname, '.'); - if (c && (cx = strrchr(fname, '/')) && (cx > c)) c = NULL; - if (c && (cx = strrchr(fname, '\\')) && (cx > c)) c = NULL; - if (c == NULL) c = fname + strlen(fname); - xasprintf(&tmpname, "%*.*s%s.%s", c - fname, c - fname, fname, buff, ozi_extensions[ozi_objective]); - - /* re-open file_out with the new filename */ - if (file_out) { - gbfclose(file_out); - file_out = NULL; + if (0 == strcmp(fname, "-")) { + if (! file_out) { + file_out = gbfopen(fname, "wb", MYNAME); } + return; + } + + if ((track_out_count) && (ozi_objective == trkdata)) { + sprintf(buff, "-%d", track_out_count); + } else { + buff[0] = '\0'; + } + + /* remove extension and add buff + ozi's extension */ + c = strrchr(fname, '.'); + if (c && (cx = strrchr(fname, '/')) && (cx > c)) { + c = NULL; + } + if (c && (cx = strrchr(fname, '\\')) && (cx > c)) { + c = NULL; + } + if (c == NULL) { + c = fname + strlen(fname); + } + xasprintf(&tmpname, "%*.*s%s.%s", c - fname, c - fname, fname, buff, ozi_extensions[ozi_objective]); + + /* re-open file_out with the new filename */ + if (file_out) { + gbfclose(file_out); + file_out = NULL; + } - file_out = gbfopen(tmpname, "wb", MYNAME); + file_out = gbfopen(tmpname, "wb", MYNAME); - xfree(tmpname); + xfree(tmpname); - return; + return; } -static void +static void ozi_track_hdr(const route_head * rte) { - static char *ozi_trk_header = - "OziExplorer Track Point File Version 2.1\r\n" - "WGS 84\r\n" - "Altitude is in %s\r\n" - "Reserved 3\r\n" - "0,2,255,%s,0,0,2,8421376\r\n" - "0\r\n"; - - if ((! pack_opt) || (track_out_count == 0)) { - ozi_openfile(ozi_ofname); - gbfprintf(file_out, ozi_trk_header, - altunit == 'f' ? "Feet" : "Meters", - rte->rte_name ? rte->rte_name : "ComplimentsOfGPSBabel"); - } - - track_out_count++; - new_track = 1; + static char *ozi_trk_header = + "OziExplorer Track Point File Version 2.1\r\n" + "WGS 84\r\n" + "Altitude is in %s\r\n" + "Reserved 3\r\n" + "0,2,255,%s,0,0,2,8421376\r\n" + "0\r\n"; + + if ((! pack_opt) || (track_out_count == 0)) { + ozi_openfile(ozi_ofname); + gbfprintf(file_out, ozi_trk_header, + altunit == 'f' ? "Feet" : "Meters", + rte->rte_name ? rte->rte_name : "ComplimentsOfGPSBabel"); + } + + track_out_count++; + new_track = 1; } -static void +static void ozi_track_disp(const waypoint * waypointp) { - double alt; - char ozi_time[16]; + double alt; + char ozi_time[16]; - ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); + ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); - if (waypointp->altitude == unknown_alt) { - alt = -777; - } else { - alt = waypointp->altitude * alt_scale; - } + if (waypointp->altitude == unknown_alt) { + alt = -777; + } else { + alt = waypointp->altitude * alt_scale; + } - gbfprintf(file_out, "%.6f,%.6f,%d,%.0f,%s,,\r\n", - waypointp->latitude, waypointp->longitude, new_track, - alt, ozi_time); + gbfprintf(file_out, "%.6f,%.6f,%d,%.0f,%s,,\r\n", + waypointp->latitude, waypointp->longitude, new_track, + alt, ozi_time); - new_track = 0; + new_track = 0; } static void @@ -266,86 +294,86 @@ ozi_track_tlr(const route_head * rte) { } -static void +static void ozi_track_pr() { - track_disp_all(ozi_track_hdr, ozi_track_tlr, ozi_track_disp); + track_disp_all(ozi_track_hdr, ozi_track_tlr, ozi_track_disp); } static void ozi_route_hdr(const route_head * rte) { - static char *ozi_route_header = - "OziExplorer Route File Version 1.0\r\n" - "WGS 84\r\n" - "Reserved 1\r\n" - "Reserved 2\r\n"; - - /* prologue on 1st pass only */ - if (route_out_count == 0) { - gbfprintf(file_out, ozi_route_header); - } - - route_out_count++; - route_wpt_count = 0; - - /* - * Route Record - * Field 1 : R - indicating route details - * Field 2 : Number - this is the location in the array, must be unique, usually start at 0 for Garmins 1 for other and increment. - * Field 3 : Name - the waypoint name, use the correct length name to suit the GPS type. - * Field 4 : Description. - * Field 5 : Route Color as displayed on map (RGB). - * - * R, 0,R0 ,,255 - * R, 1, ICP GALHETA,, 16711680 - */ - - gbfprintf(file_out, "R,%d,%s,%s,\r\n", - route_out_count, - rte->rte_name ? rte->rte_name : "", - rte->rte_desc ? rte->rte_desc : ""); + static char *ozi_route_header = + "OziExplorer Route File Version 1.0\r\n" + "WGS 84\r\n" + "Reserved 1\r\n" + "Reserved 2\r\n"; + + /* prologue on 1st pass only */ + if (route_out_count == 0) { + gbfprintf(file_out, ozi_route_header); + } + + route_out_count++; + route_wpt_count = 0; + + /* + * Route Record + * Field 1 : R - indicating route details + * Field 2 : Number - this is the location in the array, must be unique, usually start at 0 for Garmins 1 for other and increment. + * Field 3 : Name - the waypoint name, use the correct length name to suit the GPS type. + * Field 4 : Description. + * Field 5 : Route Color as displayed on map (RGB). + * + * R, 0,R0 ,,255 + * R, 1, ICP GALHETA,, 16711680 + */ + + gbfprintf(file_out, "R,%d,%s,%s,\r\n", + route_out_count, + rte->rte_name ? rte->rte_name : "", + rte->rte_desc ? rte->rte_desc : ""); } static void ozi_route_disp(const waypoint * waypointp) { - double alt; - char ozi_time[16]; - - route_wpt_count++; - - ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); - - if (waypointp->altitude == unknown_alt) { - alt = -777; - } else { - alt = waypointp->altitude * alt_scale; - } - -/* - * Field 1 : W - indicating route waypoint details. - * Field 2 : Route Number - location in array of routes - * Field 3 : Number - this is the location in the array of route waypoints, this field is now ignored. - * Field 4 : Wp Number - this is the number of the waypoint (the Wp number within the GPS for lowrances) - * Field 5 : Name - the waypoint name, use the correct length name to suit the GPS type. - * Field 6 : Latitude - decimal degrees. - * Field 7 : Longitude - decimal degrees. - * Field 8 : Date - see Date Format below, if blank a preset date will be used - * Field 9 : Symbol - 0 to number of symbols in GPS - * Field 10 : Status - always set to 1 - * Field 11 : Map Display Format - * Field 12 : Foreground Color (RGB value) - * Field 13 : Background Color (RGB value) - * Field 14 : Description (max 40), no commas - * Field 15 : Pointer Direction - * Field 16 : Garmin Display Format - * - * W,1,7,7,007,-25.581670,-48.316660,36564.54196,10,1,4,0,65535,TR ILHA GALHETA,0,0 - */ - - gbfprintf(file_out, "W,%d,%d,,%s,%.6f,%.6f,%s,0,1,3,0,65535,%s,0,0\r\n", + double alt; + char ozi_time[16]; + + route_wpt_count++; + + ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); + + if (waypointp->altitude == unknown_alt) { + alt = -777; + } else { + alt = waypointp->altitude * alt_scale; + } + + /* + * Field 1 : W - indicating route waypoint details. + * Field 2 : Route Number - location in array of routes + * Field 3 : Number - this is the location in the array of route waypoints, this field is now ignored. + * Field 4 : Wp Number - this is the number of the waypoint (the Wp number within the GPS for lowrances) + * Field 5 : Name - the waypoint name, use the correct length name to suit the GPS type. + * Field 6 : Latitude - decimal degrees. + * Field 7 : Longitude - decimal degrees. + * Field 8 : Date - see Date Format below, if blank a preset date will be used + * Field 9 : Symbol - 0 to number of symbols in GPS + * Field 10 : Status - always set to 1 + * Field 11 : Map Display Format + * Field 12 : Foreground Color (RGB value) + * Field 13 : Background Color (RGB value) + * Field 14 : Description (max 40), no commas + * Field 15 : Pointer Direction + * Field 16 : Garmin Display Format + * + * W,1,7,7,007,-25.581670,-48.316660,36564.54196,10,1,4,0,65535,TR ILHA GALHETA,0,0 + */ + + gbfprintf(file_out, "W,%d,%d,,%s,%.6f,%.6f,%s,0,1,3,0,65535,%s,0,0\r\n", route_out_count, route_wpt_count, waypointp->shortname ? waypointp->shortname : "", @@ -361,577 +389,604 @@ ozi_route_tlr(const route_head * rte) { } -static void +static void ozi_route_pr() { - route_disp_all(ozi_route_hdr, ozi_route_tlr, ozi_route_disp); + route_disp_all(ozi_route_hdr, ozi_route_tlr, ozi_route_disp); } static void ozi_init_units(const int direction) /* 0 = in; 1 = out */ { - altunit = tolower(*altunit_opt); - switch(altunit) { - case 'm': /* meters, okay */ alt_scale = 1.0; break; - case 'f': /* feet, okay */ alt_scale = FEET_TO_METERS(1.0); break; - default: - fatal(MYNAME ": Unknown value (%s) for option 'altunit'!\n", altunit_opt); - } - if (direction != 0) alt_scale = 1 / alt_scale; - - proxunit = tolower(*proxunit_opt); - switch(proxunit) { - case 'm': /* miles, okay */ prox_scale = MILES_TO_METERS(1.0); break; - case 'n': /* nautical miles, okay */ prox_scale = NMILES_TO_METERS(1.0); break; - case 'k': /* kilometers, okay */ prox_scale = 1000.0; break; - default: - fatal(MYNAME ": Unknown value (%s) for option 'proxunit'!\n", proxunit_opt); - } - if (direction != 0) prox_scale = 1 / prox_scale; + altunit = tolower(*altunit_opt); + switch (altunit) { + case 'm': /* meters, okay */ + alt_scale = 1.0; + break; + case 'f': /* feet, okay */ + alt_scale = FEET_TO_METERS(1.0); + break; + default: + fatal(MYNAME ": Unknown value (%s) for option 'altunit'!\n", altunit_opt); + } + if (direction != 0) { + alt_scale = 1 / alt_scale; + } + + proxunit = tolower(*proxunit_opt); + switch (proxunit) { + case 'm': /* miles, okay */ + prox_scale = MILES_TO_METERS(1.0); + break; + case 'n': /* nautical miles, okay */ + prox_scale = NMILES_TO_METERS(1.0); + break; + case 'k': /* kilometers, okay */ + prox_scale = 1000.0; + break; + default: + fatal(MYNAME ": Unknown value (%s) for option 'proxunit'!\n", proxunit_opt); + } + if (direction != 0) { + prox_scale = 1 / prox_scale; + } } static void rd_init(const char *fname) { - file_in = gbfopen(fname, "rb", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); - mkshort_handle = mkshort_new_handle(); - ozi_init_units(0); + mkshort_handle = mkshort_new_handle(); + ozi_init_units(0); } static void rd_deinit(void) { - gbfclose(file_in); - file_in = NULL; - mkshort_del_handle(&mkshort_handle); + gbfclose(file_in); + file_in = NULL; + mkshort_del_handle(&mkshort_handle); } static void wr_init(const char *fname) { - - /* At this point, we have no idea whether we'll be writing waypoint, - * route, or tracks. So we'll hold off opening any files until - * we're actually ready to write. - */ - ozi_ofname = (char *)fname; + /* At this point, we have no idea whether we'll be writing waypoint, + * route, or tracks. So we'll hold off opening any files until + * we're actually ready to write. + */ - mkshort_handle = mkshort_new_handle(); + ozi_ofname = (char *)fname; - /* set mkshort options from the command line if applicable */ - if (global_opts.synthesize_shortnames) { + mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, atoi(snlenopt)); + /* set mkshort options from the command line if applicable */ + if (global_opts.synthesize_shortnames) { - if (snwhiteopt) - setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + setshort_length(mkshort_handle, atoi(snlenopt)); - if (snupperopt) - setshort_mustupper(mkshort_handle, atoi(snupperopt)); + if (snwhiteopt) { + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + } - if (snuniqueopt) - setshort_mustuniq(mkshort_handle, atoi(snuniqueopt)); + if (snupperopt) { + setshort_mustupper(mkshort_handle, atoi(snupperopt)); + } - setshort_badchars(mkshort_handle, "\","); + if (snuniqueopt) { + setshort_mustuniq(mkshort_handle, atoi(snuniqueopt)); } - ozi_init_units(1); - parse_distance(proximityarg, &proximity, 1 / prox_scale, MYNAME); + setshort_badchars(mkshort_handle, "\","); + } - file_out = NULL; + ozi_init_units(1); + parse_distance(proximityarg, &proximity, 1 / prox_scale, MYNAME); + + file_out = NULL; } static void wr_deinit(void) { - if (file_out != NULL) { - - gbfclose(file_out); - file_out = NULL; - } - ozi_ofname = NULL; + if (file_out != NULL) { + + gbfclose(file_out); + file_out = NULL; + } + ozi_ofname = NULL; - mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_handle); } static void ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp, ozi_fsdata *fsdata) { - double alt; - - if (*str == '\0') return; + double alt; - switch (field) { - case 0: - /* sequence # */ - break; - case 1: - /* waypoint name */ - wpt_tmp->shortname = csv_stringtrim(str, "", 0); - break; - case 2: - /* degrees latitude */ - wpt_tmp->latitude = atof(str); - break; - case 3: - /* degrees longitude */ - wpt_tmp->longitude = atof(str); - break; - case 4: - /* DAYS since 1900 00:00:00 in days.days (5.5) */ - ozi_set_time_str(str, wpt_tmp); - break; - case 5: - /* icons 0-xx. Ozi seems to use some kind of internal tables to - pick numbers for icons based on GPS type. We don't know what those - tables are, so we read just the numbers. This converts badly to - other types, but it at least maintains fidelity for an ozi->ozi - operation. */ - if (str && isdigit(str[0])) { - wpt_tmp->icon_descr = xstrdup(str); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - } - break; - case 6: - /* unknown - always 1 */ - break; - case 7: - /* display format options 0-8 */ - break; - case 8: - /* foreground color (0=black) */ - fsdata->fgcolor = atoi(str); - break; - case 9: - /* background color (65535=yellow) */ - fsdata->bgcolor = atoi(str); - break; - case 10: - /* Description */ - wpt_tmp->description = csv_stringtrim(str, "", 0); - break; - case 11: - /* pointer direction 0,1,2,3 bottom,top,left,right */ - break; - case 12: - /* garmin gps display flags (0-name w/sym, 1-sym only, 2-comment w/symbol */ - break; - case 13: - /* proximity distance - meters */ - WAYPT_SET(wpt_tmp, proximity, atof(str) * prox_scale); - break; - case 14: - /* altitude */ - alt = atof(str); - if (alt == -777) { - wpt_tmp->altitude = unknown_alt; - } else { - wpt_tmp->altitude = alt * alt_scale; - } - break; - case 15: - /* waypoint text name size */ - break; - case 16: - /* bold checkbox (1=bold, default 0) */ - break; - case 17: - /* symbol size - 17 default */ - break; - /* - * Fields 18-23 were added around version 3.90.4g of - * Ozi, but aren't documented. We silently ignore - * these or any additional fields we don't need. - */ - default: - break; + if (*str == '\0') { + return; + } + + switch (field) { + case 0: + /* sequence # */ + break; + case 1: + /* waypoint name */ + wpt_tmp->shortname = csv_stringtrim(str, "", 0); + break; + case 2: + /* degrees latitude */ + wpt_tmp->latitude = atof(str); + break; + case 3: + /* degrees longitude */ + wpt_tmp->longitude = atof(str); + break; + case 4: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + case 5: + /* icons 0-xx. Ozi seems to use some kind of internal tables to + pick numbers for icons based on GPS type. We don't know what those + tables are, so we read just the numbers. This converts badly to + other types, but it at least maintains fidelity for an ozi->ozi + operation. */ + if (str && isdigit(str[0])) { + wpt_tmp->icon_descr = xstrdup(str); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + } + break; + case 6: + /* unknown - always 1 */ + break; + case 7: + /* display format options 0-8 */ + break; + case 8: + /* foreground color (0=black) */ + fsdata->fgcolor = atoi(str); + break; + case 9: + /* background color (65535=yellow) */ + fsdata->bgcolor = atoi(str); + break; + case 10: + /* Description */ + wpt_tmp->description = csv_stringtrim(str, "", 0); + break; + case 11: + /* pointer direction 0,1,2,3 bottom,top,left,right */ + break; + case 12: + /* garmin gps display flags (0-name w/sym, 1-sym only, 2-comment w/symbol */ + break; + case 13: + /* proximity distance - meters */ + WAYPT_SET(wpt_tmp, proximity, atof(str) * prox_scale); + break; + case 14: + /* altitude */ + alt = atof(str); + if (alt == -777) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = alt * alt_scale; } + break; + case 15: + /* waypoint text name size */ + break; + case 16: + /* bold checkbox (1=bold, default 0) */ + break; + case 17: + /* symbol size - 17 default */ + break; + /* + * Fields 18-23 were added around version 3.90.4g of + * Ozi, but aren't documented. We silently ignore + * these or any additional fields we don't need. + */ + default: + break; + } } static void ozi_parse_track(int field, char *str, waypoint * wpt_tmp, char *trk_name) { - double alt; - - if (*str == '\0') return; - - switch (field) { - case 0: - /* latitude */ - wpt_tmp->latitude = atof(str); - break; - case 1: - /* longitude */ - wpt_tmp->longitude = atof(str); - break; - case 2: - /* new track flag */ - if ((atoi(str) == 1) && (trk_head->rte_waypt_ct > 0)) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - if (trk_name) - trk_head->rte_name = trk_name; - } - break; - case 3: - /* altitude */ - alt = atof(str); - if (alt == -777) { - wpt_tmp->altitude = unknown_alt; - } else { - wpt_tmp->altitude = alt * alt_scale; - } - break; - case 4: - /* DAYS since 1900 00:00:00 in days.days (5.5) */ - ozi_set_time_str(str, wpt_tmp); - break; - default: - break; + double alt; + + if (*str == '\0') { + return; + } + + switch (field) { + case 0: + /* latitude */ + wpt_tmp->latitude = atof(str); + break; + case 1: + /* longitude */ + wpt_tmp->longitude = atof(str); + break; + case 2: + /* new track flag */ + if ((atoi(str) == 1) && (trk_head->rte_waypt_ct > 0)) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + if (trk_name) { + trk_head->rte_name = trk_name; + } + } + break; + case 3: + /* altitude */ + alt = atof(str); + if (alt == -777) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = alt * alt_scale; } + break; + case 4: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + default: + break; + } } static void ozi_parse_routepoint(int field, char *str, waypoint * wpt_tmp) { - if (*str == '\0') return; - - switch (field) { - case 0: - /* W */ - break; - case 1: - /* route # */ - break; - case 2: - /* waypoint # -- ignored by ozi */ - break; - case 3: - /* waypoint # */ - break; - case 4: - /* waypoint name */ - wpt_tmp->shortname = csv_stringclean(str, ","); - break; - case 5: - /* latitude */ - wpt_tmp->latitude = atof(str); - break; - case 6: - /* longitude */ - wpt_tmp->longitude = atof(str); - break; - case 7: - /* DAYS since 1900 00:00:00 in days.days (5.5) */ - ozi_set_time_str(str, wpt_tmp); - break; - case 8: - /* symbol */ - break; - case 9: - /* status */ - break; - case 10: - /* map display format */ - break; - case 11: - /* foreground color (RGB) */ - break; - case 12: - /* background color (RGB) */ - break; - case 13: - /* description */ - wpt_tmp->description = csv_stringclean(str, ","); - break; - default: - break; - } + if (*str == '\0') { + return; + } + + switch (field) { + case 0: + /* W */ + break; + case 1: + /* route # */ + break; + case 2: + /* waypoint # -- ignored by ozi */ + break; + case 3: + /* waypoint # */ + break; + case 4: + /* waypoint name */ + wpt_tmp->shortname = csv_stringclean(str, ","); + break; + case 5: + /* latitude */ + wpt_tmp->latitude = atof(str); + break; + case 6: + /* longitude */ + wpt_tmp->longitude = atof(str); + break; + case 7: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + case 8: + /* symbol */ + break; + case 9: + /* status */ + break; + case 10: + /* map display format */ + break; + case 11: + /* foreground color (RGB) */ + break; + case 12: + /* background color (RGB) */ + break; + case 13: + /* description */ + wpt_tmp->description = csv_stringclean(str, ","); + break; + default: + break; + } } static void ozi_parse_routeheader(int field, char *str, waypoint * wpt_tmp) { - switch (field) { - case 0: - /* R */ - rte_head = route_head_alloc(); - route_add_head(rte_head); - break; - case 1: - /* route # */ - rte_head->rte_num = atoi(str); - break; - case 2: - /* route name */ - rte_head->rte_name = csv_stringclean(str, ","); - break; - case 3: - /* route description */ - rte_head->rte_desc = csv_stringclean(str, ","); - break; - case 4: - /* route color */ - break; - default: - break; - } + switch (field) { + case 0: + /* R */ + rte_head = route_head_alloc(); + route_add_head(rte_head); + break; + case 1: + /* route # */ + rte_head->rte_num = atoi(str); + break; + case 2: + /* route name */ + rte_head->rte_name = csv_stringclean(str, ","); + break; + case 3: + /* route description */ + rte_head->rte_desc = csv_stringclean(str, ","); + break; + case 4: + /* route color */ + break; + default: + break; + } } static void data_read(void) { - char *buff; - char *s = NULL; - char *trk_name = NULL; - waypoint *wpt_tmp; - int i; - int linecount = 0; - - while ((buff = gbfgetstr(file_in))) { - - if ((linecount++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - /* - * this is particularly nasty. use the first line of the file - * to attempt to divine the data type we are parsing - */ - if (linecount == 1) { - if (strstr(buff, "Track Point") != NULL) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - ozi_objective = trkdata; - } else - if (strstr(buff, "Route File") != NULL) { - ozi_objective = rtedata; - } else { - ozi_objective = wptdata; - } + char *buff; + char *s = NULL; + char *trk_name = NULL; + waypoint *wpt_tmp; + int i; + int linecount = 0; + + while ((buff = gbfgetstr(file_in))) { + + if ((linecount++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + /* + * this is particularly nasty. use the first line of the file + * to attempt to divine the data type we are parsing + */ + if (linecount == 1) { + if (strstr(buff, "Track Point") != NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + ozi_objective = trkdata; + } else if (strstr(buff, "Route File") != NULL) { + ozi_objective = rtedata; + } else { + ozi_objective = wptdata; + } + } else if (linecount == 2) { + datum = GPS_Lookup_Datum_Index(buff); + if (datum < 0) { + fatal(MYNAME ": Unsupported datum '%s'.\n", buff); + } + } else if (linecount == 3) { + if (case_ignore_strncmp(buff, "Altitude is in ", 15) == 0) { + char *unit = &buff[15]; + if (case_ignore_strncmp(unit, "Feet", 4) == 0) { + altunit = 'f'; + alt_scale = FEET_TO_METERS(1.0); + } else if (case_ignore_strncmp(unit, "Meter", 5) == 0) { + altunit = 'm'; + alt_scale = 1.0; + } else { + fatal(MYNAME ": Unknown unit (%s) used by altitude values!\n", unit); } - else if (linecount == 2) { - datum = GPS_Lookup_Datum_Index(buff); - if (datum < 0) { - fatal(MYNAME ": Unsupported datum '%s'.\n", buff); - } - } - else if (linecount == 3) { - if (case_ignore_strncmp(buff, "Altitude is in ", 15) == 0) { - char *unit = &buff[15]; - if (case_ignore_strncmp(unit, "Feet", 4) == 0) { - altunit = 'f'; - alt_scale = FEET_TO_METERS(1.0); - } - else if (case_ignore_strncmp(unit, "Meter", 5) == 0) { - altunit = 'm'; - alt_scale = 1.0; - } - else fatal(MYNAME ": Unknown unit (%s) used by altitude values!\n", unit); - } - } else if ((linecount == 5) && (ozi_objective == trkdata)) { - int field = 0; - s = csv_lineparse(buff, ",", "", linecount); - while (s) { - field ++; - if (field == 4) { - trk_head->rte_name = xstrdup(lrtrim(s)); - } - s = csv_lineparse(NULL, ",", "", linecount); - } - } - - if ((strlen(buff)) && (strstr(buff, ",") != NULL)) { - ozi_fsdata *fsdata = ozi_alloc_fsdata(); - wpt_tmp = waypt_new(); - - /* data delimited by commas, possibly enclosed in quotes. */ - s = buff; - s = csv_lineparse(s, ",", "", linecount); - - i = 0; - while (s) { - switch (ozi_objective) { - case trkdata: - ozi_parse_track(i, s, wpt_tmp, trk_name); - break; - case rtedata: - if (buff[0] == 'R') { - ozi_parse_routeheader(i, s, wpt_tmp); - } else { - ozi_parse_routepoint(i, s, wpt_tmp); - } - - break; - case wptdata: - ozi_parse_waypt(i, s, wpt_tmp, fsdata); - break; - case posndata: - fatal(MYNAME ": realtime positioning not supported.\n"); - break; - } - i++; - s = csv_lineparse(NULL, ",", "", linecount); - } - - switch (ozi_objective) { - case trkdata: - if (linecount > 6) {/* skipping over file header */ - ozi_convert_datum(wpt_tmp); - track_add_wpt(trk_head, wpt_tmp); - } - else - waypt_free(wpt_tmp); - break; - case rtedata: - if (linecount > 5) {/* skipping over file header */ - ozi_convert_datum(wpt_tmp); - route_add_wpt(rte_head, wpt_tmp); - } - else - waypt_free(wpt_tmp); - break; - case wptdata: - if (linecount > 4) { /* skipping over file header */ - fs_chain_add(&(wpt_tmp->fs), - (format_specific_data *) fsdata); - ozi_convert_datum(wpt_tmp); - waypt_add(wpt_tmp); - } else { - waypt_free(wpt_tmp); - } - break; - case posndata: - fatal(MYNAME ": realtime positioning not supported.\n"); - break; - } + } + } else if ((linecount == 5) && (ozi_objective == trkdata)) { + int field = 0; + s = csv_lineparse(buff, ",", "", linecount); + while (s) { + field ++; + if (field == 4) { + trk_head->rte_name = xstrdup(lrtrim(s)); + } + s = csv_lineparse(NULL, ",", "", linecount); + } + } + if ((strlen(buff)) && (strstr(buff, ",") != NULL)) { + ozi_fsdata *fsdata = ozi_alloc_fsdata(); + wpt_tmp = waypt_new(); + + /* data delimited by commas, possibly enclosed in quotes. */ + s = buff; + s = csv_lineparse(s, ",", "", linecount); + + i = 0; + while (s) { + switch (ozi_objective) { + case trkdata: + ozi_parse_track(i, s, wpt_tmp, trk_name); + break; + case rtedata: + if (buff[0] == 'R') { + ozi_parse_routeheader(i, s, wpt_tmp); + } else { + ozi_parse_routepoint(i, s, wpt_tmp); + } + + break; + case wptdata: + case unknown_gpsdata: + ozi_parse_waypt(i, s, wpt_tmp, fsdata); + break; + case posndata: + fatal(MYNAME ": realtime positioning not supported.\n"); + break; + } + i++; + s = csv_lineparse(NULL, ",", "", linecount); + } + + switch (ozi_objective) { + case trkdata: + if (linecount > 6) {/* skipping over file header */ + ozi_convert_datum(wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); } else { - /* empty line */ + waypt_free(wpt_tmp); } + break; + case rtedata: + if (linecount > 5) {/* skipping over file header */ + ozi_convert_datum(wpt_tmp); + route_add_wpt(rte_head, wpt_tmp); + } else { + waypt_free(wpt_tmp); + } + break; + case wptdata: + case unknown_gpsdata: + if (linecount > 4) { /* skipping over file header */ + fs_chain_add(&(wpt_tmp->fs), + (format_specific_data *) fsdata); + ozi_convert_datum(wpt_tmp); + waypt_add(wpt_tmp); + } else { + waypt_free(wpt_tmp); + } + break; + case posndata: + fatal(MYNAME ": realtime positioning not supported.\n"); + break; + } + } else { + /* empty line */ } + + } } static void ozi_waypt_pr(const waypoint * wpt) { - static int index = 0; - double alt; - char ozi_time[16]; - char *description; - char *shortname; - int faked_fsdata = 0; - ozi_fsdata *fs = NULL; - int icon = 0; - - fs = (ozi_fsdata *) fs_chain_find(wpt->fs, FS_OZI); - - if (!fs) { - fs = ozi_alloc_fsdata(); - faked_fsdata = 1; - } - - ozi_get_time_str(wpt, ozi_time, sizeof(ozi_time)); - - if (wpt->altitude == unknown_alt) { - alt = -777; - } else { - alt = wpt->altitude * alt_scale; - } - - if ((!wpt->shortname) || (global_opts.synthesize_shortnames)) { - if (wpt->description) { - if (global_opts.synthesize_shortnames) - shortname = mkshort_from_wpt(mkshort_handle, wpt); - else - shortname = csv_stringclean(wpt->description, BADCHARS); - } else { - /* no description available */ - shortname = xstrdup(""); - } + static int index = 0; + double alt; + char ozi_time[16]; + char *description; + char *shortname; + int faked_fsdata = 0; + ozi_fsdata *fs = NULL; + int icon = 0; + + fs = (ozi_fsdata *) fs_chain_find(wpt->fs, FS_OZI); + + if (!fs) { + fs = ozi_alloc_fsdata(); + faked_fsdata = 1; + } + + ozi_get_time_str(wpt, ozi_time, sizeof(ozi_time)); + + if (wpt->altitude == unknown_alt) { + alt = -777; + } else { + alt = wpt->altitude * alt_scale; + } + + if ((!wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) { + shortname = mkshort_from_wpt(mkshort_handle, wpt); + } else { + shortname = csv_stringclean(wpt->description, BADCHARS); + } } else { - shortname = csv_stringclean(wpt->shortname, BADCHARS); + /* no description available */ + shortname = xstrdup(""); } + } else { + shortname = csv_stringclean(wpt->shortname, BADCHARS); + } - if (!wpt->description) { - if (shortname) { - description = csv_stringclean(shortname, BADCHARS); - } else { - description = xstrdup(""); - } + if (!wpt->description) { + if (shortname) { + description = csv_stringclean(shortname, BADCHARS); } else { - description = csv_stringclean(wpt->description, BADCHARS); + description = xstrdup(""); } + } else { + description = csv_stringclean(wpt->description, BADCHARS); + } - index++; + index++; - if(wpt->icon_descr && isdigit(wpt->icon_descr[0])) { - icon = atoi(wpt->icon_descr); - } + if (wpt->icon_descr && isdigit(wpt->icon_descr[0])) { + icon = atoi(wpt->icon_descr); + } - gbfprintf(file_out, + gbfprintf(file_out, "%d,%s,%.6f,%.6f,%s,%d,%d,%d,%d,%d,%s,%d,%d,", index, shortname, wpt->latitude, wpt->longitude, ozi_time, icon, 1, 3, fs->fgcolor, fs->bgcolor, description, 0, 0); - if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) - gbfprintf(file_out, "%.1f,", wpt->proximity * prox_scale); - else if (proximity > 0) - gbfprintf(file_out,"%.1f,", proximity * prox_scale); - else - gbfprintf(file_out,"%d,", 0); - gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt, 6, 0, 17); - - xfree(description); - xfree(shortname); - - if (faked_fsdata) { - xfree(fs); - } + if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) { + gbfprintf(file_out, "%.1f,", wpt->proximity * prox_scale); + } else if (proximity > 0) { + gbfprintf(file_out,"%.1f,", proximity * prox_scale); + } else { + gbfprintf(file_out,"%d,", 0); + } + gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt, 6, 0, 17); + + xfree(description); + xfree(shortname); + + if (faked_fsdata) { + xfree(fs); + } } static void data_write(void) { - static char *ozi_wpt_header = - "OziExplorer Waypoint File Version 1.1\r\n" - "WGS 84\r\n" - "Reserved 2\r\n" - "Reserved 3\r\n"; - - track_out_count = route_out_count = 0; - - if (waypt_count()) { - ozi_objective = wptdata; - ozi_openfile(ozi_ofname); - gbfprintf(file_out, ozi_wpt_header); - waypt_disp_all(ozi_waypt_pr); - } - - if (track_count()) { - ozi_objective = trkdata; - ozi_track_pr(); /* ozi_track_hdr handles filenames / file_out */ - } - - if (route_count()) { - ozi_objective = rtedata; - ozi_openfile(ozi_ofname); /* ozi routes go in one big file */ - ozi_route_pr(); - } + static char *ozi_wpt_header = + "OziExplorer Waypoint File Version 1.1\r\n" + "WGS 84\r\n" + "Reserved 2\r\n" + "Reserved 3\r\n"; + + track_out_count = route_out_count = 0; + + if (waypt_count()) { + ozi_objective = wptdata; + ozi_openfile(ozi_ofname); + gbfprintf(file_out, ozi_wpt_header); + waypt_disp_all(ozi_waypt_pr); + } + + if (track_count()) { + ozi_objective = trkdata; + ozi_track_pr(); /* ozi_track_hdr handles filenames / file_out */ + } + + if (route_count()) { + ozi_objective = rtedata; + ozi_openfile(ozi_ofname); /* ozi routes go in one big file */ + ozi_route_pr(); + } } ff_vecs_t ozi_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - ozi_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + ozi_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/palmdoc.c b/gpsbabel/palmdoc.c index e8c083a12..4fa0a8f25 100644 --- a/gpsbabel/palmdoc.c +++ b/gpsbabel/palmdoc.c @@ -56,543 +56,561 @@ static char *palm_encrypt; #define UNCOMPRESSED 1 struct buffer { - unsigned char *data; - unsigned len; + unsigned char *data; + unsigned len; }; #define NEW_BUFFER(b) (b)->data = (unsigned char *)xmalloc( ((b)->len = 0,BUFFER_SIZE) ) static arglist_t palmdoc_args[] = { - { "nosep", &suppresssep, - "No separator lines between waypoints", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"encrypt", &palm_encrypt, "Encrypt hints with ROT13", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logs", &includelogs, - "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "bookmarks_short", &bmid, "Include short name in bookmarks", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "nosep", &suppresssep, + "No separator lines between waypoints", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { + "encrypt", &palm_encrypt, "Encrypt hints with ROT13", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logs", &includelogs, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "bookmarks_short", &bmid, "Include short name in bookmarks", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static struct buffer buf; -struct doc_record0 /* 16 bytes total */ -{ - gbuint16 version; /* 1 = plain text, 2 = compressed */ - gbuint16 reserved1; - gbuint32 doc_size; /* in bytes, when uncompressed */ - gbuint16 num_records; /* PDB header numRecords - 1 */ - gbuint16 rec_size; /* usually RECORD_SIZE_MAX */ - gbuint32 reserved2; - gbuint16 recsizes[1]; +struct doc_record0 { /* 16 bytes total */ + gbuint16 version; /* 1 = plain text, 2 = compressed */ + gbuint16 reserved1; + gbuint32 doc_size; /* in bytes, when uncompressed */ + gbuint16 num_records; /* PDB header numRecords - 1 */ + gbuint16 rec_size; /* usually RECORD_SIZE_MAX */ + gbuint32 reserved2; + gbuint16 recsizes[1]; }; static struct recordsize { - int size; - struct recordsize *next; + int size; + struct recordsize *next; } *recordsize_tail; static struct bookmark { - int offset; - char *text; - struct bookmark *next; + int offset; + char *text; + struct bookmark *next; } *bookmark_tail; struct bookmark_record { - char text[16]; - gbuint32 offset; + char text[16]; + gbuint32 offset; }; static void put_byte(struct buffer *b, unsigned char c, int *space) { - if ( *space ) { - *space = 0; - /* - ** There is an outstanding space char: see if we can squeeze it - ** in with an ASCII char. - */ - if ( c >= 0x40 && c <= 0x7F ) { - b->data[ b->len++ ] = c ^ 0x80; - return; - } - b->data[ b->len++ ] = ' '; /* couldn't squeeze it in */ - } else if ( c == ' ' ) { - *space = 1; - return; - } - - if ( (c >= 1 && c <= 8) || c >= 0x80 ) - b->data[ b->len++ ] = '\1'; - - b->data[ b->len++ ] = c; + if (*space) { + *space = 0; + /* + ** There is an outstanding space char: see if we can squeeze it + ** in with an ASCII char. + */ + if (c >= 0x40 && c <= 0x7F) { + b->data[ b->len++ ] = c ^ 0x80; + return; + } + b->data[ b->len++ ] = ' '; /* couldn't squeeze it in */ + } else if (c == ' ') { + *space = 1; + return; + } + + if ((c >= 1 && c <= 8) || c >= 0x80) { + b->data[ b->len++ ] = '\1'; + } + + b->data[ b->len++ ] = c; } static unsigned char * mem_find(unsigned char *t, int t_len, unsigned char *m, int m_len) { - register int i; - for ( i = t_len - m_len + 1; i > 0; --i, ++t ) - if ( *t == *m && !memcmp( t, m, m_len ) ) - return t; - return 0; + register int i; + for (i = t_len - m_len + 1; i > 0; --i, ++t) + if (*t == *m && !memcmp(t, m, m_len)) { + return t; + } + return 0; } -static void pd_compress( struct buffer *b ) +static void pd_compress(struct buffer *b) { - unsigned i, j; - int space = 0; - - unsigned char *buf_orig; - unsigned char *p; /* walking test hit; works up on successive matches */ - unsigned char *p_prev; - unsigned char *head; /* current test string */ - unsigned char *tail; /* 1 past the current test buffer */ - unsigned char *end; /* 1 past the end of the input buffer */ - - p = p_prev = head = buf_orig = b->data; - tail = head + 1; - end = b->data + b->len; - - NEW_BUFFER( b ); - b->len = 0; - - /* loop, absorbing one more char from the input buffer on each pass */ - while ( head != end ) { - /* establish where the scan can begin */ - if ( head - p_prev > (( 1 << DISP_BITS )-1) ) - p_prev = head - (( 1 << DISP_BITS )-1); - - /* scan in the previous data for a match */ - p = mem_find( p_prev, tail - p_prev, head, tail - head ); - - /* on a mismatch or end of buffer, issued codes */ - if ( !p || p == head || tail - head > ( 1 << COUNT_BITS ) + 2 - || tail == end - ) { - /* issued the codes */ - /* first, check for short runs */ - if ( tail - head < 4 ) { - put_byte( b, *head++, &space ); - } - else { - unsigned dist = head - p_prev; - unsigned compound = (dist << COUNT_BITS) - + tail - head - 4; - - /* for longer runs, issue a run-code */ - /* issue space char if required */ - if ( space ) { - b->data[ b->len++ ] = ' '; - space = 0; - } - - b->data[ b->len++ ] = 0x80 + ( compound >> 8 ); - b->data[ b->len++ ] = compound & 0xFF; - head = tail - 1;/* and start again */ - } - p_prev = buf_orig; /* start search again */ - } else - p_prev = p; /* got a match */ - - /* when we get to the end of the buffer, don't inc past the */ - /* end; this forces the residue chars out one at a time */ - if ( tail != end ) - ++tail; - } - xfree( buf_orig ); - - if ( space ) - b->data[ b->len++ ] = ' '; /* add left-over space */ - - /* final scan to merge consecutive high chars together */ - for ( i = j = 0; i < b->len; ++i, ++j ) { - b->data[ j ] = b->data[ i ]; - - /* skip run-length codes */ - if ( b->data[ j ] >= 0x80 && b->data[ j ] < 0xC0 ) - b->data[ ++j ] = b->data[ ++i ]; - - /* if we hit a high char marker, look ahead for another */ - else if ( b->data[ j ] == '\1' ) { - b->data[ j + 1 ] = b->data[ i + 1 ]; - while ( i + 2 < b->len && - b->data[ i + 2 ] == 1 && b->data[ j ] < 8 - ) { - b->data[ j ]++; - b->data[ j + b->data[ j ] ] = b->data[ i + 3 ]; - i += 2; - } - j += b->data[ j ]; - ++i; - } - } - b->len = j; + unsigned i, j; + int space = 0; + + unsigned char *buf_orig; + unsigned char *p; /* walking test hit; works up on successive matches */ + unsigned char *p_prev; + unsigned char *head; /* current test string */ + unsigned char *tail; /* 1 past the current test buffer */ + unsigned char *end; /* 1 past the end of the input buffer */ + + p = p_prev = head = buf_orig = b->data; + tail = head + 1; + end = b->data + b->len; + + NEW_BUFFER(b); + b->len = 0; + + /* loop, absorbing one more char from the input buffer on each pass */ + while (head != end) { + /* establish where the scan can begin */ + if (head - p_prev > ((1 << DISP_BITS)-1)) { + p_prev = head - ((1 << DISP_BITS)-1); + } + + /* scan in the previous data for a match */ + p = mem_find(p_prev, tail - p_prev, head, tail - head); + + /* on a mismatch or end of buffer, issued codes */ + if (!p || p == head || tail - head > (1 << COUNT_BITS) + 2 + || tail == end + ) { + /* issued the codes */ + /* first, check for short runs */ + if (tail - head < 4) { + put_byte(b, *head++, &space); + } else { + unsigned dist = head - p_prev; + unsigned compound = (dist << COUNT_BITS) + + tail - head - 4; + + /* for longer runs, issue a run-code */ + /* issue space char if required */ + if (space) { + b->data[ b->len++ ] = ' '; + space = 0; + } + + b->data[ b->len++ ] = 0x80 + (compound >> 8); + b->data[ b->len++ ] = compound & 0xFF; + head = tail - 1;/* and start again */ + } + p_prev = buf_orig; /* start search again */ + } else { + p_prev = p; /* got a match */ + } + + /* when we get to the end of the buffer, don't inc past the */ + /* end; this forces the residue chars out one at a time */ + if (tail != end) { + ++tail; + } + } + xfree(buf_orig); + + if (space) { + b->data[ b->len++ ] = ' '; /* add left-over space */ + } + + /* final scan to merge consecutive high chars together */ + for (i = j = 0; i < b->len; ++i, ++j) { + b->data[ j ] = b->data[ i ]; + + /* skip run-length codes */ + if (b->data[ j ] >= 0x80 && b->data[ j ] < 0xC0) { + b->data[ ++j ] = b->data[ ++i ]; + } + + /* if we hit a high char marker, look ahead for another */ + else if (b->data[ j ] == '\1') { + b->data[ j + 1 ] = b->data[ i + 1 ]; + while (i + 2 < b->len && + b->data[ i + 2 ] == 1 && b->data[ j ] < 8 + ) { + b->data[ j ]++; + b->data[ j + b->data[ j ] ] = b->data[ i + 3 ]; + i += 2; + } + j += b->data[ j ]; + ++i; + } + } + b->len = j; } -static void write_header( void ) { - - int recs = ct-1; - struct doc_record0 *rec0; - --ct; - - rec0 = xcalloc( 1, sizeof(struct doc_record0)+(ct-1)*sizeof(short)); - be_write16( &rec0->version, COMPRESSED ); - be_write16( &rec0->reserved1, 0 ); - be_write32( &rec0->doc_size, offset ); - be_write16( &rec0->num_records, ct ); - be_write16( &rec0->rec_size, 4096 ); - be_write32( &rec0->reserved2, 0 ); - while ( recs ) { - struct recordsize *oldrec = recordsize_tail; - be_write16( &rec0->recsizes[recs], oldrec->size ); - recordsize_tail = oldrec->next; - xfree( oldrec ); - --recs; - } - - pdb_write_rec(file_out, 0, 0, 0, (void *)rec0, sizeof(struct doc_record0) + sizeof(short)*(ct-1)); - - xfree(rec0); +static void write_header(void) +{ + + int recs = ct-1; + struct doc_record0 *rec0; + --ct; + + rec0 = (struct doc_record0*) xcalloc(1, sizeof(struct doc_record0)+(ct-1)*sizeof(short)); + be_write16(&rec0->version, COMPRESSED); + be_write16(&rec0->reserved1, 0); + be_write32(&rec0->doc_size, offset); + be_write16(&rec0->num_records, ct); + be_write16(&rec0->rec_size, 4096); + be_write32(&rec0->reserved2, 0); + while (recs) { + struct recordsize *oldrec = recordsize_tail; + be_write16(&rec0->recsizes[recs], oldrec->size); + recordsize_tail = oldrec->next; + xfree(oldrec); + --recs; + } + + pdb_write_rec(file_out, 0, 0, 0, (void *)rec0, sizeof(struct doc_record0) + sizeof(short)*(ct-1)); + + xfree(rec0); } -static void write_bookmarks( void ) { - struct bookmark *oldmark = NULL; - struct bookmark_record rec; - - struct bookmark *newtail = NULL; - - /* reverse the bookmark list */ - while ( bookmark_tail ) { - oldmark = bookmark_tail; - bookmark_tail = oldmark->next; - oldmark->next = newtail; - newtail = oldmark; - } - bookmark_tail = newtail; - - ct++; - while ( bookmark_tail ) { - oldmark = bookmark_tail; - bookmark_tail = oldmark->next; - - be_write32( &rec.offset, oldmark->offset ); - memset( rec.text, 0, 16 ); - strncpy( rec.text, oldmark->text, 16 ); - - pdb_write_rec(file_out, 0, 0, ct++, (void *)&rec, sizeof(struct bookmark_record)); - - xfree( oldmark ); - } +static void write_bookmarks(void) +{ + struct bookmark *oldmark = NULL; + struct bookmark_record rec; + + struct bookmark *newtail = NULL; + + /* reverse the bookmark list */ + while (bookmark_tail) { + oldmark = bookmark_tail; + bookmark_tail = oldmark->next; + oldmark->next = newtail; + newtail = oldmark; + } + bookmark_tail = newtail; + + ct++; + while (bookmark_tail) { + oldmark = bookmark_tail; + bookmark_tail = oldmark->next; + + be_write32(&rec.offset, oldmark->offset); + memset(rec.text, 0, 16); + strncpy(rec.text, oldmark->text, 16); + + pdb_write_rec(file_out, 0, 0, ct++, (void *)&rec, sizeof(struct bookmark_record)); + + xfree(oldmark); + } } -static void commit_buffer( void ) { +static void commit_buffer(void) +{ + + struct recordsize *newrec = (struct recordsize*) xcalloc(1, sizeof(struct recordsize)); + newrec->next = recordsize_tail; + newrec->size = buf.len; + recordsize_tail = newrec; - struct recordsize *newrec = xcalloc( 1, sizeof(struct recordsize)); - newrec->next = recordsize_tail; - newrec->size = buf.len; - recordsize_tail = newrec; + pd_compress(&buf); - pd_compress( &buf ); - - pdb_write_rec(file_out, 0, 0, ct++, (void *)buf.data, buf.len); + pdb_write_rec(file_out, 0, 0, ct++, (void *)buf.data, buf.len); } -static void create_bookmark( char *bmtext ) { - struct bookmark *newmark = (struct bookmark *) xcalloc( 1, sizeof(struct bookmark)); - newmark->next = bookmark_tail; - newmark->offset = offset; - newmark->text = bmtext; - bookmark_tail = newmark; -} - -static void docprintf( int maxlen, const char *format, ... ) { - - char *txt = NULL; - char *txt2 = NULL; - va_list list; - int newlen; - int partlen; - - txt = (char *) xmalloc( maxlen ); - - va_start( list, format ); - newlen = vsprintf( txt, format, list ); - - txt2 = txt; - offset += newlen; - while (txt2 && *txt2 ) { - /* append to buffer what we can */ - partlen = BUFFER_SIZE-1-buf.len; - if ( buf.len + newlen + 1 > BUFFER_SIZE ) - { - strncpy( (char *) buf.data+buf.len, txt2, partlen ); - buf.data[BUFFER_SIZE-1] = '\0'; - txt2 += partlen; - newlen -= partlen; - buf.len = BUFFER_SIZE-1; - commit_buffer(); - NEW_BUFFER( &buf ); - } - else { - strcpy( (char *) buf.data+buf.len, txt2 ); - buf.len += newlen; - txt2 = NULL; - } +static void create_bookmark(char *bmtext) +{ + struct bookmark *newmark = (struct bookmark *) xcalloc(1, sizeof(struct bookmark)); + newmark->next = bookmark_tail; + newmark->offset = offset; + newmark->text = bmtext; + bookmark_tail = newmark; +} + +static void docprintf(int maxlen, const char *format, ...) +{ + + char *txt = NULL; + char *txt2 = NULL; + va_list list; + int newlen; + int partlen; + + txt = (char *) xmalloc(maxlen); + + va_start(list, format); + newlen = vsprintf(txt, format, list); + + txt2 = txt; + offset += newlen; + while (txt2 && *txt2) { + /* append to buffer what we can */ + partlen = BUFFER_SIZE-1-buf.len; + if (buf.len + newlen + 1 > BUFFER_SIZE) { + strncpy((char *) buf.data+buf.len, txt2, partlen); + buf.data[BUFFER_SIZE-1] = '\0'; + txt2 += partlen; + newlen -= partlen; + buf.len = BUFFER_SIZE-1; + commit_buffer(); + NEW_BUFFER(&buf); + } else { + strcpy((char *) buf.data+buf.len, txt2); + buf.len += newlen; + txt2 = NULL; } - - xfree( txt ); + } + + xfree(txt); } -static void docfinish() { - commit_buffer(); - write_header(); - write_bookmarks(); +static void docfinish() +{ + commit_buffer(); + write_header(); + write_bookmarks(); } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - - mkshort_handle = mkshort_new_handle(); - mkshort_bookmark_handle = mkshort_new_handle(); - ct = 1; - offset = 1; - recordsize_tail = NULL; - bookmark_tail = NULL; - NEW_BUFFER( &buf ); + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + + mkshort_handle = mkshort_new_handle(); + mkshort_bookmark_handle = mkshort_new_handle(); + ct = 1; + offset = 1; + recordsize_tail = NULL; + bookmark_tail = NULL; + NEW_BUFFER(&buf); } static void wr_deinit(void) { - pdb_close(file_out); - mkshort_del_handle(&mkshort_handle); - mkshort_del_handle(&mkshort_bookmark_handle); - - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_bookmark_handle); + + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void palmdoc_disp(const waypoint *wpt) { - int latint, lonint; - char tbuf[1024]; - time_t tm = wpt->creation_time; - int32 utmz; - double utme, utmn; - char utmzc; - char *bm; - fs_xml *fs_gpx = NULL; - - char bookmarktext[17]; - - if ( bmid ) { - char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); - sprintf( bookmarktext, "%6s:%9s", - wpt->shortname?wpt->shortname:"",s); - xfree(s); - } - else { - char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); - sprintf( bookmarktext, "%16s", s); - xfree(s); - } - - bm = xstrdup(bookmarktext); - create_bookmark(bm); - - lonint = abs((int) wpt->longitude); - latint = abs((int) wpt->latitude); - - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - - if (tm == 0) - tm = time(NULL); - strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); - - docprintf(300, "%-16s %c%d %06.3f %c%d %06.3f (%d%c %6.0f %7.0f)", - (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, - wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), - wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint), - utmz, utmzc, utme, utmn); - if (wpt->altitude != unknown_alt) - docprintf (100, " alt: %1.1f", wpt->altitude); - docprintf (10, "\n"); - if (strcmp(wpt->description, wpt->shortname)) { - docprintf(10+strlen(wpt->description), "%s\n", wpt->description); - } - if (wpt->gc_data->terr) { - - docprintf (100, "%s/%s\n", gs_get_cachetype(wpt->gc_data->type), - gs_get_container(wpt->gc_data->container)); - - if (wpt->gc_data->desc_short.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_short); - docprintf (10+strlen(stripped_html), "\n%s\n", stripped_html); - xfree(stripped_html); - } - if (wpt->gc_data->desc_long.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_long); - docprintf (10+strlen(stripped_html), "\n%s\n", stripped_html); - xfree(stripped_html); - } - if (wpt->gc_data->hint) { - char *hint = NULL; - if ( palm_encrypt ) - hint = rot13( wpt->gc_data->hint ); - else - hint = xstrdup( wpt->gc_data->hint ); - docprintf (10+strlen(hint), "\nHint: %s\n", hint); - xfree( hint ); - } - } - else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { - docprintf (10+strlen(wpt->notes), "%s\n", wpt->notes); - } - - fs_gpx = NULL; - if ( includelogs ) { - fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX); - } - - if ( fs_gpx && fs_gpx->tag ) { - xml_tag *root = fs_gpx->tag; - xml_tag *curlog = NULL; - xml_tag *logpart = NULL; - curlog = xml_findfirst( root, "groundspeak:log" ); - while ( curlog ) { - time_t logtime = 0; - struct tm *logtm = NULL; - docprintf( 10, "\n" ); - - logpart = xml_findfirst( curlog, "groundspeak:type" ); - if ( logpart ) { - docprintf( 10+strlen(logpart->cdata), "%s by ", logpart->cdata ); - } - - logpart = xml_findfirst( curlog, "groundspeak:finder" ); - if ( logpart ) { - docprintf( 10+strlen(logpart->cdata), "%s on ", logpart->cdata ); - } - - logpart = xml_findfirst( curlog, "groundspeak:date" ); - if ( logpart ) { - logtime = xml_parse_time( logpart->cdata, NULL); - logtm = localtime( &logtime ); - if ( logtm ) { - docprintf( 15, - "%2.2d/%2.2d/%4.4d\n", - logtm->tm_mon+1, - logtm->tm_mday, - logtm->tm_year+1900 - ); - } - } - - logpart = xml_findfirst( curlog, "groundspeak:log_wpt" ); - if ( logpart ) { - char *coordstr = NULL; - float lat = 0; - int latdeg = 0; - float lon = 0; - int londeg = 0; - coordstr = xml_attribute( logpart, "lat" ); - if ( coordstr ) { - lat = atof( coordstr ); - } - coordstr = xml_attribute( logpart, "lon" ); - if ( coordstr ) { - lon = atof( coordstr ); - } - latdeg = abs(lat); - londeg = abs(lon); - - docprintf( 30, - "%c %d\xb0 %.3f' %c %d\xb0 %.3f'\n", - - lat < 0 ? 'S' : 'N', latdeg, 60.0 * (fabs(lat) - latdeg), - lon < 0 ? 'W' : 'E', londeg, 60.0 * (fabs(lon) - londeg) - ); - } - - logpart = xml_findfirst( curlog, "groundspeak:text" ); - if ( logpart ) { - char *encstr = NULL; - char *s = NULL; - int encoded = 0; - encstr = xml_attribute( logpart, "encoded" ); - encoded = (encstr[0] != 'F'); - - if ( palm_encrypt && encoded ) { - s = rot13( logpart->cdata ); - } - else { - s = xstrdup( logpart->cdata ); - } - - docprintf( 5+strlen(s), "%s", s ); - xfree( s ); - } - - docprintf( 10, "\n" ); - curlog = xml_findnext( root, curlog, "groundspeak:log" ); - } - } - if (! suppresssep) - docprintf(50, "---------------------------\n"); - else - docprintf(10, "\n"); + int latint, lonint; + char tbuf[1024]; + time_t tm = wpt->creation_time; + int32 utmz; + double utme, utmn; + char utmzc; + char *bm; + fs_xml *fs_gpx = NULL; + + char bookmarktext[17]; + + if (bmid) { + char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); + sprintf(bookmarktext, "%6s:%9s", + wpt->shortname?wpt->shortname:"",s); + xfree(s); + } else { + char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); + sprintf(bookmarktext, "%16s", s); + xfree(s); + } + + bm = xstrdup(bookmarktext); + create_bookmark(bm); + + lonint = abs((int) wpt->longitude); + latint = abs((int) wpt->latitude); + + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + + if (tm == 0) { + tm = time(NULL); + } + strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); + + docprintf(300, "%-16s %c%d %06.3f %c%d %06.3f (%d%c %6.0f %7.0f)", + (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, + wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), + wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint), + utmz, utmzc, utme, utmn); + if (wpt->altitude != unknown_alt) { + docprintf(100, " alt: %1.1f", wpt->altitude); + } + docprintf(10, "\n"); + if (strcmp(wpt->description, wpt->shortname)) { + docprintf(10+strlen(wpt->description), "%s\n", wpt->description); + } + if (wpt->gc_data->terr) { + + docprintf(100, "%s/%s\n", gs_get_cachetype(wpt->gc_data->type), + gs_get_container(wpt->gc_data->container)); + + if (wpt->gc_data->desc_short.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data->desc_short); + docprintf(10+strlen(stripped_html), "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data->desc_long.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data->desc_long); + docprintf(10+strlen(stripped_html), "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data->hint) { + char *hint = NULL; + if (palm_encrypt) { + hint = rot13(wpt->gc_data->hint); + } else { + hint = xstrdup(wpt->gc_data->hint); + } + docprintf(10+strlen(hint), "\nHint: %s\n", hint); + xfree(hint); + } + } else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { + docprintf(10+strlen(wpt->notes), "%s\n", wpt->notes); + } + + fs_gpx = NULL; + if (includelogs) { + fs_gpx = (fs_xml *)fs_chain_find(wpt->fs, FS_GPX); + } + + if (fs_gpx && fs_gpx->tag) { + xml_tag *root = fs_gpx->tag; + xml_tag *curlog = NULL; + xml_tag *logpart = NULL; + curlog = xml_findfirst(root, "groundspeak:log"); + while (curlog) { + time_t logtime = 0; + struct tm *logtm = NULL; + docprintf(10, "\n"); + + logpart = xml_findfirst(curlog, "groundspeak:type"); + if (logpart) { + docprintf(10+strlen(logpart->cdata), "%s by ", logpart->cdata); + } + + logpart = xml_findfirst(curlog, "groundspeak:finder"); + if (logpart) { + docprintf(10+strlen(logpart->cdata), "%s on ", logpart->cdata); + } + + logpart = xml_findfirst(curlog, "groundspeak:date"); + if (logpart) { + logtime = xml_parse_time(logpart->cdata, NULL); + logtm = localtime(&logtime); + if (logtm) { + docprintf(15, + "%2.2d/%2.2d/%4.4d\n", + logtm->tm_mon+1, + logtm->tm_mday, + logtm->tm_year+1900 + ); + } + } + + logpart = xml_findfirst(curlog, "groundspeak:log_wpt"); + if (logpart) { + char *coordstr = NULL; + float lat = 0; + int latdeg = 0; + float lon = 0; + int londeg = 0; + coordstr = xml_attribute(logpart, "lat"); + if (coordstr) { + lat = atof(coordstr); + } + coordstr = xml_attribute(logpart, "lon"); + if (coordstr) { + lon = atof(coordstr); + } + latdeg = abs(lat); + londeg = abs(lon); + + docprintf(30, + "%c %d\xb0 %.3f' %c %d\xb0 %.3f'\n", + + lat < 0 ? 'S' : 'N', latdeg, 60.0 * (fabs(lat) - latdeg), + lon < 0 ? 'W' : 'E', londeg, 60.0 * (fabs(lon) - londeg) + ); + } + + logpart = xml_findfirst(curlog, "groundspeak:text"); + if (logpart) { + char *encstr = NULL; + char *s = NULL; + int encoded = 0; + encstr = xml_attribute(logpart, "encoded"); + encoded = (toupper(encstr[0]) != 'F'); + + if (palm_encrypt && encoded) { + s = rot13(logpart->cdata); + } else { + s = xstrdup(logpart->cdata); + } + + docprintf(5+strlen(s), "%s", s); + xfree(s); + } + + docprintf(10, "\n"); + curlog = xml_findnext(root, curlog, "groundspeak:log"); + } + } + if (! suppresssep) { + docprintf(50, "---------------------------\n"); + } else { + docprintf(10, "\n"); + } } static void data_write(void) { - if ( dbname ) { - strncpy( file_out->name, dbname, PDB_DBNAMELEN ); - } - else { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - } - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = DOC_TYPE; - file_out->creator = DOC_CREATOR; - file_out->version = 1; - - if (! suppresssep) - docprintf(50, "---------------------------\n"); - setshort_length(mkshort_handle, 20 ); - setshort_length(mkshort_bookmark_handle, 16-(bmid?7:0)); - setshort_whitespace_ok( mkshort_bookmark_handle, 0 ); - waypt_disp_all(palmdoc_disp); - - docfinish(); + if (dbname) { + strncpy(file_out->name, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = DOC_TYPE; + file_out->creator = DOC_CREATOR; + file_out->version = 1; + + if (! suppresssep) { + docprintf(50, "---------------------------\n"); + } + setshort_length(mkshort_handle, 20); + setshort_length(mkshort_bookmark_handle, 16-(bmid?7:0)); + setshort_whitespace_ok(mkshort_bookmark_handle, 0); + waypt_disp_all(palmdoc_disp); + + docfinish(); } ff_vecs_t palmdoc_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_none, ff_cap_none}, - NULL, - wr_init, - NULL, - wr_deinit, - NULL, - data_write, - NULL, - palmdoc_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none}, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + palmdoc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/parse.c b/gpsbabel/parse.c index 9b49b8b32..46807a4f3 100644 --- a/gpsbabel/parse.c +++ b/gpsbabel/parse.c @@ -42,36 +42,49 @@ int parse_distance(const char *str, double *val, double scale, const char *module) { - char *unit; - - if ((str == NULL) || (*str == '\0')) return 0; - - *val = strtod(str, &unit); - if (unit == NULL) - fatal("%s: Unconvertable numeric value (%s)!\n", module, str); - - if (fabs(*val) + 1 >= 1.0e25) { - return 0; /* not only Garmin uses this as 'unknown value' */ - } - - while (isspace(*unit)) unit++; - - if (*unit == '\0') { - *val *= scale; - return 1; - } - - if (case_ignore_strcmp(unit, "m") == 0) /* do nothing, that's our standard */; - else if (case_ignore_strcmp(unit, "ft") == 0) *val = FEET_TO_METERS(*val); - else if (case_ignore_strcmp(unit, "feet") == 0) *val = FEET_TO_METERS(*val); - else if (case_ignore_strcmp(unit, "k") == 0) *val *= 1000.0; - else if (case_ignore_strcmp(unit, "km") == 0) *val *= 1000.0; - else if (case_ignore_strcmp(unit, "nm") == 0) *val = NMILES_TO_METERS(*val); - else if (case_ignore_strcmp(unit, "mi") == 0) *val = MILES_TO_METERS(*val); - else if (case_ignore_strcmp(unit, "fa") == 0) *val = FATHOMS_TO_METERS(*val); - else - fatal("%s: Unsupported distance unit in item '%s'!\n", module, str); - return 2; + char *unit; + + if ((str == NULL) || (*str == '\0')) { + return 0; + } + + *val = strtod(str, &unit); + if (unit == NULL) { + fatal("%s: Unconvertable numeric value (%s)!\n", module, str); + } + + if (fabs(*val) + 1 >= 1.0e25) { + return 0; /* not only Garmin uses this as 'unknown value' */ + } + + while (isspace(*unit)) { + unit++; + } + + if (*unit == '\0') { + *val *= scale; + return 1; + } + + if (case_ignore_strcmp(unit, "m") == 0) /* do nothing, that's our standard */; + else if (case_ignore_strcmp(unit, "ft") == 0) { + *val = FEET_TO_METERS(*val); + } else if (case_ignore_strcmp(unit, "feet") == 0) { + *val = FEET_TO_METERS(*val); + } else if (case_ignore_strcmp(unit, "k") == 0) { + *val *= 1000.0; + } else if (case_ignore_strcmp(unit, "km") == 0) { + *val *= 1000.0; + } else if (case_ignore_strcmp(unit, "nm") == 0) { + *val = NMILES_TO_METERS(*val); + } else if (case_ignore_strcmp(unit, "mi") == 0) { + *val = MILES_TO_METERS(*val); + } else if (case_ignore_strcmp(unit, "fa") == 0) { + *val = FATHOMS_TO_METERS(*val); + } else { + fatal("%s: Unsupported distance unit in item '%s'!\n", module, str); + } + return 2; } /* @@ -85,38 +98,52 @@ parse_distance(const char *str, double *val, double scale, const char *module) int parse_speed(const char *str, double *val, const double scale, const char *module) { - char *unit; - - if ((str == NULL) || (*str == '\0')) return 0; - - *val = strtod(str, &unit); - if (unit == NULL) - fatal("%s: Unconvertable numeric value (%s)!\n", module, str); - - while (isspace(*unit)) unit++; - - if (*unit == '\0') { - *val *= scale; - return 1; - } - - if (case_ignore_strcmp(unit, "m/s") == 0) ; - else if (case_ignore_strcmp(unit, "mps") == 0) ; - else if (case_ignore_strcmp(unit, "kph") == 0) *val = KPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "km/h") == 0) *val = KPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "kmh") == 0) *val = KPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "kt") == 0) *val = KNOTS_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "knot") == 0) *val = KNOTS_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "mph") == 0) *val = MPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "mi/h") == 0) *val = MPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "mih") == 0) *val = MPH_TO_MPS(*val); - else - fatal("%s: Unsupported speed unit '%s' in item '%s'!\n", module, unit, str); - - return 2; + char *unit; + + if ((str == NULL) || (*str == '\0')) { + return 0; + } + + *val = strtod(str, &unit); + if (unit == NULL) { + fatal("%s: Unconvertable numeric value (%s)!\n", module, str); + } + + while (isspace(*unit)) { + unit++; + } + + if (*unit == '\0') { + *val *= scale; + return 1; + } + + if (case_ignore_strcmp(unit, "m/s") == 0) ; + else if (case_ignore_strcmp(unit, "mps") == 0) ; + else if (case_ignore_strcmp(unit, "kph") == 0) { + *val = KPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "km/h") == 0) { + *val = KPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "kmh") == 0) { + *val = KPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "kt") == 0) { + *val = KNOTS_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "knot") == 0) { + *val = KNOTS_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "mph") == 0) { + *val = MPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "mi/h") == 0) { + *val = MPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "mih") == 0) { + *val = MPH_TO_MPS(*val); + } else { + fatal("%s: Unsupported speed unit '%s' in item '%s'!\n", module, unit, str); + } + + return 2; } -/* +/* * Convert string 'str' into geodetic latitide & longitude values. The format * will be interpreted depending on 'grid' parameter. * @@ -124,168 +151,179 @@ parse_speed(const char *str, double *val, const double scale, const char *module */ int -parse_coordinates(const char *str, int datum, const grid_type grid, - double *latitude, double *longitude, const char *module) +parse_coordinates(const char *str, int datum, const grid_type grid, + double *latitude, double *longitude, const char *module) { - double lat, lon; - unsigned char lathemi, lonhemi; - int deg_lat, deg_lon, min_lat, min_lon; - char map[3]; - int utmz; - double utme, utmn; - char utmc; - int valid, result, ct; - double lx, ly; - const char *format; - - valid = 1; - - switch(grid) { - - case grid_lat_lon_ddd: - format = "%c%lf %c%lf%n"; - ct = sscanf(str, format, - &lathemi, &lat, &lonhemi, &lon, &result); - valid = (ct == 4); - break; - - case grid_lat_lon_dmm: - format = "%c%d %lf %c%d %lf%n"; - ct = sscanf(str, format, - &lathemi, °_lat, &lat, &lonhemi, °_lon, &lon, &result); - valid = (ct == 6); - if (valid) { - lat = (double)deg_lat + (lat / (double)60); - lon = (double)deg_lon + (lon / (double)60); - } - break; - - case grid_lat_lon_dms: - format = "%c%d %d %lf %c%d %d %lf%n"; - ct = sscanf(str, format, - &lathemi, °_lat, &min_lat, &lat, &lonhemi, °_lon, &min_lon, &lon, - &result); - valid = (ct == 8); - if (valid) { - lat = (double)deg_lat + ((double)min_lat / (double)60) + (lat / (double)3600.0); - lon = (double)deg_lon + ((double)min_lon / (double)60) + (lon / (double)3600.0); - } - break; - - case grid_bng: - datum = DATUM_WGS84; /* fix */ - format = "%2s %lf %lf%n"; - ct = sscanf(str, format, - map, &lx, &ly, - &result); - valid = (ct == 3); - if (valid) { - if (! GPS_Math_UKOSMap_To_WGS84_M(map, lx, ly, &lat, &lon)) - fatal("%s: Unable to convert BNG coordinates (%s)!\n", - module, str); - } - lathemi = lonhemi = '\0'; - break; - - case grid_utm: - format = "%d %c %lf %lf%n"; - ct = sscanf(str, format, - &utmz, &utmc, &utme, &utmn, - &result); - valid = (ct == 4); - if (valid) { - if (! GPS_Math_UTM_EN_To_Known_Datum(&lat, &lon, utme, utmn, utmz, utmc, datum)) - fatal("%s: Unable to convert UTM coordinates (%s)!\n", - module, str); - } - lathemi = lonhemi = '\0'; - break; - - case grid_swiss: { - double east, north; - - datum = DATUM_WGS84; /* fix */ - format = "%lf %lf%n"; - ct = sscanf(str, format, - &east, &north, &result); - valid = (ct == 2); - GPS_Math_Swiss_EN_To_WGS84(east, north, &lat, &lon); - break; - } - default: - /* this should never happen in a release version */ - fatal("%s/util: Unknown grid in parse_coordinates (%d)!\n", - module, (int)grid); - } - - if (! valid) { - warning("%s: sscanf error using format \"%s\"!\n", module, format); - warning("%s: parsing has stopped at parameter number %d.\n", module, ct); - fatal("%s: could not convert coordinates \"%s\"!\n", module, str); - } - - if (lathemi == 'S') lat = -lat; - if (lonhemi == 'W') lon = -lon; - - if (datum != DATUM_WGS84) { - double alt; - GPS_Math_Known_Datum_To_WGS84_M(lat, lon, (double) 0.0, - &lat, &lon, &alt, datum); - } - - if (latitude) *latitude = lat; - if (longitude) *longitude = lon; - - return result; + double lat, lon; + unsigned char lathemi, lonhemi; + int deg_lat, deg_lon, min_lat, min_lon; + char map[3]; + int utmz; + double utme, utmn; + char utmc; + int valid, result, ct; + double lx, ly; + const char *format; + + valid = 1; + + switch (grid) { + + case grid_lat_lon_ddd: + format = "%c%lf %c%lf%n"; + ct = sscanf(str, format, + &lathemi, &lat, &lonhemi, &lon, &result); + valid = (ct == 4); + break; + + case grid_lat_lon_dmm: + format = "%c%d %lf %c%d %lf%n"; + ct = sscanf(str, format, + &lathemi, °_lat, &lat, &lonhemi, °_lon, &lon, &result); + valid = (ct == 6); + if (valid) { + lat = (double)deg_lat + (lat / (double)60); + lon = (double)deg_lon + (lon / (double)60); + } + break; + + case grid_lat_lon_dms: + format = "%c%d %d %lf %c%d %d %lf%n"; + ct = sscanf(str, format, + &lathemi, °_lat, &min_lat, &lat, &lonhemi, °_lon, &min_lon, &lon, + &result); + valid = (ct == 8); + if (valid) { + lat = (double)deg_lat + ((double)min_lat / (double)60) + (lat / (double)3600.0); + lon = (double)deg_lon + ((double)min_lon / (double)60) + (lon / (double)3600.0); + } + break; + + case grid_bng: + datum = DATUM_WGS84; /* fix */ + format = "%2s %lf %lf%n"; + ct = sscanf(str, format, + map, &lx, &ly, + &result); + valid = (ct == 3); + if (valid) { + if (! GPS_Math_UKOSMap_To_WGS84_M(map, lx, ly, &lat, &lon)) + fatal("%s: Unable to convert BNG coordinates (%s)!\n", + module, str); + } + lathemi = lonhemi = '\0'; + break; + + case grid_utm: + format = "%d %c %lf %lf%n"; + ct = sscanf(str, format, + &utmz, &utmc, &utme, &utmn, + &result); + valid = (ct == 4); + if (valid) { + if (! GPS_Math_UTM_EN_To_Known_Datum(&lat, &lon, utme, utmn, utmz, utmc, datum)) + fatal("%s: Unable to convert UTM coordinates (%s)!\n", + module, str); + } + lathemi = lonhemi = '\0'; + break; + + case grid_swiss: { + double east, north; + + datum = DATUM_WGS84; /* fix */ + format = "%lf %lf%n"; + ct = sscanf(str, format, + &east, &north, &result); + valid = (ct == 2); + GPS_Math_Swiss_EN_To_WGS84(east, north, &lat, &lon); + break; + } + default: + /* this should never happen in a release version */ + fatal("%s/util: Unknown grid in parse_coordinates (%d)!\n", + module, (int)grid); + } + + if (! valid) { + warning("%s: sscanf error using format \"%s\"!\n", module, format); + warning("%s: parsing has stopped at parameter number %d.\n", module, ct); + fatal("%s: could not convert coordinates \"%s\"!\n", module, str); + } + + if (lathemi == 'S') { + lat = -lat; + } + if (lonhemi == 'W') { + lon = -lon; + } + + if (datum != DATUM_WGS84) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(lat, lon, (double) 0.0, + &lat, &lon, &alt, datum); + } + + if (latitude) { + *latitude = lat; + } + if (longitude) { + *longitude = lon; + } + + return result; } time_t parse_date(const char *str, const char *format, const char *module) { - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - if (format) { - char *cx = strptime(str, format, &tm); - if ((cx != NULL) && (*cx != '\0')) - fatal("%s: Could not parse date string (%s).\n", module, str); - } - else { - int p1, p2, p3, ct; - char sep[2]; - - ct = sscanf(str, "%d%1[-.//]%d%1[-.//]%d", &p1, sep, &p2, sep, &p3); - if (ct != 5) - fatal("%s: Could not parse date string (%s).\n", module, str); - - if ((p1 > 99) || (sep[0] == '-')) { /* Y-M-D (iso like) */ - tm.tm_year = p1; - tm.tm_mon = p2; - tm.tm_mday = p3; - } - else if (sep[0] == '.') { /* Germany and any other countries */ - tm.tm_mday = p1; /* have a fixed D.M.Y format */ - tm.tm_mon = p2; - tm.tm_year = p3; - } - else { - tm.tm_mday = p2; - tm.tm_mon = p1; - tm.tm_year = p3; - } - if ((p1 < 100) && (p2 < 100) && (p3 < 100)) { - if (tm.tm_year < 70) tm.tm_year += 2000; - else tm.tm_year += 1900; - } - /* some low-level checks */ - if ((tm.tm_mon > 12) || (tm.tm_mon < 1) || (tm.tm_mday > 31) || (tm.tm_mday < 1)) - fatal("%s: Could not parse date string (%s).\n", module, str); - - tm.tm_year -= 1900; - tm.tm_mon -= 1; - } - - return mkgmtime(&tm); + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + if (format) { + char *cx = strptime(str, format, &tm); + if ((cx != NULL) && (*cx != '\0')) { + fatal("%s: Could not parse date string (%s).\n", module, str); + } + } else { + int p1, p2, p3, ct; + char sep[2]; + + ct = sscanf(str, "%d%1[-.//]%d%1[-.//]%d", &p1, sep, &p2, sep, &p3); + if (ct != 5) { + fatal("%s: Could not parse date string (%s).\n", module, str); + } + + if ((p1 > 99) || (sep[0] == '-')) { /* Y-M-D (iso like) */ + tm.tm_year = p1; + tm.tm_mon = p2; + tm.tm_mday = p3; + } else if (sep[0] == '.') { /* Germany and any other countries */ + tm.tm_mday = p1; /* have a fixed D.M.Y format */ + tm.tm_mon = p2; + tm.tm_year = p3; + } else { + tm.tm_mday = p2; + tm.tm_mon = p1; + tm.tm_year = p3; + } + if ((p1 < 100) && (p2 < 100) && (p3 < 100)) { + if (tm.tm_year < 70) { + tm.tm_year += 2000; + } else { + tm.tm_year += 1900; + } + } + /* some low-level checks */ + if ((tm.tm_mon > 12) || (tm.tm_mon < 1) || (tm.tm_mday > 31) || (tm.tm_mday < 1)) { + fatal("%s: Could not parse date string (%s).\n", module, str); + } + + tm.tm_year -= 1900; + tm.tm_mon -= 1; + } + + return mkgmtime(&tm); } diff --git a/gpsbabel/pathaway.c b/gpsbabel/pathaway.c index 288314f3d..e88b3acaa 100644 --- a/gpsbabel/pathaway.c +++ b/gpsbabel/pathaway.c @@ -1,5 +1,5 @@ -/* - Support for PathAway Palm Database, +/* + Support for PathAway Palm Database, Copyright (C) 2005-2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -18,21 +18,21 @@ */ -/* +/* remarks: - + The german release 3.0 of PathAway violates the PathAway standards: * N.. .... O.. .... instead of N.. .... E.. .... * date is formatted in DDMMYYYY instead of YYYYMMDD Release 4.x store only numeric coordinates and uses a six-number date. - + Modified by by Andrei Boros 2008-11-07 - * added information about database vehicle icon - * Pathaway 4.x can handle invalid date/time and date format apparently - has changed slightly between revisions : + * added information about database vehicle icon + * Pathaway 4.x can handle invalid date/time and date format apparently + has changed slightly between revisions : 131502.29 26102008 = HHMMSS.MS DDMMYYYY - * work around errors reading date/time information + * work around errors reading date/time information (real life data collected by Pathaway sometimes has the date/time field contain some missing/invalid data. This information can be safely ignored most of the time. So far gpsbabel stopped processing files @@ -42,10 +42,10 @@ - date/time field may contain invalid characters -> ignore - invalid or missing date/time -> ignore - only time may be present (some older versions of Pathaway 4) - + (this is still incomplete, but solved most of my problems when converting pathaway .pdb files) - + */ #include @@ -72,33 +72,31 @@ static char *datefmt; static int ct; static int warn_ = 0; -typedef struct ppdb_appdata -{ - unsigned char reservedA[274]; /* all 0 */ - unsigned char dirtyFlag; - unsigned char dataBaseSubType; /* 0 = Track, 1 = Route */ - short int dbAttributes; /* 0 */ - char vehicleStr[VEHICLE_LEN]; - unsigned char reservedB[100]; /* all 0 */ +typedef struct ppdb_appdata { + unsigned char reservedA[274]; /* all 0 */ + unsigned char dirtyFlag; + unsigned char dataBaseSubType; /* 0 = Track, 1 = Route */ + short int dbAttributes; /* 0 */ + char vehicleStr[VEHICLE_LEN]; + unsigned char reservedB[100]; /* all 0 */ } ppdb_appdata_t; #define PPDB_APPINFO_SIZE sizeof(struct ppdb_appdata) static ppdb_appdata_t *appinfo; static char *opt_dbname = NULL; -static char *opt_dbicon = NULL; +static char *opt_dbicon = NULL; static char *opt_deficon = NULL; static char *opt_snlen = NULL; static char *opt_date = NULL; -static arglist_t ppdb_args[] = -{ - {"date", &opt_date, "Read/Write date format (i.e. DDMMYYYY)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"dbname", &opt_dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"dbicon", &opt_dbicon, "Database vehicle icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"snlen", &opt_snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR +static arglist_t ppdb_args[] = { + {"date", &opt_date, "Read/Write date format (i.e. DDMMYYYY)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"dbname", &opt_dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"dbicon", &opt_dbicon, "Database vehicle icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"snlen", &opt_snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR }; /*#undef PPDB_DEBUG*/ @@ -108,18 +106,18 @@ static arglist_t ppdb_args[] = static void internal_debug1(const char *filename, int fileline) { - static int ct=1; - printf("DBG(%d): file %s, line %d: ", ct++, filename, fileline); + static int ct=1; + printf("DBG(%d): file %s, line %d: ", ct++, filename, fileline); } static void -internal_debug2(const char *format, ... ) +internal_debug2(const char *format, ...) { - va_list args; + va_list args; - va_start(args, format); - vprintf(format, args); - puts(""); - va_end(args); + va_start(args, format); + vprintf(format, args); + puts(""); + va_end(args); } #define DBG(args) internal_debug1(__FILE__, __LINE__);internal_debug2 args #else @@ -136,27 +134,29 @@ internal_debug2(const char *format, ... ) static char *ppdb_strcat(char *dest, char *src, char *def, int *size) { - int len; - char *res, *tmp; - - tmp = src; - if (tmp == NULL) - { - tmp = def; - if (tmp == NULL) return dest; - } - if (*tmp == '\0') return dest; - - len = strlen(dest) + strlen(tmp) + 1; - if (len > *size) - { - *size = len; - res = xrealloc(dest, *size); - } - else - res = dest; - strcat(res, tmp); - return res; + int len; + char *res, *tmp; + + tmp = src; + if (tmp == NULL) { + tmp = def; + if (tmp == NULL) { + return dest; + } + } + if (*tmp == '\0') { + return dest; + } + + len = strlen(dest) + strlen(tmp) + 1; + if (len > *size) { + *size = len; + res = (char*) xrealloc(dest, *size); + } else { + res = dest; + } + strcat(res, tmp); + return res; } #define STR_POOL_SIZE 16 /* !!! any power of 2 !!! */ @@ -168,368 +168,341 @@ static int str_poolp = -1; static void str_pool_init(void) { - int i; - for (i = 0; i < STR_POOL_SIZE; i++) - { - str_pool[i] = NULL; - str_pool_s[i] = 0; - } + int i; + for (i = 0; i < STR_POOL_SIZE; i++) { + str_pool[i] = NULL; + str_pool_s[i] = 0; + } } static void str_pool_deinit(void) { - int i; - - for (i = 0; i < STR_POOL_SIZE; i++) - if ( str_pool_s[i] != 0 ) - { - xfree(str_pool[i]); - str_pool[i] = NULL; - str_pool_s[i] = 0; - } + int i; + + for (i = 0; i < STR_POOL_SIZE; i++) + if (str_pool_s[i] != 0) { + xfree(str_pool[i]); + str_pool[i] = NULL; + str_pool_s[i] = 0; + } } static char *str_pool_get(size_t size) { - char *tmp; - - str_poolp = ((str_poolp + 1) & (STR_POOL_SIZE - 1)); - tmp = str_pool[str_poolp]; - - if (str_pool_s[str_poolp] == 0) - tmp = xmalloc(size); - else if (str_pool_s[str_poolp] < size) - tmp = xrealloc(tmp, size); - else - return tmp; - - str_pool[str_poolp] = tmp; - str_pool_s[str_poolp] = size; - - return tmp; + char *tmp; + + str_poolp = ((str_poolp + 1) & (STR_POOL_SIZE - 1)); + tmp = str_pool[str_poolp]; + + if (str_pool_s[str_poolp] == 0) { + tmp = (char*) xmalloc(size); + } else if (str_pool_s[str_poolp] < size) { + tmp = (char*) xrealloc(tmp, size); + } else { + return tmp; + } + + str_pool[str_poolp] = tmp; + str_pool_s[str_poolp] = size; + + return tmp; } static char *str_pool_getcpy(const char *src, char *def) { - char *res; - - if (src == NULL) - { - src = def; - if (src == NULL) src = ""; - } - res = str_pool_get(strlen(src) + 1); - strcpy(res, src); - - return res; + char *res; + + if (src == NULL) { + src = def; + if (src == NULL) { + src = ""; + } + } + res = str_pool_get(strlen(src) + 1); + strcpy(res, src); + + return res; } /* * decoding/formatting functions */ - + static char *ppdb_fmt_float(const double val) { - char *str = str_pool_get(32); - char *c; - snprintf(str, 32, "%.8f", val); - c = str + strlen(str) - 1; - while ((c > str) && (*c == '0')) - { - *c = '\0'; - c--; - if (*c == '.') - { - c++; - *c = '0'; - break; - } - } - return str; + char *str = str_pool_get(32); + char *c; + snprintf(str, 32, "%.8f", val); + c = str + strlen(str) - 1; + while ((c > str) && (*c == '0')) { + *c = '\0'; + c--; + if (*c == '.') { + c++; + *c = '0'; + break; + } + } + return str; } static char *ppdb_fmt_degrees(char dir, double val) { - char *str = str_pool_get(32); - int deg = fabs(val); - double min = 60.0 * (fabs(val) - deg); - char *tmp; - - snprintf(str, 31, "%c%0*d %.8f", dir, (deg > 99) ? 3 : 2, deg, min); - - tmp = str + strlen(str) - 1; /* trim trailing nulls */ - while ((tmp > str) && (*tmp == '0')) - { - *tmp = '\0'; - tmp--; - if (*tmp == '.') - { - tmp++; - *tmp = '0'; - break; - } - } - return str; + char *str = str_pool_get(32); + int deg = fabs(val); + double min = 60.0 * (fabs(val) - deg); + char *tmp; + + snprintf(str, 31, "%c%0*d %.8f", dir, (deg > 99) ? 3 : 2, deg, min); + + tmp = str + strlen(str) - 1; /* trim trailing nulls */ + while ((tmp > str) && (*tmp == '0')) { + *tmp = '\0'; + tmp--; + if (*tmp == '.') { + tmp++; + *tmp = '0'; + break; + } + } + return str; } static double ppdb_decode_coord(const char *str) { - double val; - int deg; - char dir; - - if (*str < 'A') /* only numeric */ - { - CHECK_INP(1, sscanf(str,"%lf", &val), "decode_coord(1) DD.dddd", str); - return val; - } - else - { - char *tmp; - - if (*str == 'O') german_release = 1; - - tmp = strchr(str, ' '); - if ((tmp) && (tmp - str < 5)) - { - CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, °, &val), "decode_coord(2) DD MM.mmm", str); - val = deg + (val / 60.0); - } - else - { - CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val), "decode_coord(3) DD.dddd", str); - } - if ((dir == 'S') || (dir == 'W')) - val = -val; - } - return val; + double val; + int deg; + char dir; + + if (*str < 'A') { /* only numeric */ + CHECK_INP(1, sscanf(str,"%lf", &val), "decode_coord(1) DD.dddd", str); + return val; + } else { + char *tmp; + + if (*str == 'O') { + german_release = 1; + } + + tmp = strchr(str, ' '); + if ((tmp) && (tmp - str < 5)) { + CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, °, &val), "decode_coord(2) DD MM.mmm", str); + val = deg + (val / 60.0); + } else { + CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val), "decode_coord(3) DD.dddd", str); + } + if ((dir == 'S') || (dir == 'W')) { + val = -val; + } + } + return val; } static int ppdb_decode_tm(char *str, struct tm *tm) { - int msec, d1, d2, d3, d4; - int year; - int temp=0; - char *cx; - - str = lrtrim(str); /* time field may start/end with spaces, drop them */ - - if (*str == '\0') - { - if (global_opts.debug_level > 0) - { - warning(MYNAME ": Time value missing, reseting to 0\n"); - warn_ = 1; - } - return 0; /* empty time field */ - } - - if (strchr(str, '.')) /* time in hhmmss.ms */ - { - CHECK_INP(4, sscanf(str, "%02d%02d%02d.%d", - &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &msec), - "decode_tm(1) hhmmss.ss", str); - } - else if (sscanf(str,"%06d",&temp)==1) - /* WORKAROUND read time info only if a valid 6 digit string found */ - { - CHECK_INP(3, sscanf(str, "%02d%02d%02d", - &tm->tm_hour, &tm->tm_min, &tm->tm_sec), - "decode_tm(2) hhmmss", str); - } - else - { - if (global_opts.debug_level > 0) - { - warning(MYNAME ": Invalid time value, reseting to 0\n"); - warn_ = 1; - } - return 0; /* WORKAROUND maybe invalid time, just ignore it and continue */ - } - cx = strchr(str, ' '); - - if (cx == NULL) - { - if (global_opts.debug_level > 0) - { - warning(MYNAME ": Date value missing, reseting to 0\n"); - warn_ = 1; - } - return 0; /* empty date field */ - } - - cx = lrtrim(cx); - if (*cx == '\0') - { - if (global_opts.debug_level > 0) - { - warning(MYNAME ": Date value missing, found only spaces, reseting to 0\n"); - warn_ = 1; - } - return 0; /* empty date field */ - } - - if (datefmt) - { - struct tm tm2; - - if (NULL == strptime(cx, datefmt, &tm2)) - { - fatal(MYNAME ": Unable to convert date '%s' using format '%s' (%s)!\n", cx, datefmt, opt_date); - } - - tm->tm_year = tm2.tm_year + 1900; - tm->tm_mon = tm2.tm_mon + 1; - tm->tm_mday = tm2.tm_mday; - } - else - { - time_t tnow; - struct tm now; - - - tnow = current_time(); - now = *localtime(&tnow); - now.tm_year += 1900; - now.tm_mon++; - - if (strlen(cx) == 8) - { - CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3) invalid date (YYYYMMDD)", cx); - - year = (d1 * 100) + d2; - /* the coordinates comes before date and time in - the dataset, so the flag "german_release" is set yet. */ - - /* next code works for most, except for 19. and 20. of month */ - - if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) /* YYYYMMDD or DDMMYYYY ????? */ - { - tm->tm_year = (d3 * 100) + d4; - tm->tm_mon = d2; - tm->tm_mday = d1; - } - else - { - tm->tm_year = (d1 * 100) + d2; - tm->tm_mon = d3; - tm->tm_mday = d4; - } - } else if (strlen(cx) == 6) - { - CHECK_INP(3, sscanf(cx, "%02d%02d%02d", &d1, &d2, &d3), "decode_tm(3) invalid date (DDMMYY)", cx); - if (d3 < 1970) /* Usual Y2K interpretation */ - year = d3 + 2000; - else - year = d3 + 1900; - -/* I don't know how a german release handles this - * so for now I will assume only DDMMYY if date has 6 digits - */ - tm->tm_year = year; - tm->tm_mon = d2; - tm->tm_mday = d1; - } else /* date string is neither 8 nor 6 digits */ - { - printf(MYNAME ": Date from first record is %s.\n", cx); - printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n"); - fatal(MYNAME ": (... -i pathaway,date=DDMMYY ...)\n"); - } - } - return 1; + int msec, d1, d2, d3, d4; + int year; + int temp=0; + char *cx; + + str = lrtrim(str); /* time field may start/end with spaces, drop them */ + + if (*str == '\0') { + if (global_opts.debug_level > 0) { + warning(MYNAME ": Time value missing, reseting to 0\n"); + warn_ = 1; + } + return 0; /* empty time field */ + } + + if (strchr(str, '.')) { /* time in hhmmss.ms */ + CHECK_INP(4, sscanf(str, "%02d%02d%02d.%d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &msec), + "decode_tm(1) hhmmss.ss", str); + } else if (sscanf(str,"%06d",&temp)==1) + /* WORKAROUND read time info only if a valid 6 digit string found */ + { + CHECK_INP(3, sscanf(str, "%02d%02d%02d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec), + "decode_tm(2) hhmmss", str); + } else { + if (global_opts.debug_level > 0) { + warning(MYNAME ": Invalid time value, reseting to 0\n"); + warn_ = 1; + } + return 0; /* WORKAROUND maybe invalid time, just ignore it and continue */ + } + cx = strchr(str, ' '); + + if (cx == NULL) { + if (global_opts.debug_level > 0) { + warning(MYNAME ": Date value missing, reseting to 0\n"); + warn_ = 1; + } + return 0; /* empty date field */ + } + + cx = lrtrim(cx); + if (*cx == '\0') { + if (global_opts.debug_level > 0) { + warning(MYNAME ": Date value missing, found only spaces, reseting to 0\n"); + warn_ = 1; + } + return 0; /* empty date field */ + } + + if (datefmt) { + struct tm tm2; + + if (NULL == strptime(cx, datefmt, &tm2)) { + fatal(MYNAME ": Unable to convert date '%s' using format '%s' (%s)!\n", cx, datefmt, opt_date); + } + + tm->tm_year = tm2.tm_year + 1900; + tm->tm_mon = tm2.tm_mon + 1; + tm->tm_mday = tm2.tm_mday; + } else { + time_t tnow; + struct tm now; + + + tnow = current_time(); + now = *localtime(&tnow); + now.tm_year += 1900; + now.tm_mon++; + + if (strlen(cx) == 8) { + CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3) invalid date (YYYYMMDD)", cx); + + year = (d1 * 100) + d2; + /* the coordinates comes before date and time in + the dataset, so the flag "german_release" is set yet. */ + + /* next code works for most, except for 19. and 20. of month */ + + if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) { /* YYYYMMDD or DDMMYYYY ????? */ + tm->tm_year = (d3 * 100) + d4; + tm->tm_mon = d2; + tm->tm_mday = d1; + } else { + tm->tm_year = (d1 * 100) + d2; + tm->tm_mon = d3; + tm->tm_mday = d4; + } + } else if (strlen(cx) == 6) { + CHECK_INP(3, sscanf(cx, "%02d%02d%02d", &d1, &d2, &d3), "decode_tm(3) invalid date (DDMMYY)", cx); + if (d3 < 1970) { /* Usual Y2K interpretation */ + year = d3 + 2000; + } else { + year = d3 + 1900; + } + + /* I don't know how a german release handles this + * so for now I will assume only DDMMYY if date has 6 digits + */ + tm->tm_year = year; + tm->tm_mon = d2; + tm->tm_mday = d1; + } else { /* date string is neither 8 nor 6 digits */ + printf(MYNAME ": Date from first record is %s.\n", cx); + printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n"); + fatal(MYNAME ": (... -i pathaway,date=DDMMYY ...)\n"); + } + } + return 1; } -static +static int ppdb_read_wpt(route_head *head, int isRoute) { - char *data, *str; - double altfeet; - struct tm tm; - - while (pdb_read_rec(file_in, NULL, NULL, NULL, (void *)&data) >= 0) { - waypoint *wpt_tmp = waypt_new(); - int line = 0; - char *tmp = data; - -/* Print the whole input record. All input records are printed before processing. */ - if (global_opts.debug_level >= 5) - { - DBG(("\n\ + char *data, *str; + double altfeet; + struct tm tm; + + while (pdb_read_rec(file_in, NULL, NULL, NULL, (void **)&data) >= 0) { + waypoint *wpt_tmp = waypt_new(); + int line = 0; + char *tmp = data; + + /* Print the whole input record. All input records are printed before processing. */ + if (global_opts.debug_level >= 5) { + DBG(("\n\ --- BEGIN Input data record -----------------------------------------------\n\ %s\n\ --- END Input data record -------------------------------------------------\n",data)); - } - - while ((str = csv_lineparse(tmp, ",", "\"", line++))) { - tmp = NULL; - switch(line) - { - case 1: /* latitude */ - wpt_tmp->latitude = ppdb_decode_coord(str); - break; - case 2: /* longitude */ - wpt_tmp->longitude = ppdb_decode_coord(str); - break; - case 3: /* altitude */ - if (*str != '\0') - { - CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude", str); - if (altfeet != -9999) - wpt_tmp->altitude = FEET_TO_METERS(altfeet); - } - break; - case 4: /* time and date (optional) */ - memset(&tm, 0, sizeof(tm)); - if (ppdb_decode_tm(str, &tm)) - { - tm.tm_year -= 1900; - tm.tm_mon--; - wpt_tmp->creation_time = mkgmtime(&tm); - } - break; - case 5: /* name */ - if (*str != '\0') - wpt_tmp->shortname = xstrdup(str); - break; - case 6: /* icon */ - if (*str != '\0') - wpt_tmp->icon_descr = xstrdup(str); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - break; - case 7: /* notes */ - if (*str != '\0') - wpt_tmp->notes = xstrdup(str); - break; - - } - } - -/* Print the whole input record, should a warning be triggered. - * Use warning() here instead of DBG() to print the data record - * right after the warning is issued. - */ - if (warn_ && (global_opts.debug_level > 1) && (global_opts.debug_level < 5)) - { - warning("Faulty input data record : %s\n",data); - warn_ = 0; - } - - if (head && isRoute ) - route_add_wpt(head, wpt_tmp); - else if (head) - track_add_wpt(head, wpt_tmp); - else - waypt_add(wpt_tmp); - - } - return 0; + } + + while ((str = csv_lineparse(tmp, ",", "\"", line++))) { + tmp = NULL; + switch (line) { + case 1: /* latitude */ + wpt_tmp->latitude = ppdb_decode_coord(str); + break; + case 2: /* longitude */ + wpt_tmp->longitude = ppdb_decode_coord(str); + break; + case 3: /* altitude */ + if (*str != '\0') { + CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude", str); + if (altfeet != -9999) { + wpt_tmp->altitude = FEET_TO_METERS(altfeet); + } + } + break; + case 4: /* time and date (optional) */ + memset(&tm, 0, sizeof(tm)); + if (ppdb_decode_tm(str, &tm)) { + tm.tm_year -= 1900; + tm.tm_mon--; + wpt_tmp->creation_time = mkgmtime(&tm); + } + break; + case 5: /* name */ + if (*str != '\0') { + wpt_tmp->shortname = xstrdup(str); + } + break; + case 6: /* icon */ + if (*str != '\0') { + wpt_tmp->icon_descr = xstrdup(str); + } + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 7: /* notes */ + if (*str != '\0') { + wpt_tmp->notes = xstrdup(str); + } + break; + + } + } + + /* Print the whole input record, should a warning be triggered. + * Use warning() here instead of DBG() to print the data record + * right after the warning is issued. + */ + if (warn_ && (global_opts.debug_level > 1) && (global_opts.debug_level < 5)) { + warning("Faulty input data record : %s\n",data); + warn_ = 0; + } + + if (head && isRoute) { + route_add_wpt(head, wpt_tmp); + } else if (head) { + track_add_wpt(head, wpt_tmp); + } else { + waypt_add(wpt_tmp); + } + + } + return 0; } /* ============================================================================================ @@ -538,89 +511,90 @@ int ppdb_read_wpt(route_head *head, int isRoute) static void ppdb_rd_init(const char *fname) { - str_pool_init(); - file_in = pdb_open(fname, MYNAME); - ct = 0; - - if (opt_date) - datefmt = convert_human_date_format(opt_date); - else - datefmt = NULL; + str_pool_init(); + file_in = pdb_open(fname, MYNAME); + ct = 0; + + if (opt_date) { + datefmt = convert_human_date_format(opt_date); + } else { + datefmt = NULL; + } } static void ppdb_rd_deinit(void) { - pdb_close(file_in); - str_pool_deinit(); - if (datefmt) xfree(datefmt); + pdb_close(file_in); + str_pool_deinit(); + if (datefmt) { + xfree(datefmt); + } } static void ppdb_read(void) { - ppdb_appdata_t *info = NULL; - route_head *track_head, *route_head; - const char *descr = NULL; - - if (file_in->creator != PPDB_MAGIC) /* identify the database */ - fatal(MYNAME ": Not a PathAway pdb file.\n"); - - if (file_in->version != 3) /* Currently we support only version 3 */ - fatal(MYNAME ": This file is from an untested version (%d) of PathAway and is unsupported.\n", file_in->version); - - if ((file_in->appinfo_len > 0) && (file_in->appinfo != NULL)) - { - info = (ppdb_appdata_t *) file_in->appinfo; - descr = info->vehicleStr; - } - switch(file_in->type) - { - case PPDB_MAGIC_TRK: - ppdb_type = trkdata; /* as default */ - if (info != NULL) - { - switch(info->dataBaseSubType) - { - case 0: - ppdb_type = trkdata; - break; - case 1: - ppdb_type = rtedata; - break; - default: - fatal(MYNAME": Invalid database subtype.\n"); - } - } - break; - - case PPDB_MAGIC_WPT: - ppdb_type = wptdata; - break; - - default: - fatal(MYNAME ": It looks like a PathAway pdb, but has no gps magic.\n"); - } - - switch(ppdb_type) - { - case trkdata: - track_head = route_head_alloc(); - track_add_head(track_head); - track_head->rte_name = xstrdup(file_in->name); - ppdb_read_wpt(track_head, 0); - break; - case rtedata: - route_head = route_head_alloc(); - route_add_head(route_head); - route_head->rte_name = xstrdup(file_in->name); - ppdb_read_wpt(route_head, 1); - break; - case wptdata: - ppdb_read_wpt(NULL, 0); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - } + ppdb_appdata_t *info = NULL; + route_head *track_head, *route_head; + const char *descr = NULL; + + if (file_in->creator != PPDB_MAGIC) { /* identify the database */ + fatal(MYNAME ": Not a PathAway pdb file.\n"); + } + + if (file_in->version != 3) { /* Currently we support only version 3 */ + fatal(MYNAME ": This file is from an untested version (%d) of PathAway and is unsupported.\n", file_in->version); + } + + if ((file_in->appinfo_len > 0) && (file_in->appinfo != NULL)) { + info = (ppdb_appdata_t *) file_in->appinfo; + descr = info->vehicleStr; + } + switch (file_in->type) { + case PPDB_MAGIC_TRK: + ppdb_type = trkdata; /* as default */ + if (info != NULL) { + switch (info->dataBaseSubType) { + case 0: + ppdb_type = trkdata; + break; + case 1: + ppdb_type = rtedata; + break; + default: + fatal(MYNAME": Invalid database subtype.\n"); + } + } + break; + + case PPDB_MAGIC_WPT: + ppdb_type = wptdata; + break; + + default: + fatal(MYNAME ": It looks like a PathAway pdb, but has no gps magic.\n"); + } + + switch (ppdb_type) { + case trkdata: + track_head = route_head_alloc(); + track_add_head(track_head); + track_head->rte_name = xstrdup(file_in->name); + ppdb_read_wpt(track_head, 0); + break; + case rtedata: + route_head = route_head_alloc(); + route_add_head(route_head); + route_head->rte_name = xstrdup(file_in->name); + ppdb_read_wpt(route_head, 1); + break; + case wptdata: + case unknown_gpsdata: + ppdb_read_wpt(NULL, 0); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } } /* ============================================================================================ @@ -629,199 +603,208 @@ static void ppdb_read(void) static void ppdb_wr_init(const char *fname) { - int len; - - fname_out = xstrdup(fname); - str_pool_init(); - file_out = pdb_create(fname, MYNAME); - mkshort_handle = mkshort_new_handle(); - ct = 0; - appinfo = NULL; - - if (global_opts.synthesize_shortnames != 0) - { - len = atoi(opt_snlen); - setshort_length(mkshort_handle, len); - setshort_mustupper(mkshort_handle, 1); - setshort_badchars(mkshort_handle, ","); - setshort_whitespace_ok(mkshort_handle, 0); - } - if (opt_date) - { - char *c = convert_human_date_format(opt_date); - xasprintf(&datefmt, "%s %s", "%H%M%S", c); - xfree(c); - } - else - datefmt = xstrdup("%H%M%S %Y%m%d"); + int len; + + fname_out = xstrdup(fname); + str_pool_init(); + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + ct = 0; + appinfo = NULL; + + if (global_opts.synthesize_shortnames != 0) { + len = atoi(opt_snlen); + setshort_length(mkshort_handle, len); + setshort_mustupper(mkshort_handle, 1); + setshort_badchars(mkshort_handle, ","); + setshort_whitespace_ok(mkshort_handle, 0); + } + if (opt_date) { + char *c = convert_human_date_format(opt_date); + xasprintf(&datefmt, "%s %s", "%H%M%S", c); + xfree(c); + } else { + datefmt = xstrdup("%H%M%S %Y%m%d"); + } } static void ppdb_wr_deinit(void) { - mkshort_del_handle(&mkshort_handle); - pdb_close(file_out); - str_pool_deinit(); - xfree(fname_out); - if (datefmt) xfree(datefmt); - if (appinfo) xfree(appinfo); + mkshort_del_handle(&mkshort_handle); + pdb_close(file_out); + str_pool_deinit(); + xfree(fname_out); + if (datefmt) { + xfree(datefmt); + } + if (appinfo) { + xfree(appinfo); + } } /* * ppdb_write_wpt: callback for waypoint output - */ - + */ + #define REC_SIZE 128 static void ppdb_write_wpt(const waypoint *wpt) { - char *buff, *tmp; - char latdir, longdir; - int len; - struct tm tm; - - buff = xcalloc(REC_SIZE, 1); - - if (wpt->latitude < 0) - latdir = 'S'; - else - latdir = 'N'; - if (wpt->longitude < 0) - longdir = 'W'; - else - longdir = 'E'; - /* 1 latitude, - 2 longitude */ - - snprintf(buff, REC_SIZE, "%s,%s,", - ppdb_fmt_degrees(latdir, wpt->latitude), - ppdb_fmt_degrees(longdir, wpt->longitude) - ); - - len = REC_SIZE; /* we have coordinates in buff, now optional stuff */ - /* 3 altitude */ - - if (fabs(wpt->altitude) < 9999.0) - { - tmp = str_pool_get(32); - snprintf(tmp, 32, "%s", ppdb_fmt_float(METERS_TO_FEET(wpt->altitude))); - buff = ppdb_strcat(buff, tmp, NULL, &len); - } - buff = ppdb_strcat(buff, ",", NULL, &len); - /* 4 time, date */ - - if ( wpt->creation_time != 0) - { - tmp = str_pool_get(20); - tm = *gmtime(&wpt->creation_time); - strftime(tmp, 20, datefmt, &tm); - buff = ppdb_strcat(buff, tmp, NULL, &len); - } - buff = ppdb_strcat(buff, ",", NULL, &len); - /* 5 name */ - - if (global_opts.synthesize_shortnames != 0) - { - tmp = mkshort_from_wpt(mkshort_handle, wpt); - DBG(("shortname %s from %s", tmp, wpt->shortname)); - } - else - { - tmp = str_pool_getcpy(wpt->shortname, ""); - while (strchr(tmp, ',') != NULL) - *strchr(tmp, ',') = '.'; - } - buff = ppdb_strcat(buff, tmp, "", &len); - - buff = ppdb_strcat(buff, ",", NULL, &len); - /* 6 icon */ - - tmp = str_pool_getcpy(wpt->icon_descr, opt_deficon); /* point icon or deficon from options */ - buff = ppdb_strcat(buff, tmp, NULL, &len); - buff = ppdb_strcat(buff, ",", NULL, &len); - /* 7 description */ - - tmp = str_pool_getcpy(wpt->description, ""); - if (strchr(tmp, ',') != NULL ) - { - buff = ppdb_strcat(buff, "\"", NULL, &len); - while (strchr(tmp, '"') != NULL) - *strchr(tmp, '"') = '\''; - buff = ppdb_strcat(buff, tmp, NULL, &len); - buff = ppdb_strcat(buff, "\"", NULL, &len); - } - else - buff = ppdb_strcat(buff, tmp, "", &len); - - len = strlen(buff) + 1; - pdb_write_rec(file_out, 0, 0, ct++, buff, len); - - xfree(buff); + char *buff, *tmp; + char latdir, longdir; + int len; + struct tm tm; + + buff = (char *) xcalloc(REC_SIZE, 1); + + if (wpt->latitude < 0) { + latdir = 'S'; + } else { + latdir = 'N'; + } + if (wpt->longitude < 0) { + longdir = 'W'; + } else { + longdir = 'E'; + } + /* 1 latitude, + 2 longitude */ + + snprintf(buff, REC_SIZE, "%s,%s,", + ppdb_fmt_degrees(latdir, wpt->latitude), + ppdb_fmt_degrees(longdir, wpt->longitude) + ); + + len = REC_SIZE; /* we have coordinates in buff, now optional stuff */ + /* 3 altitude */ + + if (fabs(wpt->altitude) < 9999.0) { + tmp = str_pool_get(32); + snprintf(tmp, 32, "%s", ppdb_fmt_float(METERS_TO_FEET(wpt->altitude))); + buff = ppdb_strcat(buff, tmp, NULL, &len); + } + buff = ppdb_strcat(buff, ",", NULL, &len); + /* 4 time, date */ + + if (wpt->creation_time != 0) { + tmp = str_pool_get(20); + tm = *gmtime(&wpt->creation_time); + strftime(tmp, 20, datefmt, &tm); + buff = ppdb_strcat(buff, tmp, NULL, &len); + } + buff = ppdb_strcat(buff, ",", NULL, &len); + /* 5 name */ + + if (global_opts.synthesize_shortnames != 0) { + tmp = mkshort_from_wpt(mkshort_handle, wpt); + DBG(("shortname %s from %s", tmp, wpt->shortname)); + } else { + tmp = str_pool_getcpy(wpt->shortname, ""); + while (strchr(tmp, ',') != NULL) { + *strchr(tmp, ',') = '.'; + } + } + buff = ppdb_strcat(buff, tmp, "", &len); + + buff = ppdb_strcat(buff, ",", NULL, &len); + /* 6 icon */ + + tmp = str_pool_getcpy(wpt->icon_descr, opt_deficon); /* point icon or deficon from options */ + buff = ppdb_strcat(buff, tmp, NULL, &len); + buff = ppdb_strcat(buff, ",", NULL, &len); + /* 7 description */ + + tmp = str_pool_getcpy(wpt->description, ""); + if (strchr(tmp, ',') != NULL) { + buff = ppdb_strcat(buff, "\"", NULL, &len); + while (strchr(tmp, '"') != NULL) { + *strchr(tmp, '"') = '\''; + } + buff = ppdb_strcat(buff, tmp, NULL, &len); + buff = ppdb_strcat(buff, "\"", NULL, &len); + } else { + buff = ppdb_strcat(buff, tmp, "", &len); + } + + len = strlen(buff) + 1; + pdb_write_rec(file_out, 0, 0, ct++, buff, len); + + xfree(buff); } /* * track and route write callbacks */ - + static void ppdb_write(void) { - - if (opt_dbname) - strncpy(file_out->name, opt_dbname, PDB_DBNAMELEN); - - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->creator = PPDB_MAGIC; - file_out->version = 3; - -/* Waypoint target does use vehicleStr from appinfo block - * Actually, all 3 types have vehicle information. - * if (global_opts.objective != wptdata) / * Waypoint target do not need appinfo block * / - * { - */ - appinfo = xcalloc(1, sizeof(*appinfo)); - file_out->appinfo = (void *)appinfo; - file_out->appinfo_len = PPDB_APPINFO_SIZE; -/* } - */ - if (opt_dbicon != NULL) strncpy(appinfo->vehicleStr, opt_dbicon, VEHICLE_LEN); - - switch(global_opts.objective) /* Only one target is possible */ - { - case wptdata: - if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Waypoints", PDB_DBNAMELEN); - file_out->type = PPDB_MAGIC_WPT; - waypt_disp_all(ppdb_write_wpt); - break; - case trkdata: - if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Track", PDB_DBNAMELEN); - file_out->type = PPDB_MAGIC_TRK; - appinfo->dataBaseSubType = 0; - track_disp_all(NULL, NULL, ppdb_write_wpt); - break; - case rtedata: - if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Route", PDB_DBNAMELEN); - file_out->type = PPDB_MAGIC_TRK; - appinfo->dataBaseSubType = 1; - route_disp_all(NULL, NULL, ppdb_write_wpt); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - } + + if (opt_dbname) { + strncpy(file_out->name, opt_dbname, PDB_DBNAMELEN); + } + + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->creator = PPDB_MAGIC; + file_out->version = 3; + + /* Waypoint target does use vehicleStr from appinfo block + * Actually, all 3 types have vehicle information. + * if (global_opts.objective != wptdata) / * Waypoint target do not need appinfo block * / + * { + */ + appinfo = (ppdb_appdata_t *) xcalloc(1, sizeof(*appinfo)); + file_out->appinfo = (void *)appinfo; + file_out->appinfo_len = PPDB_APPINFO_SIZE; + /* } + */ + if (opt_dbicon != NULL) { + strncpy(appinfo->vehicleStr, opt_dbicon, VEHICLE_LEN); + } + + switch (global_opts.objective) { /* Only one target is possible */ + case wptdata: + case unknown_gpsdata: + if (opt_dbname == NULL) { + strncpy(file_out->name, "PathAway Waypoints", PDB_DBNAMELEN); + } + file_out->type = PPDB_MAGIC_WPT; + waypt_disp_all(ppdb_write_wpt); + break; + case trkdata: + if (opt_dbname == NULL) { + strncpy(file_out->name, "PathAway Track", PDB_DBNAMELEN); + } + file_out->type = PPDB_MAGIC_TRK; + appinfo->dataBaseSubType = 0; + track_disp_all(NULL, NULL, ppdb_write_wpt); + break; + case rtedata: + if (opt_dbname == NULL) { + strncpy(file_out->name, "PathAway Route", PDB_DBNAMELEN); + } + file_out->type = PPDB_MAGIC_TRK; + appinfo->dataBaseSubType = 1; + route_disp_all(NULL, NULL, ppdb_write_wpt); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } } ff_vecs_t ppdb_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - ppdb_rd_init, - ppdb_wr_init, - ppdb_rd_deinit, - ppdb_wr_deinit, - ppdb_read, - ppdb_write, - NULL, - ppdb_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + ppdb_rd_init, + ppdb_wr_init, + ppdb_rd_deinit, + ppdb_wr_deinit, + ppdb_read, + ppdb_write, + NULL, + ppdb_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/pcx.c b/gpsbabel/pcx.c index 6a4437b97..c30ce305e 100644 --- a/gpsbabel/pcx.c +++ b/gpsbabel/pcx.c @@ -42,416 +42,430 @@ static int lon_col; static arglist_t pcx_args[] = { - {"deficon", &deficon, "Default icon name", "Waypoint", - ARGTYPE_STRING, ARG_NOMINMAX }, - {"cartoexploreur", &cartoexploreur, - "Write tracks compatible with Carto Exploreur", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "deficon", &deficon, "Default icon name", "Waypoint", + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "cartoexploreur", &cartoexploreur, + "Write tracks compatible with Carto Exploreur", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = gbfopen(fname, "rb", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen(fname, "w", MYNAME); - mkshort_handle = mkshort_new_handle(); - mkshort_handle2 = mkshort_new_handle(); + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); + mkshort_handle2 = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); - mkshort_del_handle(&mkshort_handle2); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_handle2); } static void data_read(void) { - char name[7], desc[41]; - double lat = 0, lon = 0; - long alt; - int symnum; - char date[10]; - char time[9]; - char month[4]; - waypoint *wpt_tmp; - char *buff; - struct tm tm; - route_head *track = NULL; - route_head *route = NULL; - int n; - char lathemi, lonhemi; - char tbuf[20]; - char nbuf[20]; - int points; - int line = 0; - - read_as_degrees = 0; - points = 0; - - while ((buff = gbfgetstr(file_in))) - { - char *ibuf = lrtrim(buff); - char *cp; - - if ((line++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - switch (ibuf[0]) { - case 'W': - time[0] = 0; - date[0] = 0; - desc[0] = 0; - alt = -9999; - sscanf(ibuf, "W %6c %s %s %s %s %ld", - name, tbuf, nbuf, date, time, &alt); - if (alt == -9999) { - alt = unknown_alt; - } - - if (comment_col) { - strncpy(desc, &ibuf[comment_col], sizeof(desc)-1); - } else { - desc[0] = 0; - } - - - symnum = 18; - if (sym_col) { - symnum = atoi(&ibuf[sym_col]); - } - - // If we have explicit columns for lat and lon, - // copy those entire words (warning: no spaces) - // into the respective coord buffers. - if (lat_col) { - sscanf(tbuf, "%s", ibuf + lat_col); - } - if (lon_col) { - sscanf(nbuf, "%s", ibuf + lon_col); - } - - name[sizeof(name)-1] = '\0'; - desc[sizeof(desc)-1] = '\0'; - - wpt_tmp = waypt_new(); - wpt_tmp->altitude = alt; - cp = lrtrim(name); - if (*cp != '\0') { - wpt_tmp->shortname = xstrdup(cp); - } - cp = lrtrim(desc); - if (*cp != '\0') { - wpt_tmp->description = xstrdup(cp); - } - wpt_tmp->icon_descr = gt_find_desc_from_icon_number(symnum, PCX, NULL); - - if (read_as_degrees || read_gpsu) { - human_to_dec(tbuf, &lat, &lon, 1); - human_to_dec(nbuf, &lat, &lon, 2); - - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - } else { - lat = atof(&tbuf[1]); - lon = atof(&nbuf[1]); - if (tbuf[0] == 'S') lat = -lat; - if (nbuf[0] == 'W') lon = -lon; - wpt_tmp->longitude = ddmm2degrees(lon); - wpt_tmp->latitude = ddmm2degrees(lat); - } - if (route != NULL) - route_add_wpt(route, waypt_dupe(wpt_tmp)); - waypt_add(wpt_tmp); - points++; - break; - case 'H': - /* Garmap2 has headers - "H(2 spaces)LATITUDE(some spaces)LONGTITUDE(etc... followed by);track - everything else is - H(2 chars)TN(tracknane\0) - */ - if (points > 0) { - track = NULL; - points = 0; - } - if (track == NULL) { - if (ibuf[3] == 'L' && ibuf[4] == 'A') { - track = route_head_alloc(); - track->rte_name = xstrdup("track"); - track_add_head(track); - } else if (ibuf[3] == 'T' && ibuf[4] == 'N') { - track = route_head_alloc(); - track->rte_name = xstrdup(&ibuf[6]); - track_add_head(track); - } - } - break; - case 'R': - n = 1; - while (ibuf[n] == ' ') n++; - route = route_head_alloc(); - route->rte_name = xstrdup(&ibuf[n]); - route_add_head(route); - break; - case 'T': - n = sscanf(ibuf, "T %lf %lf %s %s %ld", - &lat, &lon, date, time, &alt); - - if (n == 0) { - /* Attempt alternate PCX format used by - * www.radroutenplaner.nrw.de */ - n = sscanf(ibuf, "T %c%lf %c%lf %s %s %ld", - &lathemi, &lat, &lonhemi, &lon, date, - time, &alt); - if (lathemi == 'S') lat = -lat; - if (lonhemi == 'W') lon = -lon; - } else if (n == 0) { - fatal(MYNAME ":Unrecognized track line '%s'\n", - ibuf); - } - - memset(&tm, 0, sizeof(tm)); - tm.tm_hour = atoi(time); - tm.tm_min = atoi(time+3); - tm.tm_sec = atoi(time+6); - tm.tm_mday = atoi(date); - strncpy(month, date+3, 3); - month[3] = 0; - tm.tm_mon = month_lookup(month); - tm.tm_year = atoi(date + 7); - if (tm.tm_year < 70) tm.tm_year += 100; - wpt_tmp = waypt_new(); - wpt_tmp->creation_time = mkgmtime(&tm); - if (read_as_degrees) { - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - } else { - wpt_tmp->longitude = ddmm2degrees(lon); - wpt_tmp->latitude = ddmm2degrees(lat); - } - wpt_tmp->altitude = alt; - /* Did we get a track point before a track header? */ - if (track == NULL) { - track = route_head_alloc(); - track->rte_name = xstrdup("Default"); - track_add_head(track); - } - track_add_wpt(track, wpt_tmp); - points++; - break; - case 'U': - read_as_degrees = ! strncmp("LAT LON DEG", ibuf + 3, 11); - if (strstr(ibuf, "UTM")) { - fatal (MYNAME ": UTM is not supported.\n"); - } - break; - // GPSU is apparently PCX but with a different definition - // of "LAT LON DM" - unlike the other, it actually IS decimal - // minutes. - case 'I': - read_gpsu = ! (strstr(ibuf, "GPSU") == NULL) ; - break; - // This is a format specifier. Use this line to figure out - // where our other columns start. - case 'F': { - int col; - char *i = ibuf; - sym_col = 0; - - for (col = 0, i = ibuf; *i; col++, i++) { - if (0 == case_ignore_strncmp(i, "comment", 7)) { - comment_col = col; - } - if (0 == case_ignore_strncmp(i, "symbol", 6)) { - sym_col = col; - } - if (0 == case_ignore_strncmp(i, "latitude", 8)) { - lat_col = col; - } - if (0 == case_ignore_strncmp(i, "longitude", 9)) { - lon_col = col; - } - } - } - break; - default: - break; - ; - - } - } + char name[7], desc[41]; + double lat = 0, lon = 0; + long alt; + int symnum; + char date[10]; + char time[9]; + char month[4]; + waypoint *wpt_tmp; + char *buff; + struct tm tm; + route_head *track = NULL; + route_head *route = NULL; + int n; + char lathemi, lonhemi; + char tbuf[20]; + char nbuf[20]; + int points; + int line = 0; + + read_as_degrees = 0; + points = 0; + + while ((buff = gbfgetstr(file_in))) { + char *ibuf = lrtrim(buff); + char *cp; + + if ((line++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + switch (ibuf[0]) { + case 'W': + time[0] = 0; + date[0] = 0; + desc[0] = 0; + alt = -9999; + sscanf(ibuf, "W %6c %s %s %s %s %ld", + name, tbuf, nbuf, date, time, &alt); + if (alt == -9999) { + alt = unknown_alt; + } + + if (comment_col) { + strncpy(desc, &ibuf[comment_col], sizeof(desc)-1); + } else { + desc[0] = 0; + } + + + symnum = 18; + if (sym_col) { + symnum = atoi(&ibuf[sym_col]); + } + + // If we have explicit columns for lat and lon, + // copy those entire words (warning: no spaces) + // into the respective coord buffers. + if (lat_col) { + sscanf(tbuf, "%s", ibuf + lat_col); + } + if (lon_col) { + sscanf(nbuf, "%s", ibuf + lon_col); + } + + name[sizeof(name)-1] = '\0'; + desc[sizeof(desc)-1] = '\0'; + + wpt_tmp = waypt_new(); + wpt_tmp->altitude = alt; + cp = lrtrim(name); + if (*cp != '\0') { + wpt_tmp->shortname = xstrdup(cp); + } + cp = lrtrim(desc); + if (*cp != '\0') { + wpt_tmp->description = xstrdup(cp); + } + wpt_tmp->icon_descr = gt_find_desc_from_icon_number(symnum, PCX, NULL); + + if (read_as_degrees || read_gpsu) { + human_to_dec(tbuf, &lat, &lon, 1); + human_to_dec(nbuf, &lat, &lon, 2); + + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + } else { + lat = atof(&tbuf[1]); + lon = atof(&nbuf[1]); + if (tbuf[0] == 'S') { + lat = -lat; + } + if (nbuf[0] == 'W') { + lon = -lon; + } + wpt_tmp->longitude = ddmm2degrees(lon); + wpt_tmp->latitude = ddmm2degrees(lat); + } + if (route != NULL) { + route_add_wpt(route, waypt_dupe(wpt_tmp)); + } + waypt_add(wpt_tmp); + points++; + break; + case 'H': + /* Garmap2 has headers + "H(2 spaces)LATITUDE(some spaces)LONGTITUDE(etc... followed by);track + everything else is + H(2 chars)TN(tracknane\0) + */ + if (points > 0) { + track = NULL; + points = 0; + } + if (track == NULL) { + if (ibuf[3] == 'L' && ibuf[4] == 'A') { + track = route_head_alloc(); + track->rte_name = xstrdup("track"); + track_add_head(track); + } else if (ibuf[3] == 'T' && ibuf[4] == 'N') { + track = route_head_alloc(); + track->rte_name = xstrdup(&ibuf[6]); + track_add_head(track); + } + } + break; + case 'R': + n = 1; + while (ibuf[n] == ' ') { + n++; + } + route = route_head_alloc(); + route->rte_name = xstrdup(&ibuf[n]); + route_add_head(route); + break; + case 'T': + n = sscanf(ibuf, "T %lf %lf %s %s %ld", + &lat, &lon, date, time, &alt); + + if (n == 0) { + /* Attempt alternate PCX format used by + * www.radroutenplaner.nrw.de */ + n = sscanf(ibuf, "T %c%lf %c%lf %s %s %ld", + &lathemi, &lat, &lonhemi, &lon, date, + time, &alt); + if (lathemi == 'S') { + lat = -lat; + } + if (lonhemi == 'W') { + lon = -lon; + } + } else if (n == 0) { + fatal(MYNAME ":Unrecognized track line '%s'\n", + ibuf); + } + + memset(&tm, 0, sizeof(tm)); + tm.tm_hour = atoi(time); + tm.tm_min = atoi(time+3); + tm.tm_sec = atoi(time+6); + tm.tm_mday = atoi(date); + strncpy(month, date+3, 3); + month[3] = 0; + tm.tm_mon = month_lookup(month); + tm.tm_year = atoi(date + 7); + if (tm.tm_year < 70) { + tm.tm_year += 100; + } + wpt_tmp = waypt_new(); + wpt_tmp->creation_time = mkgmtime(&tm); + if (read_as_degrees) { + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + } else { + wpt_tmp->longitude = ddmm2degrees(lon); + wpt_tmp->latitude = ddmm2degrees(lat); + } + wpt_tmp->altitude = alt; + /* Did we get a track point before a track header? */ + if (track == NULL) { + track = route_head_alloc(); + track->rte_name = xstrdup("Default"); + track_add_head(track); + } + track_add_wpt(track, wpt_tmp); + points++; + break; + case 'U': + read_as_degrees = ! strncmp("LAT LON DEG", ibuf + 3, 11); + if (strstr(ibuf, "UTM")) { + fatal(MYNAME ": UTM is not supported.\n"); + } + break; + // GPSU is apparently PCX but with a different definition + // of "LAT LON DM" - unlike the other, it actually IS decimal + // minutes. + case 'I': + read_gpsu = !(strstr(ibuf, "GPSU") == NULL) ; + break; + // This is a format specifier. Use this line to figure out + // where our other columns start. + case 'F': { + int col; + char *i = ibuf; + sym_col = 0; + + for (col = 0, i = ibuf; *i; col++, i++) { + if (0 == case_ignore_strncmp(i, "comment", 7)) { + comment_col = col; + } + if (0 == case_ignore_strncmp(i, "symbol", 6)) { + sym_col = col; + } + if (0 == case_ignore_strncmp(i, "latitude", 8)) { + lat_col = col; + } + if (0 == case_ignore_strncmp(i, "longitude", 9)) { + lon_col = col; + } + } + } + break; + default: + break; + ; + + } + } } static void gpsutil_disp(const waypoint *wpt) { - double lon,lat; - int icon_token = 0; - char tbuf[1024]; - time_t tm = wpt->creation_time; - - lon = degrees2ddmm(wpt->longitude); - lat = degrees2ddmm(wpt->latitude); - - if (tm == 0) - tm = current_time(); - strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S", localtime(&tm)); - strupper(tbuf); - - if (deficon) { - icon_token = atoi(deficon); - } else { - icon_token = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); - if (get_cache_icon(wpt)) { - icon_token = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); - } - } - - - gbfprintf(file_out, "W %-6.6s %c%08.5f %c%011.5f %s %5.f %-40.40s %5e %d\n", - global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, wpt) : - wpt->shortname, - lat < 0.0 ? 'S' : 'N', - fabs(lat), - lon < 0.0 ? 'W' : 'E', - fabs(lon), - tbuf, - (wpt->altitude == unknown_alt) ? -9999 : wpt->altitude, - (wpt->description != NULL) ? wpt->description : "", - 0.0, - icon_token); + double lon,lat; + int icon_token = 0; + char tbuf[1024]; + time_t tm = wpt->creation_time; + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + if (tm == 0) { + tm = current_time(); + } + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S", localtime(&tm)); + strupper(tbuf); + + if (deficon) { + icon_token = atoi(deficon); + } else { + icon_token = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + if (get_cache_icon(wpt)) { + icon_token = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } + } + + + gbfprintf(file_out, "W %-6.6s %c%08.5f %c%011.5f %s %5.f %-40.40s %5e %d\n", + global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname, + lat < 0.0 ? 'S' : 'N', + fabs(lat), + lon < 0.0 ? 'W' : 'E', + fabs(lon), + tbuf, + (wpt->altitude == unknown_alt) ? -9999 : wpt->altitude, + (wpt->description != NULL) ? wpt->description : "", + 0.0, + icon_token); } static void pcx_track_hdr(const route_head *trk) { - char *name; - char buff[20]; - - route_ctr++; - snprintf(buff, sizeof(buff)-1, "Trk%03d", route_ctr); - - name = mkshort(mkshort_handle2, (trk->rte_name != NULL) ? trk->rte_name : buff); - /* Carto Exploreur (popular in France) chokes on trackname headers, - * so provide option to supppress these. - */ - if (!cartoexploreur) { - gbfprintf(file_out, "\n\nH TN %s\n", name); - } - xfree(name); - gbfprintf(file_out, "H LATITUDE LONGITUDE DATE TIME ALT ;track\n"); + char *name; + char buff[20]; + + route_ctr++; + snprintf(buff, sizeof(buff)-1, "Trk%03d", route_ctr); + + name = mkshort(mkshort_handle2, (trk->rte_name != NULL) ? trk->rte_name : buff); + /* Carto Exploreur (popular in France) chokes on trackname headers, + * so provide option to supppress these. + */ + if (!cartoexploreur) { + gbfprintf(file_out, "\n\nH TN %s\n", name); + } + xfree(name); + gbfprintf(file_out, "H LATITUDE LONGITUDE DATE TIME ALT ;track\n"); } static void pcx_route_hdr(const route_head *rte) { - char *name; - char buff[20]; - - route_ctr++; - snprintf(buff, sizeof(buff)-1, "Rte%03d", route_ctr); - - name = mkshort(mkshort_handle2, (rte->rte_name != NULL) ? rte->rte_name : buff); - - /* see pcx_track_hdr */ - if (!cartoexploreur) { - gbfprintf(file_out, "\n\nR %s\n", name); - } - gbfprintf(file_out, "\n" -"H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); + char *name; + char buff[20]; + + route_ctr++; + snprintf(buff, sizeof(buff)-1, "Rte%03d", route_ctr); + + name = mkshort(mkshort_handle2, (rte->rte_name != NULL) ? rte->rte_name : buff); + + /* see pcx_track_hdr */ + if (!cartoexploreur) { + gbfprintf(file_out, "\n\nR %s\n", name); + } + gbfprintf(file_out, "\n" + "H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); } void pcx_track_disp(const waypoint *wpt) { - double lon,lat; - char tbuf[100]; - struct tm *tm; - char *tp; - - lon = degrees2ddmm(wpt->longitude); - lat = degrees2ddmm(wpt->latitude); - - tm = gmtime(&wpt->creation_time); - - strftime(tbuf, sizeof(tbuf), "%d-%b-%y %H:%M:%S", tm); /* currently ...%T does nothing under Windows */ - for (tp = tbuf; *tp; tp++) { - *tp = toupper(*tp); - } - gbfprintf(file_out, "T %c%08.5f %c%011.5f %s %.f\n", - lat < 0.0 ? 'S' : 'N', - fabs(lat), - lon < 0.0 ? 'W' : 'E', - fabs(lon), - tbuf, wpt->altitude); + double lon,lat; + char tbuf[100]; + struct tm *tm; + char *tp; + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + tm = gmtime(&wpt->creation_time); + + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %H:%M:%S", tm); /* currently ...%T does nothing under Windows */ + for (tp = tbuf; *tp; tp++) { + *tp = toupper(*tp); + } + gbfprintf(file_out, "T %c%08.5f %c%011.5f %s %.f\n", + lat < 0.0 ? 'S' : 'N', + fabs(lat), + lon < 0.0 ? 'W' : 'E', + fabs(lon), + tbuf, wpt->altitude); } static void data_write(void) { -gbfprintf(file_out, -"H SOFTWARE NAME & VERSION\n" -"I PCX5 2.09\n" -"\n" -"H R DATUM IDX DA DF DX DY DZ\n" -"M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00\n" -"\n" -"H COORDINATE SYSTEM\n" -"U LAT LON DM\n"); - - setshort_length(mkshort_handle, 6); - - setshort_length(mkshort_handle2, 20); /* for track and route names */ - setshort_whitespace_ok(mkshort_handle2, 0); - setshort_mustuniq(mkshort_handle2, 0); - - if (global_opts.objective == wptdata) - { - gbfprintf(file_out, -"\n" -"H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); - - waypt_disp_all(gpsutil_disp); - } - else if (global_opts.objective == trkdata) - { - route_ctr = 0; - track_disp_all(pcx_track_hdr, NULL, pcx_track_disp); - } - else if (global_opts.objective == rtedata) - { - route_ctr = 0; - route_disp_all(pcx_route_hdr, NULL, gpsutil_disp); - } + gbfprintf(file_out, + "H SOFTWARE NAME & VERSION\n" + "I PCX5 2.09\n" + "\n" + "H R DATUM IDX DA DF DX DY DZ\n" + "M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00\n" + "\n" + "H COORDINATE SYSTEM\n" + "U LAT LON DM\n"); + + setshort_length(mkshort_handle, 6); + + setshort_length(mkshort_handle2, 20); /* for track and route names */ + setshort_whitespace_ok(mkshort_handle2, 0); + setshort_mustuniq(mkshort_handle2, 0); + + if (global_opts.objective == wptdata) { + gbfprintf(file_out, + "\n" + "H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); + + waypt_disp_all(gpsutil_disp); + } else if (global_opts.objective == trkdata) { + route_ctr = 0; + track_disp_all(pcx_track_hdr, NULL, pcx_track_disp); + } else if (global_opts.objective == rtedata) { + route_ctr = 0; + route_disp_all(pcx_route_hdr, NULL, gpsutil_disp); + } } ff_vecs_t pcx_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - pcx_args, - CET_CHARSET_ASCII, 1 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + pcx_args, + CET_CHARSET_ASCII, 1 /* CET-REVIEW */ }; diff --git a/gpsbabel/pdbfile.c b/gpsbabel/pdbfile.c index 8c852d42e..0b6af46f0 100644 --- a/gpsbabel/pdbfile.c +++ b/gpsbabel/pdbfile.c @@ -4,7 +4,7 @@ Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org Written after study the Coldsync project - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -36,15 +36,15 @@ static void pdb_invalid_file(const pdbfile *pdb_in, const char *fmt, ...) { - char buff[128]; - va_list args; - - va_start(args, fmt); - vsnprintf(buff, sizeof(buff), fmt, args); - buff[sizeof(buff)-1] = '0'; - - warning(MYNAME ": %s\n", buff); - fatal(MYNAME ": Invalid or unsupported file (%s).\n", pdb_in->file->name); + char buff[128]; + va_list args; + + va_start(args, fmt); + vsnprintf(buff, sizeof(buff), fmt, args); + buff[sizeof(buff)-1] = '0'; + + warning(MYNAME ": %s\n", buff); + fatal(MYNAME ": Invalid or unsupported file (%s).\n", pdb_in->file->name); } /* try to read to EOF (avoid determining file-size) */ @@ -52,250 +52,279 @@ pdb_invalid_file(const pdbfile *pdb_in, const char *fmt, ...) static void * pdb_read_tail(gbfile *fin, gbuint32 *size) { - int count; - char buff[256]; - char *res = NULL; - int bytes = 0; - - while ((count = gbfread(buff, 1, sizeof(buff), fin))) { - - if (!res) { - res = (char *) xmalloc(count); - memcpy(res, buff, count); - } - else { - res = xrealloc(res, bytes + count); - memcpy(&res[bytes], buff, count); - } - bytes += count; - } - if (res) res = xrealloc(res, bytes + 1); - else res = xmalloc(1); - res[bytes] = '\0'; - - if (size) *size = bytes; - return (void *)res; + int count; + char buff[256]; + char *res = NULL; + int bytes = 0; + + while ((count = gbfread(buff, 1, sizeof(buff), fin))) { + + if (!res) { + res = (char *) xmalloc(count); + memcpy(res, buff, count); + } else { + res = (char*) xrealloc(res, bytes + count); + memcpy(&res[bytes], buff, count); + } + bytes += count; + } + if (res) { + res = (char*) xrealloc(res, bytes + 1); + } else { + res = (char*) xmalloc(1); + } + res[bytes] = '\0'; + + if (size) { + *size = bytes; + } + return (void *)res; } static void pdb_load_data(pdbfile *fin) { - gbuint16 i, ct; - pdbrec_t *last_rec; - gbuint32 offs; - pdbrec_t *rec; - - /* load the header */ - gbfread(fin->name, 1, PDB_DBNAMELEN, fin->file); - fin->name[PDB_DBNAMELEN] = '\0'; - - fin->attr = gbfgetuint16(fin->file); - fin->version = gbfgetuint16(fin->file); - fin->ctime = gbfgetuint32(fin->file); - fin->mtime = gbfgetuint32(fin->file); - fin->btime = gbfgetuint32(fin->file); - fin->revision = gbfgetuint32(fin->file); - fin->appinfo_offs = gbfgetint32(fin->file); - fin->index_offs = gbfgetuint32(fin->file); - fin->type = gbfgetuint32(fin->file); - fin->creator = gbfgetuint32(fin->file); - fin->uid = gbfgetuint32(fin->file); - - if (fin->appinfo_offs < 0) - pdb_invalid_file(fin, "Invalid application data offset (%0xh)", fin->appinfo_offs); - if (fin->index_offs < 0) - pdb_invalid_file(fin, "Invalid index offset (%0xh)", fin->index_offs); - + gbuint16 i, ct; + pdbrec_t *last_rec; + gbuint32 offs; + pdbrec_t *rec; + + /* load the header */ + gbfread(fin->name, 1, PDB_DBNAMELEN, fin->file); + fin->name[PDB_DBNAMELEN] = '\0'; + + fin->attr = gbfgetuint16(fin->file); + fin->version = gbfgetuint16(fin->file); + fin->ctime = gbfgetuint32(fin->file); + fin->mtime = gbfgetuint32(fin->file); + fin->btime = gbfgetuint32(fin->file); + fin->revision = gbfgetuint32(fin->file); + fin->appinfo_offs = gbfgetint32(fin->file); + fin->index_offs = gbfgetuint32(fin->file); + fin->type = gbfgetuint32(fin->file); + fin->creator = gbfgetuint32(fin->file); + fin->uid = gbfgetuint32(fin->file); + + if (fin->appinfo_offs < 0) { + pdb_invalid_file(fin, "Invalid application data offset (%0xh)", fin->appinfo_offs); + } + if (fin->index_offs < 0) { + pdb_invalid_file(fin, "Invalid index offset (%0xh)", fin->index_offs); + } + #if 0 - fprintf(stderr, "%s: dbname \"%s\"\n", MYNAME, fin->name); - fprintf(stderr, "%s: attr %-8x\n", MYNAME, fin->attr); - fprintf(stderr, "%s: creator %-8x\n", MYNAME, fin->creator); - fprintf(stderr, "%s: type %-8x\n", MYNAME, fin->type); - fprintf(stderr, "%s: ver %-8u\n", MYNAME, fin->version); - fprintf(stderr, "%s: app-ofs %-8u\n", MYNAME, fin->appinfo_offs); - fprintf(stderr, "%s: index-ofs %-8u\n", MYNAME, fin->index_offs); -#endif - /* ID = */ (void) gbfgetuint32(fin->file); - ct = fin->rec_ct = gbfgetint16(fin->file); - if (ct >= 0x7FFF) - warning(MYNAME ": Probably invalid number of records (%0d)\n", fin->rec_ct); - - offs = 78; - - last_rec = NULL; - for (i = 0; i < ct; i++) { - pdbrec_t *rec; - - rec = xcalloc(1, sizeof(*rec)); - if (fin->attr & PDB_FLAG_RESOURCE) { - (void) gbfgetuint32(fin->file); /* type */ - rec->id = gbfgetint16(fin->file); - rec->offs = gbfgetuint32(fin->file); - if ((gbint32)rec->offs < 0) - pdb_invalid_file(fin, "Invalid offset to record (%0d, id = %d)", rec->offs, rec->id); - } - else { - gbuint32 x; - - rec->offs = gbfgetint32(fin->file); - x = gbfgetuint32(fin->file); - rec->id = x & 0x0ffff; - rec->category = (x >> 24) & 0x0f; - rec->flags = (x >> 24) & 0xf0; - if ((gbint32)rec->offs < 0) - pdb_invalid_file(fin, "Invalid offset to resource record (%0d, id = %d)", rec->offs, rec->id); - } - - if (last_rec == NULL) - fin->rec_list = rec; - else - last_rec->next = rec; - last_rec = rec; - } - - offs += (ct * 8); - last_rec = fin->rec_list; - - if (fin->appinfo_offs != 0) { - gbuint32 top; - - /* seek to application info offset */ - while (offs < fin->appinfo_offs) { - (void)gbfgetc(fin->file); - offs++; - } - - /* determine the length of application info */ - if (fin->index_offs != 0) top = fin->index_offs; - else top = 0x7FFFFFFU; - if (last_rec && (last_rec->offs < top)) top = last_rec->offs; - - if (top != 0x7FFFFFFU) { - fin->appinfo = xmalloc(top - offs); - fin->appinfo_len = gbfread(fin->appinfo, 1, top - offs, fin->file); - offs += fin->appinfo_len; - } - else { - gbuint32 size; - fin->appinfo = pdb_read_tail(fin->file, &size); - fin->appinfo_len = size; - offs += size; - } - } - - for (rec = fin->rec_list; rec; rec = rec->next) { - /* seek to current record */ - while (offs < rec->offs) { - (void) gbfgetc(fin->file); - offs++; - } - if (rec->next) { - rec->size = (gbint32)rec->next->offs - (gbint32)offs; - if (rec->size > 0) { - rec->data = xmalloc(rec->size); - rec->size = gbfread(rec->data, 1, rec->size, fin->file); - offs += rec->size; - } - else if (rec->size < 0) - pdb_invalid_file(fin, "Wrong data size in record with id %d.\n", rec->id); - } - else { - rec->data = pdb_read_tail(fin->file, &rec->size); - offs += rec->size; - } - } + fprintf(stderr, "%s: dbname \"%s\"\n", MYNAME, fin->name); + fprintf(stderr, "%s: attr %-8x\n", MYNAME, fin->attr); + fprintf(stderr, "%s: creator %-8x\n", MYNAME, fin->creator); + fprintf(stderr, "%s: type %-8x\n", MYNAME, fin->type); + fprintf(stderr, "%s: ver %-8u\n", MYNAME, fin->version); + fprintf(stderr, "%s: app-ofs %-8u\n", MYNAME, fin->appinfo_offs); + fprintf(stderr, "%s: index-ofs %-8u\n", MYNAME, fin->index_offs); +#endif + /* ID = */ (void) gbfgetuint32(fin->file); + ct = fin->rec_ct = gbfgetint16(fin->file); + if (ct >= 0x7FFF) { + warning(MYNAME ": Probably invalid number of records (%0d)\n", fin->rec_ct); + } + + offs = 78; + + last_rec = NULL; + for (i = 0; i < ct; i++) { + pdbrec_t *rec; + + rec = (pdbrec_t*) xcalloc(1, sizeof(*rec)); + if (fin->attr & PDB_FLAG_RESOURCE) { + (void) gbfgetuint32(fin->file); /* type */ + rec->id = gbfgetint16(fin->file); + rec->offs = gbfgetuint32(fin->file); + if ((gbint32)rec->offs < 0) { + pdb_invalid_file(fin, "Invalid offset to record (%0d, id = %d)", rec->offs, rec->id); + } + } else { + gbuint32 x; + + rec->offs = gbfgetint32(fin->file); + x = gbfgetuint32(fin->file); + rec->id = x & 0x0ffff; + rec->category = (x >> 24) & 0x0f; + rec->flags = (x >> 24) & 0xf0; + if ((gbint32)rec->offs < 0) { + pdb_invalid_file(fin, "Invalid offset to resource record (%0d, id = %d)", rec->offs, rec->id); + } + } + + if (last_rec == NULL) { + fin->rec_list = rec; + } else { + last_rec->next = rec; + } + last_rec = rec; + } + + offs += (ct * 8); + last_rec = fin->rec_list; + + if (fin->appinfo_offs != 0) { + gbuint32 top; + + /* seek to application info offset */ + while (offs < fin->appinfo_offs) { + (void)gbfgetc(fin->file); + offs++; + } + + /* determine the length of application info */ + if (fin->index_offs != 0) { + top = fin->index_offs; + } else { + top = 0x7FFFFFFU; + } + if (last_rec && (last_rec->offs < top)) { + top = last_rec->offs; + } + + if (top != 0x7FFFFFFU) { + fin->appinfo = xmalloc(top - offs); + fin->appinfo_len = gbfread(fin->appinfo, 1, top - offs, fin->file); + offs += fin->appinfo_len; + } else { + gbuint32 size; + fin->appinfo = pdb_read_tail(fin->file, &size); + fin->appinfo_len = size; + offs += size; + } + } + + for (rec = fin->rec_list; rec; rec = rec->next) { + /* seek to current record */ + while (offs < rec->offs) { + (void) gbfgetc(fin->file); + offs++; + } + if (rec->next) { + rec->size = (gbint32)rec->next->offs - (gbint32)offs; + if (rec->size > 0) { + rec->data = (char*) xmalloc(rec->size); + rec->size = gbfread(rec->data, 1, rec->size, fin->file); + offs += rec->size; + } else if (rec->size < 0) { + pdb_invalid_file(fin, "Wrong data size in record with id %d.\n", rec->id); + } + } else { + rec->data = (char*) pdb_read_tail(fin->file, &rec->size); + offs += rec->size; + } + } } pdbfile * pdb_open(const char *filename, const char *module) { - pdbfile *res; - - res = xcalloc(1, sizeof(*res)); - res->file = gbfopen_be(filename, "rb", module); - res->mode = 1; - - pdb_load_data(res); - pdb_rewind(res); - - return res; + pdbfile *res; + + res = (pdbfile*) xcalloc(1, sizeof(*res)); + res->file = gbfopen_be(filename, "rb", module); + res->mode = 1; + + pdb_load_data(res); + pdb_rewind(res); + + return res; } int pdb_read_rec_by_id(pdbfile *fin, const gbuint32 rec_id, gbuint8 *flags, gbuint8 *category, void **data) { - pdbrec_t *rec; - - for (rec = fin->rec_list; rec; rec = rec->next) { - if (rec->id == rec_id) { - if (data) *data = rec->data; - if (flags) *flags = rec->flags; - if (category) *category = rec->category; - return rec->size; - } - } - return -1; + pdbrec_t *rec; + + for (rec = fin->rec_list; rec; rec = rec->next) { + if (rec->id == rec_id) { + if (data) { + *data = rec->data; + } + if (flags) { + *flags = rec->flags; + } + if (category) { + *category = rec->category; + } + return rec->size; + } + } + return -1; } pdbfile * pdb_create(const char *filename, const char *module) { - pdbfile *res; + pdbfile *res; - res = xcalloc(1, sizeof(*res)); - strncpy(res->name, "Palm/OS Database", PDB_DBNAMELEN); - res->file = gbfopen_be(filename, "wb", module);; - res->mode = 2; + res = (pdbfile*) xcalloc(1, sizeof(*res)); + strncpy(res->name, "Palm/OS Database", PDB_DBNAMELEN); + res->file = gbfopen_be(filename, "wb", module);; + res->mode = 2; - return res; + return res; } -void +void pdb_write_rec(pdbfile *fout, const gbuint8 flags, const gbuint8 category, const gbuint32 rec_id, const void *data, const gbuint32 size) { - pdbrec_t *rec, *cur; - - rec = xcalloc(1, sizeof(*rec)); - rec->category = category; - rec->flags = category; - rec->id = rec_id; - rec->size = size; - if (size > 0) { - rec->data = xmalloc(size); - memcpy(rec->data, data, size); - } - - /* insert rec into rec_list sorted by id */ - cur = fout->rec_list; - if (cur == NULL) fout->rec_list = rec; - else { - pdbrec_t *prev = NULL; - - while (cur) { - if (rec_id < cur->id) { - rec->next = cur; - if (prev == NULL) fout->rec_list = rec; - else prev->next = rec; - break; - } - else if (rec_id == cur->id) { /* Overwrite record with id ... */ - rec->next = cur->next; - if (prev == NULL) fout->rec_list = rec; - else prev->next = rec; - if (cur->data) xfree(cur->data); - xfree(cur); - cur = rec; - break; - } - prev = cur; - cur = cur->next; - } - if (! cur) { - if (prev == NULL) fout->rec_list = rec; - else prev->next = rec; - } - } - fout->rec_ct++; + pdbrec_t *rec, *cur; + + rec = (pdbrec_t*) xcalloc(1, sizeof(*rec)); + rec->category = category; + rec->flags = category; + rec->id = rec_id; + rec->size = size; + if (size > 0) { + rec->data = (char*) xmalloc(size); + memcpy(rec->data, data, size); + } + + /* insert rec into rec_list sorted by id */ + cur = fout->rec_list; + if (cur == NULL) { + fout->rec_list = rec; + } else { + pdbrec_t *prev = NULL; + + while (cur) { + if (rec_id < cur->id) { + rec->next = cur; + if (prev == NULL) { + fout->rec_list = rec; + } else { + prev->next = rec; + } + break; + } else if (rec_id == cur->id) { /* Overwrite record with id ... */ + rec->next = cur->next; + if (prev == NULL) { + fout->rec_list = rec; + } else { + prev->next = rec; + } + if (cur->data) { + xfree(cur->data); + } + xfree(cur); + cur = rec; + break; + } + prev = cur; + cur = cur->next; + } + if (! cur) { + if (prev == NULL) { + fout->rec_list = rec; + } else { + prev->next = rec; + } + } + } + fout->rec_ct++; } /* all data was buffered, write now to file */ @@ -303,129 +332,147 @@ pdb_write_rec(pdbfile *fout, const gbuint8 flags, const gbuint8 category, const static void pdb_flush(pdbfile *file) { - pdbrec_t *rec; - gbfile *fout = file->file; - int len, offs; - - offs = 78; - file->index_offs = 0; - offs += (file->rec_ct * 8); - - offs += 2; - - if (file->appinfo && (file->appinfo_len > 0)) { - file->appinfo_offs = offs; - offs += file->appinfo_len; - } - else - file->appinfo_offs = 0; - - rec = file->rec_list; - while (rec) { /* prepare data records */ - rec->offs = offs; - offs += rec->size; - rec = rec->next; - } - - len = strlen(file->name); - gbfwrite(file->name, 1, len, fout); - while (len++ < PDB_DBNAMELEN) gbfputc(0, fout); - - gbfputuint16(file->attr, fout); - gbfputuint16(file->version, fout); - gbfputuint32(file->ctime, fout); - gbfputuint32(file->mtime, fout); - gbfputuint32(file->btime, fout); - gbfputuint32(file->revision, fout); - gbfputuint32(file->appinfo_offs, fout); - gbfputuint32(file->index_offs, fout); - gbfputuint32(file->type, fout); - gbfputuint32(file->creator, fout); - gbfputuint32(file->uid, fout); - - gbfputuint32(0, fout); /* ? ID ? */ - gbfputuint16(file->rec_ct, fout); - - for (rec = file->rec_list; rec; rec = rec->next) { - gbuint32 attr; - - gbfputint32(rec->offs, fout); - attr = (rec->category & 0x0f) | (rec->flags & 0xf0); - gbfputint32((rec->id & 0x0ffffff) | (attr << 24), fout); - } - gbfputint16(0, fout); - - if (file->appinfo && (file->appinfo_len > 0)) { - gbfwrite(file->appinfo, 1, file->appinfo_len, fout); - } - - for (rec = file->rec_list; rec; rec = rec->next) { - if (rec->size > 0) - gbfwrite(rec->data, 1, rec->size, fout); - } + pdbrec_t *rec; + gbfile *fout = file->file; + int len, offs; + + offs = 78; + file->index_offs = 0; + offs += (file->rec_ct * 8); + + offs += 2; + + if (file->appinfo && (file->appinfo_len > 0)) { + file->appinfo_offs = offs; + offs += file->appinfo_len; + } else { + file->appinfo_offs = 0; + } + + rec = file->rec_list; + while (rec) { /* prepare data records */ + rec->offs = offs; + offs += rec->size; + rec = rec->next; + } + + len = strlen(file->name); + gbfwrite(file->name, 1, len, fout); + while (len++ < PDB_DBNAMELEN) { + gbfputc(0, fout); + } + + gbfputuint16(file->attr, fout); + gbfputuint16(file->version, fout); + gbfputuint32(file->ctime, fout); + gbfputuint32(file->mtime, fout); + gbfputuint32(file->btime, fout); + gbfputuint32(file->revision, fout); + gbfputuint32(file->appinfo_offs, fout); + gbfputuint32(file->index_offs, fout); + gbfputuint32(file->type, fout); + gbfputuint32(file->creator, fout); + gbfputuint32(file->uid, fout); + + gbfputuint32(0, fout); /* ? ID ? */ + gbfputuint16(file->rec_ct, fout); + + for (rec = file->rec_list; rec; rec = rec->next) { + gbuint32 attr; + + gbfputint32(rec->offs, fout); + attr = (rec->category & 0x0f) | (rec->flags & 0xf0); + gbfputint32((rec->id & 0x0ffffff) | (attr << 24), fout); + } + gbfputint16(0, fout); + + if (file->appinfo && (file->appinfo_len > 0)) { + gbfwrite(file->appinfo, 1, file->appinfo_len, fout); + } + + for (rec = file->rec_list; rec; rec = rec->next) { + if (rec->size > 0) { + gbfwrite(rec->data, 1, rec->size, fout); + } + } } void pdb_close(pdbfile *file) { - pdbrec_t *rec; - - if (! file) return; - - if (file->mode & 2) { + pdbrec_t *rec; + + if (! file) { + return; + } + + if (file->mode & 2) { #if 0 - /* this can be done later */ - if (gpsbabel_time == 0) { /* !!! We are in testo !!! */ - file->ctime = 0; /* (now we also can do a bincompare) */ - file->mtime = 0; - file->btime = 0; - } + /* this can be done later */ + if (gpsbabel_time == 0) { /* !!! We are in testo !!! */ + file->ctime = 0; /* (now we also can do a bincompare) */ + file->mtime = 0; + file->btime = 0; + } #endif - pdb_flush(file); - } - - gbfclose(file->file); - - if ((file->mode & 1) && file->appinfo) xfree(file->appinfo); - - rec = file->rec_list; - while (rec) { - pdbrec_t *tmp = rec; - rec = rec->next; - - if (tmp->data) xfree(tmp->data); - xfree(tmp); - } - xfree(file); + pdb_flush(file); + } + + gbfclose(file->file); + + if ((file->mode & 1) && file->appinfo) { + xfree(file->appinfo); + } + + rec = file->rec_list; + while (rec) { + pdbrec_t *tmp = rec; + rec = rec->next; + + if (tmp->data) { + xfree(tmp->data); + } + xfree(tmp); + } + xfree(file); } int pdb_eof(pdbfile *fin) { - return (fin->rec_curr) ? 0 : 1; + return (fin->rec_curr) ? 0 : 1; } int pdb_read_rec(pdbfile *fin, gbuint8 *flags, gbuint8 *category, gbuint32 *rec_id, void **data) { - if (pdb_eof(fin)) return -1; - else { - pdbrec_t *rec = fin->rec_curr; - fin->rec_curr = rec->next; - - if (data) *data = rec->data; - if (flags) *flags = rec->flags; - if (category) *category = rec->category; - if (rec_id) *rec_id = rec->id; - - return rec->size; - } + if (pdb_eof(fin)) { + return -1; + } else { + pdbrec_t *rec = fin->rec_curr; + fin->rec_curr = rec->next; + + if (data) { + *data = rec->data; + } + if (flags) { + *flags = rec->flags; + } + if (category) { + *category = rec->category; + } + if (rec_id) { + *rec_id = rec->id; + } + + return rec->size; + } } void pdb_rewind(pdbfile *fin) { - fin->rec_curr = fin->rec_list; + fin->rec_curr = fin->rec_list; } #endif diff --git a/gpsbabel/pdbfile.h b/gpsbabel/pdbfile.h index b1c652f04..e8a409f80 100644 --- a/gpsbabel/pdbfile.h +++ b/gpsbabel/pdbfile.h @@ -4,7 +4,7 @@ Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org Written after study the Coldsync project - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -39,46 +39,46 @@ #define EPOCH_1904 2082844800L typedef struct pdbrec_s { - gbuint32 offs; - gbuint32 size; - gbuint32 id; - gbuint8 category; - gbuint8 flags; - char *data; - struct pdbrec_s *next; + gbuint32 offs; + gbuint32 size; + gbuint32 id; + gbuint8 category; + gbuint8 flags; + char* data; + struct pdbrec_s* next; } pdbrec_t; typedef struct { - gbfile *file; - char mode; /* file-mode: 1 = read / 2 = write */ - char name[PDB_DBNAMELEN + 1]; /* database name */ - gbuint16 attr; /* attributes */ - gbuint16 version; /* version */ - time_t ctime; /* creation time */ - time_t mtime; /* modification time */ - time_t btime; /* backup time */ - gbuint32 revision; - gbuint32 appinfo_offs; /* offset to application info */ - gbuint32 index_offs; /* offset to sort-index info */ - gbuint32 creator; - gbuint32 type; - gbuint32 uid; - gbuint16 rec_ct; - struct pdbrec_s *rec_list; - struct pdbrec_s *rec_curr; - void *appinfo; - int appinfo_len; + gbfile* file; + char mode; /* file-mode: 1 = read / 2 = write */ + char name[PDB_DBNAMELEN + 1]; /* database name */ + gbuint16 attr; /* attributes */ + gbuint16 version; /* version */ + time_t ctime; /* creation time */ + time_t mtime; /* modification time */ + time_t btime; /* backup time */ + gbuint32 revision; + gbuint32 appinfo_offs; /* offset to application info */ + gbuint32 index_offs; /* offset to sort-index info */ + gbuint32 creator; + gbuint32 type; + gbuint32 uid; + gbuint16 rec_ct; + struct pdbrec_s* rec_list; + struct pdbrec_s* rec_curr; + void* appinfo; + int appinfo_len; } pdbfile; -pdbfile *pdb_open(const char *filename, const char *module); -pdbfile *pdb_create(const char *filename, const char *module); -void pdb_close(pdbfile *file); -int pdb_eof(pdbfile *fin); -void pdb_rewind(pdbfile *fin); -int pdb_read_rec(pdbfile *fin, gbuint8 *flags, gbuint8 *category, gbuint32 *rec_id, void **data); -int pdb_read_rec_by_id(pdbfile *fin, const gbuint32 rec_id, gbuint8 *flags, gbuint8 *category, void **data); -void pdb_write_rec(pdbfile *fout, const gbuint8 flags, const gbuint8 category, const gbuint32 rec_id, const void *data, const gbuint32 size); +pdbfile* pdb_open(const char* filename, const char* module); +pdbfile* pdb_create(const char* filename, const char* module); +void pdb_close(pdbfile* file); +int pdb_eof(pdbfile* fin); +void pdb_rewind(pdbfile* fin); +int pdb_read_rec(pdbfile* fin, gbuint8* flags, gbuint8* category, gbuint32* rec_id, void** data); +int pdb_read_rec_by_id(pdbfile* fin, const gbuint32 rec_id, gbuint8* flags, gbuint8* category, void** data); +void pdb_write_rec(pdbfile* fout, const gbuint8 flags, const gbuint8 category, const gbuint32 rec_id, const void* data, const gbuint32 size); #endif #endif diff --git a/gpsbabel/pocketfms_bc.c b/gpsbabel/pocketfms_bc.c index 588b83dc8..e7f788492 100755 --- a/gpsbabel/pocketfms_bc.c +++ b/gpsbabel/pocketfms_bc.c @@ -26,29 +26,29 @@ static char header_id[] = "BRC"; typedef struct breadcrumb { - // header - char id[4]; // 0x42 0x52 0x43 0x00 <=> "BRC" - gbuint16 version; // 0x0100 - gbuint16 reserve1; // 0x0000 - // data - float latitude; - float longitude; - float altitude; // meter - float speed; // m/s - float course; // degrees - float magvar; // degrees - float separation; // meter - float ehpe; // estimated horizontal position error - float evpe; // estimated vertical position error - float espe; // estimated speed position error - gbuint16 fix; // 1..none, 2..2D, 3..3D, 4..dgps, 5pps - gbuint16 year; // 1999..2999 - gbuint16 month; // 1..12 - gbuint16 day; // 0..31 - gbuint16 hour; // 0.23 - gbuint16 minute; // 0..59 - gbuint16 second; // 0..59 - gbuint16 reserve2; // 0x0000 + // header + char id[4]; // 0x42 0x52 0x43 0x00 <=> "BRC" + gbuint16 version; // 0x0100 + gbuint16 reserve1; // 0x0000 + // data + float latitude; + float longitude; + float altitude; // meter + float speed; // m/s + float course; // degrees + float magvar; // degrees + float separation; // meter + float ehpe; // estimated horizontal position error + float evpe; // estimated vertical position error + float espe; // estimated speed position error + gbuint16 fix; // 1..none, 2..2D, 3..3D, 4..dgps, 5pps + gbuint16 year; // 1999..2999 + gbuint16 month; // 1..12 + gbuint16 day; // 0..31 + gbuint16 hour; // 0.23 + gbuint16 minute; // 0..59 + gbuint16 second; // 0..59 + gbuint16 reserve2; // 0x0000 } BREADCRUMB; static gbfile *file_in, *file_out; @@ -56,67 +56,68 @@ static gbfile *file_in, *file_out; static void rd_init(const char *fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } static void read_tracks(void) { - struct breadcrumb bc; - route_head *trk_head = route_head_alloc(); - trk_head->rte_num = 1; - trk_head->rte_name = xstrdup("PocketFMS"); - trk_head->rte_desc = xstrdup("Breadcrumb"); - trk_head->rte_url = xstrdup("www.pocketfms.com"); - track_add_head(trk_head); - - while (1 == gbfread(&bc, sizeof (bc), 1, file_in)) { - struct tm tm; - waypoint *wpt; - - if (strcmp (bc.id, header_id) != 0) - fatal(MYNAME ": invalid breadcrumb header in input file.\n"); - - memset(&tm, 0, sizeof (tm)); - tm.tm_year = le_readu16(&bc.year)-1900; - tm.tm_mon = le_readu16(&bc.month)-1; - tm.tm_mday = le_readu16(&bc.day); - tm.tm_hour = le_readu16(&bc.hour); - tm.tm_min = le_readu16(&bc.minute); - tm.tm_sec = le_readu16(&bc.second); - - wpt = waypt_new(); - wpt->latitude = le_read_float(&bc.latitude); - wpt->longitude = le_read_float(&bc.longitude); - wpt->altitude = FEET_TO_METERS(le_read_float(&bc.altitude)); - wpt->creation_time = mkgmtime(&tm); - wpt->hdop = le_read_float(&bc.ehpe); - wpt->vdop = le_read_float(&bc.evpe); - wpt->pdop = le_read_float(&bc.espe); - wpt->course = le_read_float(&bc.course); - wpt->speed = le_read_float(&bc.speed); - wpt->fix = le_readu16(&bc.fix) - 1; - - track_add_wpt(trk_head, wpt); - } + struct breadcrumb bc; + route_head *trk_head = route_head_alloc(); + trk_head->rte_num = 1; + trk_head->rte_name = xstrdup("PocketFMS"); + trk_head->rte_desc = xstrdup("Breadcrumb"); + trk_head->rte_url = xstrdup("www.pocketfms.com"); + track_add_head(trk_head); + + while (1 == gbfread(&bc, sizeof(bc), 1, file_in)) { + struct tm tm; + waypoint *wpt; + + if (strcmp(bc.id, header_id) != 0) { + fatal(MYNAME ": invalid breadcrumb header in input file.\n"); + } + + memset(&tm, 0, sizeof(tm)); + tm.tm_year = le_readu16(&bc.year)-1900; + tm.tm_mon = le_readu16(&bc.month)-1; + tm.tm_mday = le_readu16(&bc.day); + tm.tm_hour = le_readu16(&bc.hour); + tm.tm_min = le_readu16(&bc.minute); + tm.tm_sec = le_readu16(&bc.second); + + wpt = waypt_new(); + wpt->latitude = le_read_float(&bc.latitude); + wpt->longitude = le_read_float(&bc.longitude); + wpt->altitude = FEET_TO_METERS(le_read_float(&bc.altitude)); + wpt->creation_time = mkgmtime(&tm); + wpt->hdop = le_read_float(&bc.ehpe); + wpt->vdop = le_read_float(&bc.evpe); + wpt->pdop = le_read_float(&bc.espe); + wpt->course = le_read_float(&bc.course); + wpt->speed = le_read_float(&bc.speed); + wpt->fix = (fix_type) (le_readu16(&bc.fix) - 1); + + track_add_wpt(trk_head, wpt); + } } static void @@ -127,64 +128,64 @@ route_head_noop(const route_head *wp) static void pocketfms_waypt_disp(const waypoint *wpt) { - struct breadcrumb bc; - struct tm *tm; - - memset (&bc, 0, sizeof (bc)); - tm = localtime(&wpt->creation_time); - if (wpt->creation_time) { - tm = gmtime(&wpt->creation_time); - } - - strcpy (bc.id, header_id); - le_write16(&bc.version, 1); - le_write_float(&bc.latitude, wpt->latitude); - le_write_float(&bc.longitude, wpt->longitude); - le_write_float(&bc.altitude, METERS_TO_FEET(wpt->altitude)); - if (tm) { - le_write16(&bc.year, tm->tm_year + 1900); - le_write16(&bc.month, tm->tm_mon + 1); - le_write16(&bc.day, tm->tm_mday); - le_write16(&bc.hour, tm->tm_hour); - le_write16(&bc.minute, tm->tm_min); - le_write16(&bc.second, tm->tm_sec); - } - le_write_float(&bc.ehpe, wpt->hdop); - le_write_float(&bc.evpe, wpt->vdop); - le_write_float(&bc.espe, wpt->pdop); - le_write_float(&bc.course, wpt->course); - le_write_float(&bc.speed, wpt->speed); - le_write16(&bc.fix, wpt->fix+1); - - gbfwrite(&bc, sizeof (bc), 1, file_out); + struct breadcrumb bc; + struct tm *tm; + + memset(&bc, 0, sizeof(bc)); + tm = localtime(&wpt->creation_time); + if (wpt->creation_time) { + tm = gmtime(&wpt->creation_time); + } + + strcpy(bc.id, header_id); + le_write16(&bc.version, 1); + le_write_float(&bc.latitude, wpt->latitude); + le_write_float(&bc.longitude, wpt->longitude); + le_write_float(&bc.altitude, METERS_TO_FEET(wpt->altitude)); + if (tm) { + le_write16(&bc.year, tm->tm_year + 1900); + le_write16(&bc.month, tm->tm_mon + 1); + le_write16(&bc.day, tm->tm_mday); + le_write16(&bc.hour, tm->tm_hour); + le_write16(&bc.minute, tm->tm_min); + le_write16(&bc.second, tm->tm_sec); + } + le_write_float(&bc.ehpe, wpt->hdop); + le_write_float(&bc.evpe, wpt->vdop); + le_write_float(&bc.espe, wpt->pdop); + le_write_float(&bc.course, wpt->course); + le_write_float(&bc.speed, wpt->speed); + le_write16(&bc.fix, wpt->fix+1); + + gbfwrite(&bc, sizeof(bc), 1, file_out); } static void data_read(void) { - read_tracks(); + read_tracks(); } static void data_write(void) { - track_disp_all(route_head_noop, route_head_noop, pocketfms_waypt_disp); + track_disp_all(route_head_noop, route_head_noop, pocketfms_waypt_disp); } ff_vecs_t pocketfms_bc_vecs = { - ff_type_file, - { - ff_cap_none, /* waypoints */ - ff_cap_read | ff_cap_write, /* tracks */ - ff_cap_none /* routes */ - }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_none, /* waypoints */ + (ff_cap)(ff_cap_read | ff_cap_write), /* tracks */ + ff_cap_none /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/pocketfms_fp.c b/gpsbabel/pocketfms_fp.c index f67173686..c25b1c4c0 100755 --- a/gpsbabel/pocketfms_fp.c +++ b/gpsbabel/pocketfms_fp.c @@ -33,158 +33,164 @@ static xg_callback wpt_s, wpt_from_lat, wpt_from_lon, wpt_from_name, wpt_from_el static xg_callback wpt_e, wpt_to_lat, wpt_to_lon, wpt_to_name, wpt_to_elev, wpt_altitude; static xg_tag_mapping gl_map[] = { - { wpt_s, cb_start, "/PocketFMSFlightplan/LIB" }, - { wpt_from_lat, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Latitude" }, - { wpt_from_lon, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Longitude" }, - { wpt_from_elev, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Elevation" }, - { wpt_from_name, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/FriendlyShortname" }, - { wpt_to_lat, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Latitude" }, - { wpt_to_lon, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Longitude" }, - { wpt_to_name, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/FriendlyShortname" }, - { wpt_to_elev, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Elevation" }, - { wpt_altitude, cb_start, "/PocketFMSFlightplan/LIB/PlannedAltitude" }, - { wpt_e, cb_end, "/PocketFMSFlightplan/LIB" }, - { NULL, 0, NULL} + { wpt_s, cb_start, "/PocketFMSFlightplan/LIB" }, + { wpt_from_lat, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Latitude" }, + { wpt_from_lon, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Longitude" }, + { wpt_from_elev, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Elevation" }, + { wpt_from_name, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/FriendlyShortname" }, + { wpt_to_lat, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Latitude" }, + { wpt_to_lon, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Longitude" }, + { wpt_to_name, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/FriendlyShortname" }, + { wpt_to_elev, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Elevation" }, + { wpt_altitude, cb_start, "/PocketFMSFlightplan/LIB/PlannedAltitude" }, + { wpt_e, cb_end, "/PocketFMSFlightplan/LIB" }, + { NULL, (xg_cb_type)0, NULL} }; static void rd_init(const char *fname) { - xml_init(fname, gl_map, NULL); + xml_init(fname, gl_map, NULL); } static void data_read(void) { - xml_read(); + xml_read(); } static void rd_deinit(void) { - if (route != NULL) - { - waypoint *head = (waypoint *) QUEUE_FIRST(&route->waypoint_list); - waypoint *tail = (waypoint *) QUEUE_LAST(&route->waypoint_list); - if (head != NULL) - route->rte_name = xstrdup (head->shortname); - route->rte_name = xstrappend(route->rte_name, " - "); - if (tail != NULL) - { - route->rte_name = xstrappend(route->rte_name, tail->shortname); - tail->altitude = dest_altitude; - } - } - xml_deinit(); + if (route != NULL) { + waypoint *head = (waypoint *) QUEUE_FIRST(&route->waypoint_list); + waypoint *tail = (waypoint *) QUEUE_LAST(&route->waypoint_list); + if (head != NULL) { + route->rte_name = xstrdup(head->shortname); + } + route->rte_name = xstrappend(route->rte_name, " - "); + if (tail != NULL) { + route->rte_name = xstrappend(route->rte_name, tail->shortname); + tail->altitude = dest_altitude; + } + } + xml_deinit(); } static void wr_init(const char *fname) { - fatal("Writing file of type %s is not supported\n", MYNAME); + fatal("Writing file of type %s is not supported\n", MYNAME); } void wpt_s(const char *args, const char **unused) { - if (isFirst == 1) { - wpt_from = waypt_new(); - route = route_head_alloc(); - route->rte_desc=xstrdup("PocketFMS flightplan"); - route_add_head(route); - } - wpt_to = waypt_new(); + if (isFirst == 1) { + wpt_from = waypt_new(); + route = route_head_alloc(); + route->rte_desc=xstrdup("PocketFMS flightplan"); + route_add_head(route); + } + wpt_to = waypt_new(); } void wpt_e(const char *args, const char **unused) { - if (isFirst == 1) { - route_add_wpt(route, wpt_from); - if (doing_wpts) - waypt_add(waypt_dupe(wpt_from)); - wpt_from = NULL; - isFirst = 0; - } - route_add_wpt(route, wpt_to); - if (doing_wpts) - waypt_add(waypt_dupe(wpt_to)); - wpt_to = NULL; + if (isFirst == 1) { + route_add_wpt(route, wpt_from); + if (doing_wpts) { + waypt_add(waypt_dupe(wpt_from)); + } + wpt_from = NULL; + isFirst = 0; + } + route_add_wpt(route, wpt_to); + if (doing_wpts) { + waypt_add(waypt_dupe(wpt_to)); + } + wpt_to = NULL; } void wpt_from_lat(const char *args, const char **unused) { - if (wpt_from != NULL) - wpt_from->latitude = atof(args); + if (wpt_from != NULL) { + wpt_from->latitude = atof(args); + } } void wpt_from_lon(const char *args, const char **unused) { - if (wpt_from != NULL) - wpt_from->longitude = atof(args); + if (wpt_from != NULL) { + wpt_from->longitude = atof(args); + } } void wpt_from_name(const char *args, const char **unused) { - if (wpt_from != NULL) - wpt_from->shortname = xstrappend(wpt_from->shortname, args); + if (wpt_from != NULL) { + wpt_from->shortname = xstrappend(wpt_from->shortname, args); + } } void wpt_from_elev(const char *args, const char **unused) { - if (wpt_from != NULL) - wpt_from->altitude = FEET_TO_METERS(atof(args)); + if (wpt_from != NULL) { + wpt_from->altitude = FEET_TO_METERS(atof(args)); + } } void wpt_to_lat(const char *args, const char **unused) { - wpt_to->latitude = atof(args); + wpt_to->latitude = atof(args); } void wpt_to_lon(const char *args, const char **unused) { - wpt_to->longitude = atof(args); + wpt_to->longitude = atof(args); } void wpt_to_name(const char *args, const char **unused) { - wpt_to->shortname = xstrappend(wpt_to->shortname, args); + wpt_to->shortname = xstrappend(wpt_to->shortname, args); } void wpt_to_elev(const char *args, const char **unused) { - dest_altitude = FEET_TO_METERS(atof(args)); + dest_altitude = FEET_TO_METERS(atof(args)); } void wpt_altitude(const char *args, const char **attrv) { - int isFeet = 0; - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "Value")) { - wpt_to->altitude = atof(avp[1]); - } - if (0 == strcmp(avp[0], "Unit")) { - isFeet = strcmp (avp[1], "ft") == 0 ? 1 : 0; - } - avp += 2; - } - if (isFeet) - wpt_to->altitude = FEET_TO_METERS(wpt_to->altitude); + int isFeet = 0; + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "Value")) { + wpt_to->altitude = atof(avp[1]); + } + if (0 == strcmp(avp[0], "Unit")) { + isFeet = strcmp(avp[1], "ft") == 0 ? 1 : 0; + } + avp += 2; + } + if (isFeet) { + wpt_to->altitude = FEET_TO_METERS(wpt_to->altitude); + } } ff_vecs_t pocketfms_fp_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_read /* routes */ - }, - rd_init, - wr_init, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/pocketfms_wp.c b/gpsbabel/pocketfms_wp.c index c51c2e283..8f53fed63 100755 --- a/gpsbabel/pocketfms_wp.c +++ b/gpsbabel/pocketfms_wp.c @@ -1,129 +1,126 @@ -/* - PocketFMS waypoint text files (wpt). - - Copyright (C) 2009 Tobias Kretschmar, tobias.kretschmar@gmx.de - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA - */ - -#include "defs.h" -#include "csv_util.h" - -#define MYNAME "PocketFMS waypoint text file format" - -static gbfile *file_in, *file_out; - -static void -rd_init(const char *fname) -{ - file_in = gbfopen_le(fname, "r", MYNAME); -} - -double wppos_to_dec(char *value) -{ - if (strstr(value, "°") == NULL) - return atof(value); - else - { - int degrees, minutes; - float seconds; - int sign = 1; - - if (toupper(value[0]) == 'N' || toupper(value[0]) == 'E' || value[0] == '+') - { - value = &value[1]; - } - else if (toupper(value[0]) == 'S' || toupper(value[0]) == 'W' || value[0] == '-') - { - value = &value[1]; - sign = -1; - } - - sscanf(value, "%d°%d'%f\"", °rees, &minutes, &seconds); - return sign * (degrees + ((float)minutes / 60) + (seconds / 3600)); - } -} - -static void -data_read(void) -{ - char *buff; - int linecount = 0; - while ((buff = gbfgetstr(file_in))) { - char *s; - waypoint *wpt; - rtrim(buff); - if (strlen(buff) == 0) - break; - linecount++; - wpt = waypt_new(); - s = buff; - s = csv_lineparse(s, "\\w", "", linecount); - wpt->shortname = xstrdup(s); - s = csv_lineparse(NULL, "\\w", "", linecount); - wpt->latitude = wppos_to_dec(s); - s = csv_lineparse(NULL, "\\w", "", linecount); - wpt->longitude = wppos_to_dec(s); - waypt_add(wpt); - } -} - -static void -rd_deinit(void) -{ - gbfclose(file_in); -} - -static void -wr_init(const char *fname) -{ - file_out = gbfopen_le(fname, "w", MYNAME); -} - -static void -enigma_waypt_disp(const waypoint *wpt) -{ - gbfprintf(file_out, "%s %f %f\n", wpt->shortname, wpt->latitude, wpt->longitude); -} - -static void -data_write(void) -{ - waypt_disp_all(enigma_waypt_disp); -} - -static void -wr_deinit(void) -{ - gbfclose(file_out); -} - -ff_vecs_t pocketfms_wp_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write, /* waypoints */ - ff_cap_none, /* tracks */ - ff_cap_none, /* routes */ - }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ -}; +/* + PocketFMS waypoint text files (wpt). + + Copyright (C) 2009 Tobias Kretschmar, tobias.kretschmar@gmx.de + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include "defs.h" +#include "csv_util.h" + +#define MYNAME "PocketFMS waypoint text file format" + +static gbfile *file_in, *file_out; + +static void +rd_init(const char *fname) +{ + file_in = gbfopen_le(fname, "r", MYNAME); +} + +double wppos_to_dec(char *value) +{ + if (strstr(value, "°") == NULL) { + return atof(value); + } else { + int degrees, minutes; + float seconds; + int sign = 1; + + if (toupper(value[0]) == 'N' || toupper(value[0]) == 'E' || value[0] == '+') { + value = &value[1]; + } else if (toupper(value[0]) == 'S' || toupper(value[0]) == 'W' || value[0] == '-') { + value = &value[1]; + sign = -1; + } + + sscanf(value, "%d°%d'%f\"", °rees, &minutes, &seconds); + return sign * (degrees + ((float)minutes / 60) + (seconds / 3600)); + } +} + +static void +data_read(void) +{ + char *buff; + int linecount = 0; + while ((buff = gbfgetstr(file_in))) { + char *s; + waypoint *wpt; + rtrim(buff); + if (strlen(buff) == 0) { + break; + } + linecount++; + wpt = waypt_new(); + s = buff; + s = csv_lineparse(s, "\\w", "", linecount); + wpt->shortname = xstrdup(s); + s = csv_lineparse(NULL, "\\w", "", linecount); + wpt->latitude = wppos_to_dec(s); + s = csv_lineparse(NULL, "\\w", "", linecount); + wpt->longitude = wppos_to_dec(s); + waypt_add(wpt); + } +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen_le(fname, "w", MYNAME); +} + +static void +enigma_waypt_disp(const waypoint *wpt) +{ + gbfprintf(file_out, "%s %f %f\n", wpt->shortname, wpt->latitude, wpt->longitude); +} + +static void +data_write(void) +{ + waypt_disp_all(enigma_waypt_disp); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); +} + +ff_vecs_t pocketfms_wp_vecs = { + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write), /* waypoints */ + ff_cap_none, /* tracks */ + ff_cap_none, /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/gpsbabel/polygon.c b/gpsbabel/polygon.c index 5f2abce18..7ec0acbde 100644 --- a/gpsbabel/polygon.c +++ b/gpsbabel/polygon.c @@ -1,6 +1,6 @@ /* Inside/Outside polygon filter - + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -28,70 +28,70 @@ static char *polyfileopt = NULL; static char *exclopt = NULL; /* - * This test for insideness is essentially an odd/even test. The + * This test for insideness is essentially an odd/even test. The * traditional (simple) implementation of the odd/even test counts - * intersections along a test ray, and if it should happen to exactly hit - * a vertex of the polygon, it throws away the result and fires a different + * intersections along a test ray, and if it should happen to exactly hit + * a vertex of the polygon, it throws away the result and fires a different * test ray. Since we're potentially testing hundreds of test points against * a polygon with hundreds of sides, this seemed both wasteful and difficult * to coordinate, so instead I added extra state to try to figure out what we - * would have seen if we had just missed the vertex. The result is the + * would have seen if we had just missed the vertex. The result is the * hodgepodge of "limbo" states explained below. On the credit side of the * ledger, though, the tests for intersection are vastly simplified by always * having a horizontal test ray. - * - * The general structure of this filter is: we loop over the points in the + * + * The general structure of this filter is: we loop over the points in the * polygon. For each point, we update the state of each of the waypoints in * the test set. Thus, the state of every waypoint is indeterminate until - * the end of the outer loop, at which point the state of every waypoint + * the end of the outer loop, at which point the state of every waypoint * should theoretically be completely determined. - * - * The bits following this comment encode the current state of the test point - * as we go around the polygon. OUTSIDE clearly isn't a bit; it's just here - * for completeness. If it's not INSIDE, and it's not something else, it's + * + * The bits following this comment encode the current state of the test point + * as we go around the polygon. OUTSIDE clearly isn't a bit; it's just here + * for completeness. If it's not INSIDE, and it's not something else, it's * clearly OUTSIDE. - * - * INSIDE is self-explanatory. What it means is that the last time we were - * certain of our state, we were inside of the polygon. - * - * LIMBO encodes a bit more state information, to handle the case where our + * + * INSIDE is self-explanatory. What it means is that the last time we were + * certain of our state, we were inside of the polygon. + * + * LIMBO encodes a bit more state information, to handle the case where our * test ray (a horizontal line) has intersected one of the vertices of the - * polygon exactly. If the two lines that meet at that vertex are on + * polygon exactly. If the two lines that meet at that vertex are on * opposite sides of the test ray, it was an intersection. Otherwise, it just - * grazed a local minimum or maximum and so counted as either zero or two - * intersections - not a change in state. Horizontal lines encountered + * grazed a local minimum or maximum and so counted as either zero or two + * intersections - not a change in state. Horizontal lines encountered * while in limbo don't change the limbo state. All other lines do. * The rest of the bits talk about how we got into limbo, and thus what to do * when we get out of limbo. - * + * * LIMBO_UP means that the last line segment we saw going into limbo was * headed upward. When we see another non-horizontal line segment, whether * we flip the INSIDE bit or not depends on whether it also goes upward. If * it does, we flip the INSIDE bit. Otherwise, we just clear our limbo state * and go on as if nothing had happened. - * - * LIMBO_BEGIN means that the very first vertex in the polygon put us into a + * + * LIMBO_BEGIN means that the very first vertex in the polygon put us into a * limbo state. We won't be able to resolve that limbo state until we get to * the end of the cycle, and it can actually coexist with another more local - * limbo state. The next two bits talk about the beginning limbo state in + * limbo state. The next two bits talk about the beginning limbo state in * more detail. - * + * * BEGIN_UP means that the first non-horizontal line segment we encountered * while in a LIMBO_BEGIN state went upward. As with LIMBO_UP, this is used - * to determine the final disposition of the limbo state when we get back + * to determine the final disposition of the limbo state when we get back * around to the other end of the cycle. - * + * * BEGIN_HOR is fairly temporary. It says that we've encountered one or more * horizontal line segments at the beginning of the cycle, so we haven't yet * been able to resolve the state of BEGIN_UP. It's a way of propagating the * "firstness" forward until we can make a decision, without propagating it * for every test point. - * - * UP is used to remember which way we were going in case we encounter a - * limbo state. - * - * -- RLP - */ + * + * UP is used to remember which way we were going in case we encounter a + * limbo state. + * + * -- RLP + */ #define OUTSIDE 0 #define INSIDE 1 @@ -103,262 +103,252 @@ static char *exclopt = NULL; #define UP 64 typedef struct { - unsigned short state; - unsigned short override; + unsigned short state; + unsigned short override; } extra_data; static arglist_t polygon_args[] = { - {"file", &polyfileopt, "File containing vertices of polygon", - NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"exclude", &exclopt, "Exclude points inside the polygon", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "file", &polyfileopt, "File containing vertices of polygon", + NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "exclude", &exclopt, "Exclude points inside the polygon", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static void polytest ( double lat1, double lon1, - double lat2, double lon2, - double wlat, double wlon, - unsigned short *state, int first, int last ) { - - if ( lat1 == wlat ) { - if ( lat2 < wlat ) { - /* going down */ - if (*state & LIMBO) { - if ( *state & LIMBO_UP ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO &~LIMBO_UP; - } - else if (*state & LIMBO_BEGIN) { - if ( *state & BEGIN_HOR ) { - *state = *state & ~BEGIN_HOR; - } - else if ( last ) { - if ( *state & BEGIN_UP ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; - } - } - else if ( first && (lon1 > wlon)) { - *state |= LIMBO_BEGIN; - } - } - else if ( lat2 == wlat ) { - if ( first & (lon1 > wlon || lon2 > wlon)) { - *state |= LIMBO_BEGIN | BEGIN_HOR; - } - else if (last && (*state & LIMBO_BEGIN) && (*state & LIMBO)) { - if ( (!!(*state & LIMBO_UP)) != (!!(*state & BEGIN_UP))) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO & ~LIMBO_UP & - ~LIMBO_BEGIN & ~BEGIN_UP; - } - else if ( *state & LIMBO ) { - /* do nothing */ - } - else { - if ( lon1 <= wlon && lon2 > wlon ) { - if ( *state & UP ) { - *state &= ~UP; - *state |= LIMBO_UP; - } - *state = *state | LIMBO; - } - } - } - else { - /* going up */ - if (*state & LIMBO) { - if ( !(*state & LIMBO_UP) ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO & ~LIMBO_UP; - } - else if (*state & LIMBO_BEGIN) { - if ( *state & BEGIN_HOR ) { - *state &= ~BEGIN_HOR; - *state |= BEGIN_UP; - } - else if ( last ) { - if ( !(*state & BEGIN_UP) ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; - } - } - else if ( first && (lon1 > wlon)) { - *state |= LIMBO_BEGIN | BEGIN_UP; - } - } - *state = *state & ~UP; - } - else if ( lat2 == wlat ) { - if ( lat1 < wlat ) { - if ( last ) { - if ( *state & BEGIN_UP ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; - } - else if ( lon2 > wlon ) { - *state |= LIMBO; - } - } - /* no case for lat1==wlat; that's above */ - else { - if ( last ) { - if ( !(*state & BEGIN_UP) ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; - } - else if ( lon2 > wlon ) { - *state |= LIMBO | LIMBO_UP; - } - else { - *state |= UP; - } - } - } - else { - if ( (lat1 > wlat && lat2 < wlat) || - (lat1 < wlat && lat2 > wlat)) { - /* we only care if the lines might intersect */ - if ( lon1 > wlon && lon2 > wlon ) { - *state = *state ^ INSIDE; - } - else if (!(lon1 <= wlon && lon2 <= wlon)) { - /* we're inside the bbox of a diagonal line. math time. */ - double loni = lon1+(lon2-lon1)/(lat2-lat1)*(wlat-lat1); - if ( loni > wlon ) { - *state = *state ^ INSIDE; - } - } - } - } +static void polytest(double lat1, double lon1, + double lat2, double lon2, + double wlat, double wlon, + unsigned short *state, int first, int last) +{ + + if (lat1 == wlat) { + if (lat2 < wlat) { + /* going down */ + if (*state & LIMBO) { + if (*state & LIMBO_UP) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO &~LIMBO_UP; + } else if (*state & LIMBO_BEGIN) { + if (*state & BEGIN_HOR) { + *state = *state & ~BEGIN_HOR; + } else if (last) { + if (*state & BEGIN_UP) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } + } else if (first && (lon1 > wlon)) { + *state |= LIMBO_BEGIN; + } + } else if (lat2 == wlat) { + if (first & (lon1 > wlon || lon2 > wlon)) { + *state |= LIMBO_BEGIN | BEGIN_HOR; + } else if (last && (*state & LIMBO_BEGIN) && (*state & LIMBO)) { + if ((!!(*state & LIMBO_UP)) != (!!(*state & BEGIN_UP))) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO & ~LIMBO_UP & + ~LIMBO_BEGIN & ~BEGIN_UP; + } else if (*state & LIMBO) { + /* do nothing */ + } else { + if (lon1 <= wlon && lon2 > wlon) { + if (*state & UP) { + *state &= ~UP; + *state |= LIMBO_UP; + } + *state = *state | LIMBO; + } + } + } else { + /* going up */ + if (*state & LIMBO) { + if (!(*state & LIMBO_UP)) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO & ~LIMBO_UP; + } else if (*state & LIMBO_BEGIN) { + if (*state & BEGIN_HOR) { + *state &= ~BEGIN_HOR; + *state |= BEGIN_UP; + } else if (last) { + if (!(*state & BEGIN_UP)) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } + } else if (first && (lon1 > wlon)) { + *state |= LIMBO_BEGIN | BEGIN_UP; + } + } + *state = *state & ~UP; + } else if (lat2 == wlat) { + if (lat1 < wlat) { + if (last) { + if (*state & BEGIN_UP) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } else if (lon2 > wlon) { + *state |= LIMBO; + } + } + /* no case for lat1==wlat; that's above */ + else { + if (last) { + if (!(*state & BEGIN_UP)) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } else if (lon2 > wlon) { + *state |= LIMBO | LIMBO_UP; + } else { + *state |= UP; + } + } + } else { + if ((lat1 > wlat && lat2 < wlat) || + (lat1 < wlat && lat2 > wlat)) { + /* we only care if the lines might intersect */ + if (lon1 > wlon && lon2 > wlon) { + *state = *state ^ INSIDE; + } else if (!(lon1 <= wlon && lon2 <= wlon)) { + /* we're inside the bbox of a diagonal line. math time. */ + double loni = lon1+(lon2-lon1)/(lat2-lat1)*(wlat-lat1); + if (loni > wlon) { + *state = *state ^ INSIDE; + } + } + } + } } #define BADVAL 999999 -void +void polygon_process(void) { - queue * elem, * tmp; - waypoint * waypointp; - extra_data *ed; - double lat1, lon1, lat2, lon2; - double olat, olon; - int fileline = 0; - int first = 1; - int last = 0; - char *line; - gbfile *file_in; + queue * elem, * tmp; + waypoint * waypointp; + extra_data *ed; + double lat1, lon1, lat2, lon2; + double olat, olon; + int fileline = 0; + int first = 1; + int last = 0; + char *line; + gbfile *file_in; + + file_in = gbfopen(polyfileopt, "r", MYNAME); - file_in = gbfopen(polyfileopt, "r", MYNAME); - - olat = olon = lat1 = lon1 = lat2 = lon2 = BADVAL; - while ((line = gbfgetstr(file_in))) { - char *pound = NULL; - int argsfound = 0; - - fileline++; - - pound = strchr( line, '#' ); - if ( pound ) *pound = '\0'; - - lat2 = lon2 = BADVAL; - argsfound = sscanf( line, "%lf %lf", &lat2, &lon2 ); - - if ( argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { - warning(MYNAME - ": Warning: Polygon file contains unusable vertex on line %d.\n", - fileline ); - } - else if ( lat1 != BADVAL && lon1 != BADVAL && - lat2 != BADVAL && lon2 != BADVAL ) { - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + olat = olon = lat1 = lon1 = lat2 = lon2 = BADVAL; + while ((line = gbfgetstr(file_in))) { + char *pound = NULL; + int argsfound = 0; - waypointp = (waypoint *)elem; - if ( waypointp->extra_data ) { - ed = (extra_data *) waypointp->extra_data; - } - else { - ed = (extra_data *) xcalloc(1, sizeof(*ed)); - ed->state = OUTSIDE; - ed->override = 0; - waypointp->extra_data = (extra_data *) ed; - } - if ( lat2 == waypointp->latitude && - lon2 == waypointp->longitude ) { - ed->override = 1; - } - if ( olat != BADVAL && olon != BADVAL && - olat == lat2 && olon == lon2 ) { - last = 1; - } - polytest( lat1, lon1, lat2, lon2, - waypointp->latitude, - waypointp->longitude, - &ed->state, first, last ); - first = 0; - last = 0; - } - } - if ( olat != BADVAL && olon != BADVAL && - olat == lat2 && olon == lon2 ) { - olat = BADVAL; - olon = BADVAL; - lat1 = BADVAL; - lon1 = BADVAL; - first = 1; - } - else if ( lat1 == BADVAL || lon1 == BADVAL ) { - olat = lat2; - olon = lon2; - lat1 = lat2; - lon1 = lon2; - } - else { - lat1 = lat2; - lon1 = lon2; - } - } - gbfclose(file_in); + fileline++; - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wp = (waypoint *) elem; - ed = (extra_data *) wp->extra_data; - wp->extra_data = NULL; - if ( ed ) { - if ( ed->override ) ed->state = INSIDE; - if (((ed->state & INSIDE) == OUTSIDE ) == (exclopt == NULL)) { - waypt_del(wp); - waypt_free(wp); - } - xfree( ed ); - } - } + pound = strchr(line, '#'); + if (pound) { + *pound = '\0'; + } + + lat2 = lon2 = BADVAL; + argsfound = sscanf(line, "%lf %lf", &lat2, &lon2); + + if (argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { + warning(MYNAME + ": Warning: Polygon file contains unusable vertex on line %d.\n", + fileline); + } else if (lat1 != BADVAL && lon1 != BADVAL && + lat2 != BADVAL && lon2 != BADVAL) { + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + + waypointp = (waypoint *)elem; + if (waypointp->extra_data) { + ed = (extra_data *) waypointp->extra_data; + } else { + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->state = OUTSIDE; + ed->override = 0; + waypointp->extra_data = (extra_data *) ed; + } + if (lat2 == waypointp->latitude && + lon2 == waypointp->longitude) { + ed->override = 1; + } + if (olat != BADVAL && olon != BADVAL && + olat == lat2 && olon == lon2) { + last = 1; + } + polytest(lat1, lon1, lat2, lon2, + waypointp->latitude, + waypointp->longitude, + &ed->state, first, last); + first = 0; + last = 0; + } + } + if (olat != BADVAL && olon != BADVAL && + olat == lat2 && olon == lon2) { + olat = BADVAL; + olon = BADVAL; + lat1 = BADVAL; + lon1 = BADVAL; + first = 1; + } else if (lat1 == BADVAL || lon1 == BADVAL) { + olat = lat2; + olon = lon2; + lat1 = lat2; + lon1 = lon2; + } else { + lat1 = lat2; + lon1 = lon2; + } + } + gbfclose(file_in); + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + ed = (extra_data *) wp->extra_data; + wp->extra_data = NULL; + if (ed) { + if (ed->override) { + ed->state = INSIDE; + } + if (((ed->state & INSIDE) == OUTSIDE) == (exclopt == NULL)) { + waypt_del(wp); + waypt_free(wp); + } + xfree(ed); + } + } } void -polygon_init(const char *args) { - /* do nothing */ +polygon_init(const char *args) +{ + /* do nothing */ } void -polygon_deinit(void) { - /* do nothing */ +polygon_deinit(void) +{ + /* do nothing */ } filter_vecs_t polygon_vecs = { - polygon_init, - polygon_process, - polygon_deinit, - NULL, - polygon_args + polygon_init, + polygon_process, + polygon_deinit, + NULL, + polygon_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/position.c b/gpsbabel/position.c index cc0527252..76503cc46 100644 --- a/gpsbabel/position.c +++ b/gpsbabel/position.c @@ -38,182 +38,195 @@ static char *purge_duplicates = NULL; static int check_time; typedef struct { - double distance; + double distance; } extra_data; static arglist_t position_args[] = { - {"distance", &distopt, "Maximum positional distance", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"all", &purge_duplicates, - "Suppress all points close to other points", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"time", &timeopt, "Maximum time in seconds beetween two points", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "distance", &distopt, "Maximum positional distance", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "all", &purge_duplicates, + "Suppress all points close to other points", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "time", &timeopt, "Maximum time in seconds beetween two points", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static double gc_distance(double lat1, double lon1, double lat2, double lon2) { - return gcdist( - RAD(lat1), - RAD(lon1), - RAD(lat2), - RAD(lon2) - ); + return gcdist( + RAD(lat1), + RAD(lon1), + RAD(lat2), + RAD(lon2) + ); } /* tear through a waypoint queue, processing points by distance */ -static void +static void position_runqueue(queue *q, int nelems, int qtype) { - queue * elem, * tmp; - waypoint ** comp; - int * qlist; - double dist, diff_time; - int i = 0, j, anyitem; - - comp = (waypoint **) xcalloc(nelems, sizeof(*comp)); - qlist = (int *) xcalloc(nelems, sizeof(*qlist)); - - QUEUE_FOR_EACH(q, elem, tmp) { - comp[i] = (waypoint *)elem; - qlist[i] = 0; - i++; - } - - for (i = 0 ; i < nelems ; i++) { - anyitem = 0; - - if (!qlist[i]) { - for (j = i + 1 ; j < nelems ; j++) { - if (!qlist[j]) { - dist = gc_distance(comp[j]->latitude, - comp[j]->longitude, - comp[i]->latitude, - comp[i]->longitude); - - /* convert radians to integer feet */ - dist = (int)(5280*radtomiles(dist)); - diff_time = fabs( waypt_time(comp[i]) - waypt_time(comp[j]) ); - - if (dist <= pos_dist) { - if(check_time && diff_time >= max_diff_time) - continue; - - qlist[j] = 1; - switch (qtype) { - case wptdata: - waypt_del(comp[j]); - waypt_free(comp[j]); - break; - case trkdata: - track_del_wpt(cur_rte, comp[j]); - break; - case rtedata: - route_del_wpt(cur_rte, comp[j]); - break; - default: - break; - } - anyitem = 1; - } - } - } - - if (anyitem && !!purge_duplicates) { - switch (qtype) { - case wptdata: - waypt_del(comp[i]); - break; - case trkdata: - track_del_wpt(cur_rte, comp[i]); - break; - case rtedata: - route_del_wpt(cur_rte, comp[i]); - break; - default: - break; - } - waypt_free(comp[i]); - } - } - } - - if (comp) - xfree(comp); - - if (qlist) - xfree(qlist); + queue * elem, * tmp; + waypoint ** comp; + int * qlist; + double dist, diff_time; + int i = 0, j, anyitem; + + comp = (waypoint **) xcalloc(nelems, sizeof(*comp)); + qlist = (int *) xcalloc(nelems, sizeof(*qlist)); + + QUEUE_FOR_EACH(q, elem, tmp) { + comp[i] = (waypoint *)elem; + qlist[i] = 0; + i++; + } + + for (i = 0 ; i < nelems ; i++) { + anyitem = 0; + + if (!qlist[i]) { + for (j = i + 1 ; j < nelems ; j++) { + if (!qlist[j]) { + dist = gc_distance(comp[j]->latitude, + comp[j]->longitude, + comp[i]->latitude, + comp[i]->longitude); + + /* convert radians to integer feet */ + dist = (int)(5280*radtomiles(dist)); + diff_time = fabs(waypt_time(comp[i]) - waypt_time(comp[j])); + + if (dist <= pos_dist) { + if (check_time && diff_time >= max_diff_time) { + continue; + } + + qlist[j] = 1; + switch (qtype) { + case wptdata: + waypt_del(comp[j]); + waypt_free(comp[j]); + break; + case trkdata: + track_del_wpt(cur_rte, comp[j]); + break; + case rtedata: + route_del_wpt(cur_rte, comp[j]); + break; + default: + break; + } + anyitem = 1; + } + } + } + + if (anyitem && !!purge_duplicates) { + switch (qtype) { + case wptdata: + waypt_del(comp[i]); + break; + case trkdata: + track_del_wpt(cur_rte, comp[i]); + break; + case rtedata: + route_del_wpt(cur_rte, comp[i]); + break; + default: + break; + } + waypt_free(comp[i]); + } + } + } + + if (comp) { + xfree(comp); + } + + if (qlist) { + xfree(qlist); + } } static void -position_process_route(const route_head * rh) { - int i = rh->rte_waypt_ct; +position_process_route(const route_head * rh) +{ + int i = rh->rte_waypt_ct; - if (i) { - cur_rte = (route_head *)rh; - position_runqueue((queue *)&rh->waypoint_list, i, rtedata); - cur_rte = NULL; - } + if (i) { + cur_rte = (route_head *)rh; + position_runqueue((queue *)&rh->waypoint_list, i, rtedata); + cur_rte = NULL; + } } -static void +static void position_noop_w(const waypoint *w) { } -static void +static void position_noop_t(const route_head *h) { } -void position_process(void) +void position_process(void) { - int i = waypt_count(); - - if (i) - position_runqueue(&waypt_head, i, wptdata); - - route_disp_all(position_process_route, position_noop_t, position_noop_w); - track_disp_all(position_process_route, position_noop_t, position_noop_w); + int i = waypt_count(); + + if (i) { + position_runqueue(&waypt_head, i, wptdata); + } + + route_disp_all(position_process_route, position_noop_t, position_noop_w); + track_disp_all(position_process_route, position_noop_t, position_noop_w); } void -position_init(const char *args) { - char *fm; - - pos_dist = 0; - max_diff_time = 0; - check_time = 0; - - if (distopt) { - pos_dist = strtod(distopt, &fm); - - if ((*fm == 'm') || (*fm == 'M')) { - /* distance is meters */ - pos_dist *= 3.2802; - } - } - - if (timeopt) { - check_time = 1; - max_diff_time = strtod(timeopt, &fm); - } +position_init(const char *args) +{ + char *fm; + + pos_dist = 0; + max_diff_time = 0; + check_time = 0; + + if (distopt) { + pos_dist = strtod(distopt, &fm); + + if ((*fm == 'm') || (*fm == 'M')) { + /* distance is meters */ + pos_dist *= 3.2802; + } + } + + if (timeopt) { + check_time = 1; + max_diff_time = strtod(timeopt, &fm); + } } void -position_deinit(void) { +position_deinit(void) +{ } filter_vecs_t position_vecs = { - position_init, - position_process, - position_deinit, - NULL, - position_args + position_init, + position_process, + position_deinit, + NULL, + position_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/psitrex.c b/gpsbabel/psitrex.c index 739fec4c9..9a6b64b4d 100755 --- a/gpsbabel/psitrex.c +++ b/gpsbabel/psitrex.c @@ -26,19 +26,19 @@ #include "garmin_tables.h" #include -#define MYNAME "PSITREX" +#define MYNAME "PSITREX" typedef enum { - ltrimEOL = 1 , /* skip spaces & tabs to start; ends on EOL */ - EOL, /* don't skip spaces and tabs to start; end on EOL */ - comma, /* skip spaces & tabs to start; ends on comma or EOL */ - whitespace, /* skip spaces & tabs to start; ends on white space or EOL */ - wscomma /* skip spaces & tabs to start; ends on white space, comma or EOL */ + ltrimEOL = 1 , /* skip spaces & tabs to start; ends on EOL */ + EOL, /* don't skip spaces and tabs to start; end on EOL */ + comma, /* skip spaces & tabs to start; ends on comma or EOL */ + whitespace, /* skip spaces & tabs to start; ends on white space or EOL */ + wscomma /* skip spaces & tabs to start; ends on white space, comma or EOL */ } psit_tokenSep_type; typedef struct psit_icon_mapping { - const int value; - const char *icon; + const int value; + const char *icon; } psit_icon_mapping_t; static gbfile *psit_file_in; @@ -56,223 +56,237 @@ char *snlen; static arglist_t psit_args[] = { -/* {"snlen", &snlen, "Length of generated shortnames", - NULL, ARGTYPE_INT, "1", NULL }, */ - ARG_TERMINATOR + /* {"snlen", &snlen, "Length of generated shortnames", + NULL, ARGTYPE_INT, "1", NULL }, */ + ARG_TERMINATOR }; /* Taken from PsiTrex 1.13 */ static const psit_icon_mapping_t psit_icon_value_table[] = { - { 0x00, "anchor" }, - { 0x06, "dollar" }, - { 0x07, "fish" }, - { 0x08, "fuel" }, - { 0x0a, "house" }, - { 0x0b, "knife" }, - { 0x0d, "mug" }, - { 0x0e, "skull" }, - { 0x12, "wpt_dot" }, - { 0x13, "wreck" }, - { 0x15, "mob" }, - { 0x0096, "boat_ramp" }, - { 0x0097, "camp" }, - { 0x0098, "restrooms" }, - { 0x0099, "showers" }, - { 0x009a, "drinking_wtr" }, - { 0x009b, "phone" }, - { 0x009c, "1st_aid" }, - { 0x009d, "info" }, - { 0x009e, "parking" }, - { 0x009f, "park" }, - { 0x00a0, "picnic" }, - { 0x00a1, "scenic" }, - { 0x00a2, "skiing" }, - { 0x00a3, "swimming" }, - { 0x00a4, "dam" }, - { 0x00a6, "danger" }, - { 0x00a9, "ball" }, - { 0x00aa, "car" }, - { 0x00ab, "deer" }, - { 0x00ac, "shpng_cart" }, - { 0x00ad, "lodging" }, - { 0x00ae, "mine" }, - { 0x00af, "trail_head" }, - { 0x00b0, "truck_stop" }, - { 0x00b2, "flag" }, - { 0x2005, "golf" }, - { 0x2006, "sml_cty" }, - { 0x2007, "med_cty" }, - { 0x2008, "lrg_cty" }, - { 0x200c, "amuse_pk" }, - { 0x200d, "bowling" }, - { 0x200e, "car_rental" }, - { 0x200f, "car_repair" }, - { 0x2010, "fastfood" }, - { 0x2011, "fitness" }, - { 0x2012, "movie" }, - { 0x2013, "museum" }, - { 0x2014, "pharmacy" }, - { 0x2015, "pizza" }, /* how specific does this really need to be? C'mon! */ - { 0x2016, "post_ofc" }, - { 0x2017, "rv_park" }, - { 0x2018, "school" }, - { 0x2019, "stadium" }, - { 0x201a, "store" }, - { 0x201b, "zoo" }, - { 0x201c, "gas_plus" }, - { 0x201d, "faces" }, - { 0x2022, "weigh_sttn" }, - { 0x2023, "toll_booth" }, - { 0x2029, "bridge" }, - { 0x202a, "building" }, - { 0x202b, "cemetery" }, - { 0x202c, "church" }, - { 0x202e, "crossing" }, - { 0x2032, "oil_field" }, - { 0x2033, "tunnel" }, - { 0x2035, "forest" }, - { 0x2036, "summit" }, - { 0x203f, "geocache" }, - { 0x2040, "geocache_fnd" }, - { 0x4000, "airport" }, - { 0x4007, "tall_tower" }, - { 0x4008, "short_tower" }, - { 0x4009, "glider" }, - { 0x400a, "ultralight" }, - { 0x400b, "parachute" }, - { 0x4012, "seaplane" }, - { -1, NULL } + { 0x00, "anchor" }, + { 0x06, "dollar" }, + { 0x07, "fish" }, + { 0x08, "fuel" }, + { 0x0a, "house" }, + { 0x0b, "knife" }, + { 0x0d, "mug" }, + { 0x0e, "skull" }, + { 0x12, "wpt_dot" }, + { 0x13, "wreck" }, + { 0x15, "mob" }, + { 0x0096, "boat_ramp" }, + { 0x0097, "camp" }, + { 0x0098, "restrooms" }, + { 0x0099, "showers" }, + { 0x009a, "drinking_wtr" }, + { 0x009b, "phone" }, + { 0x009c, "1st_aid" }, + { 0x009d, "info" }, + { 0x009e, "parking" }, + { 0x009f, "park" }, + { 0x00a0, "picnic" }, + { 0x00a1, "scenic" }, + { 0x00a2, "skiing" }, + { 0x00a3, "swimming" }, + { 0x00a4, "dam" }, + { 0x00a6, "danger" }, + { 0x00a9, "ball" }, + { 0x00aa, "car" }, + { 0x00ab, "deer" }, + { 0x00ac, "shpng_cart" }, + { 0x00ad, "lodging" }, + { 0x00ae, "mine" }, + { 0x00af, "trail_head" }, + { 0x00b0, "truck_stop" }, + { 0x00b2, "flag" }, + { 0x2005, "golf" }, + { 0x2006, "sml_cty" }, + { 0x2007, "med_cty" }, + { 0x2008, "lrg_cty" }, + { 0x200c, "amuse_pk" }, + { 0x200d, "bowling" }, + { 0x200e, "car_rental" }, + { 0x200f, "car_repair" }, + { 0x2010, "fastfood" }, + { 0x2011, "fitness" }, + { 0x2012, "movie" }, + { 0x2013, "museum" }, + { 0x2014, "pharmacy" }, + { 0x2015, "pizza" }, /* how specific does this really need to be? C'mon! */ + { 0x2016, "post_ofc" }, + { 0x2017, "rv_park" }, + { 0x2018, "school" }, + { 0x2019, "stadium" }, + { 0x201a, "store" }, + { 0x201b, "zoo" }, + { 0x201c, "gas_plus" }, + { 0x201d, "faces" }, + { 0x2022, "weigh_sttn" }, + { 0x2023, "toll_booth" }, + { 0x2029, "bridge" }, + { 0x202a, "building" }, + { 0x202b, "cemetery" }, + { 0x202c, "church" }, + { 0x202e, "crossing" }, + { 0x2032, "oil_field" }, + { 0x2033, "tunnel" }, + { 0x2035, "forest" }, + { 0x2036, "summit" }, + { 0x203f, "geocache" }, + { 0x2040, "geocache_fnd" }, + { 0x4000, "airport" }, + { 0x4007, "tall_tower" }, + { 0x4008, "short_tower" }, + { 0x4009, "glider" }, + { 0x400a, "ultralight" }, + { 0x400b, "parachute" }, + { 0x4012, "seaplane" }, + { -1, NULL } }; static const char * psit_find_desc_from_icon_number(const int icon) { - const psit_icon_mapping_t *i; - - for (i = psit_icon_value_table; i->icon; i++) { - if (icon == i->value) { - return i->icon; - } - } - return ""; + const psit_icon_mapping_t *i; + + for (i = psit_icon_value_table; i->icon; i++) { + if (icon == i->value) { + return i->icon; + } + } + return ""; } static int psit_find_icon_number_from_desc(const char *desc) { - const psit_icon_mapping_t *i; - int def_icon = 18; - - if (!desc) { - return def_icon; - } - - for (i = psit_icon_value_table; i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - return i->value; - } - } - if (atoi(desc) > 0) return atoi(desc); - return def_icon; + const psit_icon_mapping_t *i; + int def_icon = 18; + + if (!desc) { + return def_icon; + } + + for (i = psit_icon_value_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + return i->value; + } + } + if (atoi(desc) > 0) { + return atoi(desc); + } + return def_icon; } static void psit_rd_init(const char *fname) { - psit_file_in = gbfopen(fname, "r", MYNAME); + psit_file_in = gbfopen(fname, "r", MYNAME); } static void psit_rd_deinit(void) { - gbfclose(psit_file_in); + gbfclose(psit_file_in); } static void psit_wr_init(const char *fname) { - psit_file_out = gbfopen(fname, "w", MYNAME); + psit_file_out = gbfopen(fname, "w", MYNAME); } static void psit_wr_deinit(void) { - gbfclose(psit_file_out); + gbfclose(psit_file_out); } /* - * get characters until and including terminating NULL from psit_file_in + * get characters until and including terminating NULL from psit_file_in * and write into buf. */ static void psit_getToken(gbfile *psit_file, char *buf, size_t sz, psit_tokenSep_type delimType) { - int c = -1; - - *buf = 0; - - if (delimType != EOL) { - while ((c = gbfgetc(psit_file)) != EOF) { - if (!isspace(c)) break; - } - } - - if (gbfeof(psit_file)) return; - - if (delimType == EOL) { - c = gbfgetc(psit_file); - } - - if (c == '#') { - if (gbfgets(buf, sz, psit_file) == NULL) { - *buf = 0; - return; - } - /* use recursion to skip multiple comment lines or just to return the next token */ - psit_getToken(psit_file, buf, sz, delimType); - return; - } - - if ((delimType == EOL) || (delimType == ltrimEOL)) { - *buf = c; - buf++; - gbfgets(buf, sz-1, psit_file); - return; - } - - while (sz--) { - *buf++ = c; - if ((c = gbfgetc (psit_file)) == EOF) { - *buf = 0; - return; - } - if (((c == 0) || isspace(c)) && - ((delimType == whitespace) || (delimType == wscomma)) ) { - *buf = 0; - return; - } - if (((delimType == comma) || (delimType == wscomma)) && - (c == ',')) { - *buf = 0; - return; - } - } + int c = -1; + + *buf = 0; + + if (delimType != EOL) { + while ((c = gbfgetc(psit_file)) != EOF) { + if (!isspace(c)) { + break; + } + } + } + + if (gbfeof(psit_file)) { + return; + } + + if (delimType == EOL) { + c = gbfgetc(psit_file); + } + + if (c == '#') { + if (gbfgets(buf, sz, psit_file) == NULL) { + *buf = 0; + return; + } + /* use recursion to skip multiple comment lines or just to return the next token */ + psit_getToken(psit_file, buf, sz, delimType); + return; + } + + if ((delimType == EOL) || (delimType == ltrimEOL)) { + *buf = c; + buf++; + gbfgets(buf, sz-1, psit_file); + return; + } + + while (sz--) { + *buf++ = c; + if ((c = gbfgetc(psit_file)) == EOF) { + *buf = 0; + return; + } + if (((c == 0) || isspace(c)) && + ((delimType == whitespace) || (delimType == wscomma))) { + *buf = 0; + return; + } + if (((delimType == comma) || (delimType == wscomma)) && + (c == ',')) { + *buf = 0; + return; + } + } } /* - * test if a token is known - * + * test if a token is known + * */ static int psit_isKnownToken(char *buf) { - if (strcmp(buf, "Track:") == 0) return 0; - if (strcmp(buf, "Route:") == 0) return 0; - if (strcmp(buf, "Waypoint:") == 0) return 0; - if (strcmp(buf, "Map:") == 0) return 0; - return 1; + if (strcmp(buf, "Track:") == 0) { + return 0; + } + if (strcmp(buf, "Route:") == 0) { + return 0; + } + if (strcmp(buf, "Waypoint:") == 0) { + return 0; + } + if (strcmp(buf, "Map:") == 0) { + return 0; + } + return 1; } /* @@ -282,43 +296,42 @@ psit_isKnownToken(char *buf) static void psit_waypoint_r(gbfile *psit_file, waypoint **wpt) { - int garmin_icon_num; + int garmin_icon_num; - waypoint *thisWaypoint; + waypoint *thisWaypoint; - if (strlen(psit_current_token) > 0) { - thisWaypoint = waypt_new(); + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); - thisWaypoint->latitude = atof(psit_current_token); + thisWaypoint->latitude = atof(psit_current_token); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - thisWaypoint->longitude = atof(psit_current_token); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - if (psit_current_token[0] == '*') { - thisWaypoint->altitude = unknown_alt; - } - else { - thisWaypoint->altitude = atof(psit_current_token); - } + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } else { + thisWaypoint->altitude = atof(psit_current_token); + } - /* the name */ - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - rtrim(psit_current_token); - thisWaypoint->shortname = xstrdup(psit_current_token); - thisWaypoint->description = xstrdup(""); + /* the name */ + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + rtrim(psit_current_token); + thisWaypoint->shortname = xstrdup(psit_current_token); + thisWaypoint->description = xstrdup(""); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); - rtrim(psit_current_token); - /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ - /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ - garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); - thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + rtrim(psit_current_token); + /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ + /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ + garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); - waypt_add(thisWaypoint); + waypt_add(thisWaypoint); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - } + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } } /* @@ -328,43 +341,44 @@ psit_waypoint_r(gbfile *psit_file, waypoint **wpt) static void psit_waypoint_w(gbfile *psit_file, const waypoint *wpt) { - int icon; - const char *ident; - char *src = 0; /* BUGBUG Passed to mkshort */ - - gbfprintf(psit_file, "%11.6f,%11.6f,", - wpt->latitude, - wpt->longitude); - - if (wpt->altitude == unknown_alt) - gbfprintf(psit_file, "********,"); - else - gbfprintf(psit_file, "%8.2f,", - wpt->altitude); - - ident = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, src) : - wpt->shortname; - - gbfprintf(psit_file, " %-6s, ", ident); - icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); - - if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { - icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); - } - - ident = psit_find_desc_from_icon_number(icon); - if (strlen(ident) == 0) - gbfprintf(psit_file, "%1d\n", icon); - else - gbfprintf(psit_file, "%s\n", ident); + int icon; + const char *ident; + char *src = 0; /* BUGBUG Passed to mkshort */ + + gbfprintf(psit_file, "%11.6f,%11.6f,", + wpt->latitude, + wpt->longitude); + + if (wpt->altitude == unknown_alt) { + gbfprintf(psit_file, "********,"); + } else + gbfprintf(psit_file, "%8.2f,", + wpt->altitude); + + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + wpt->shortname; + + gbfprintf(psit_file, " %-6s, ", ident); + icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + + if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } + + ident = psit_find_desc_from_icon_number(icon); + if (strlen(ident) == 0) { + gbfprintf(psit_file, "%1d\n", icon); + } else { + gbfprintf(psit_file, "%s\n", ident); + } } static void psit_waypoint_w_wrapper(const waypoint *wpt) { - psit_waypoint_w(psit_file_out, wpt); + psit_waypoint_w(psit_file_out, wpt); } /* @@ -374,76 +388,77 @@ psit_waypoint_w_wrapper(const waypoint *wpt) static void psit_route_r(gbfile *psit_file, route_head **rte) { - char rtename[256]; - unsigned int rte_num; + char rtename[256]; + unsigned int rte_num; - int garmin_icon_num; + int garmin_icon_num; - route_head *rte_head; - unsigned int rte_count; + route_head *rte_head; + unsigned int rte_count; - waypoint *thisWaypoint; + waypoint *thisWaypoint; - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); - if (strlen(psit_current_token) == 0) { - strcpy(rtename, "ROUTE"); - } - else { - strcpy(rtename, psit_current_token); - } + if (strlen(psit_current_token) == 0) { + strcpy(rtename, "ROUTE"); + } else { + strcpy(rtename, psit_current_token); + } - rtrim(rtename); + rtrim(rtename); - rte_head = route_head_alloc(); - rte_head->rte_name = xstrdup(rtename); - route_add_head(rte_head); - *rte = rte_head; + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(rtename); + route_add_head(rte_head); + *rte = rte_head; - rte_num = 0; + rte_num = 0; - rte_count = 0; + rte_count = 0; - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - while (psit_isKnownToken(psit_current_token) != 0) { - if (strlen(psit_current_token) > 0) { - thisWaypoint = waypt_new(); + while (psit_isKnownToken(psit_current_token) != 0) { + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); - thisWaypoint->latitude = atof(psit_current_token); + thisWaypoint->latitude = atof(psit_current_token); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - thisWaypoint->longitude = atof(psit_current_token); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - if (psit_current_token[0] == '*') { - thisWaypoint->altitude = unknown_alt; - } - else { - thisWaypoint->altitude = atof(psit_current_token); - } + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } else { + thisWaypoint->altitude = atof(psit_current_token); + } - /* the name */ - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - rtrim(psit_current_token); - thisWaypoint->shortname = xstrdup(psit_current_token); - thisWaypoint->description = xstrdup(""); + /* the name */ + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + rtrim(psit_current_token); + thisWaypoint->shortname = xstrdup(psit_current_token); + thisWaypoint->description = xstrdup(""); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); - rtrim(psit_current_token); - /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ - /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ - garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); - thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + rtrim(psit_current_token); + /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ + /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ + garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); - route_add_wpt(rte_head, thisWaypoint); + route_add_wpt(rte_head, thisWaypoint); - if (gbfeof(psit_file)) break; + if (gbfeof(psit_file)) { + break; + } - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - } - else break; - } + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } else { + break; + } + } } /* @@ -453,55 +468,57 @@ psit_route_r(gbfile *psit_file, route_head **rte) static void psit_routehdr_w(gbfile *psit_file, const route_head *rte) { - char hdr[20]; - unsigned int rte_datapoints; - char *rname; - - waypoint *testwpt; - time_t uniqueValue = 0; - int allWptNameLengths; - - queue *elem, *tmp; - - /* total nodes (waypoints) this route */ - rte_datapoints = 0; - allWptNameLengths = 0; - - if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ - char *c; - - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - testwpt = (waypoint *)elem; - if (rte_datapoints == 0) { - uniqueValue = testwpt->creation_time; - } - rte_datapoints++; - } - - if (uniqueValue == 0) { - uniqueValue = current_time(); - } - - /* route name */ - if (!rte->rte_name) { - sprintf(hdr, "Route%04x", (unsigned) uniqueValue); - rname = xstrdup(hdr); - } - else - rname = xstrdup(rte->rte_name); - - /* check for psitrex comment sign; replace with '$' */ - while ((c = strchr(rname, '#'))) *c = '$'; - - gbfprintf(psit_file, "Route: %s\n", rname); - xfree(rname); - } + char hdr[20]; + unsigned int rte_datapoints; + char *rname; + + waypoint *testwpt; + time_t uniqueValue = 0; + int allWptNameLengths; + + queue *elem, *tmp; + + /* total nodes (waypoints) this route */ + rte_datapoints = 0; + allWptNameLengths = 0; + + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + char *c; + + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + testwpt = (waypoint *)elem; + if (rte_datapoints == 0) { + uniqueValue = testwpt->creation_time; + } + rte_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* route name */ + if (!rte->rte_name) { + sprintf(hdr, "Route%04x", (unsigned) uniqueValue); + rname = xstrdup(hdr); + } else { + rname = xstrdup(rte->rte_name); + } + + /* check for psitrex comment sign; replace with '$' */ + while ((c = strchr(rname, '#'))) { + *c = '$'; + } + + gbfprintf(psit_file, "Route: %s\n", rname); + xfree(rname); + } } static void psit_routehdr_w_wrapper(const route_head *rte) { - psit_routehdr_w(psit_file_out, rte); + psit_routehdr_w(psit_file_out, rte); } @@ -512,99 +529,99 @@ psit_routehdr_w_wrapper(const route_head *rte) static void psit_track_r(gbfile *psit_file, route_head **trk) { - char tbuf[100]; - char trkname[256]; - unsigned int trk_num; - - struct tm tmTime; - time_t dateTime = 0; - route_head *track_head = NULL; - unsigned int trk_count; - - waypoint *thisWaypoint; - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); - if (strlen(psit_current_token) == 0) { - strcpy(trkname, "TRACK"); - } - else { - strcpy(trkname, psit_current_token); - } - - rtrim(trkname); - - trk_num = 0; - - trk_count = 0; - - track_head = NULL; - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - - while (psit_isKnownToken(psit_current_token) != 0) { - if (strlen(psit_current_token) > 0) { - thisWaypoint = waypt_new(); - - thisWaypoint->latitude = atof(psit_current_token); - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - thisWaypoint->longitude = atof(psit_current_token); - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - if (psit_current_token[0] == '*') { - thisWaypoint->altitude = unknown_alt; - } - else { - thisWaypoint->altitude = atof(psit_current_token); - } - - /* date portion of the date time DD/MM/YY */ - psit_getToken(psit_file, psit_current_token, - sizeof(psit_current_token), whitespace); - sscanf(psit_current_token, "%02d/%02d/%02d", - &(tmTime.tm_mday) , &(tmTime.tm_mon), - &(tmTime.tm_year)); - - /* years are less 1900 in the tm struct */ - tmTime.tm_year += (tmTime.tm_year > 50 ? 0 : 100); - /* months are 0 to 11 in the tm struct */ - tmTime.tm_mon--; - /* time portion of the date time hh:mm:ss */ - psit_getToken(psit_file,psit_current_token, - sizeof(psit_current_token), wscomma); - sscanf(psit_current_token, "%02d:%02d:%02d", - &(tmTime.tm_hour) , &(tmTime.tm_min), - &(tmTime.tm_sec)); - - tmTime.tm_isdst = 0; - dateTime = mkgmtime(&tmTime); - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), whitespace); - - if ((strcmp(psit_current_token, "1") == 0) || (track_head == NULL)) { - track_head = route_head_alloc(); - /* Add a number to the track name. With Garmins, the "first" tracklog is usually ACTIVE LOG - the second is ACTIVE LOG001 and so on */ - if (trk_num > 0) { - sprintf(tbuf, "%s%03d", trkname, trk_num); - track_head->rte_name = xstrdup(tbuf); - } - else { - track_head->rte_name = xstrdup(trkname); - } - trk_num++; - track_add_head(track_head); - } - - thisWaypoint->creation_time = dateTime; - track_add_wpt(track_head, thisWaypoint); - - if (gbfeof(psit_file)) break; - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - } - else break; - } + char tbuf[100]; + char trkname[256]; + unsigned int trk_num; + + struct tm tmTime; + time_t dateTime = 0; + route_head *track_head = NULL; + unsigned int trk_count; + + waypoint *thisWaypoint; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + if (strlen(psit_current_token) == 0) { + strcpy(trkname, "TRACK"); + } else { + strcpy(trkname, psit_current_token); + } + + rtrim(trkname); + + trk_num = 0; + + trk_count = 0; + + track_head = NULL; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + + while (psit_isKnownToken(psit_current_token) != 0) { + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); + + thisWaypoint->latitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } else { + thisWaypoint->altitude = atof(psit_current_token); + } + + /* date portion of the date time DD/MM/YY */ + psit_getToken(psit_file, psit_current_token, + sizeof(psit_current_token), whitespace); + sscanf(psit_current_token, "%02d/%02d/%02d", + &(tmTime.tm_mday) , &(tmTime.tm_mon), + &(tmTime.tm_year)); + + /* years are less 1900 in the tm struct */ + tmTime.tm_year += (tmTime.tm_year > 50 ? 0 : 100); + /* months are 0 to 11 in the tm struct */ + tmTime.tm_mon--; + /* time portion of the date time hh:mm:ss */ + psit_getToken(psit_file,psit_current_token, + sizeof(psit_current_token), wscomma); + sscanf(psit_current_token, "%02d:%02d:%02d", + &(tmTime.tm_hour) , &(tmTime.tm_min), + &(tmTime.tm_sec)); + + tmTime.tm_isdst = 0; + dateTime = mkgmtime(&tmTime); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), whitespace); + + if ((strcmp(psit_current_token, "1") == 0) || (track_head == NULL)) { + track_head = route_head_alloc(); + /* Add a number to the track name. With Garmins, the "first" tracklog is usually ACTIVE LOG + the second is ACTIVE LOG001 and so on */ + if (trk_num > 0) { + sprintf(tbuf, "%s%03d", trkname, trk_num); + track_head->rte_name = xstrdup(tbuf); + } else { + track_head->rte_name = xstrdup(trkname); + } + trk_num++; + track_add_head(track_head); + } + + thisWaypoint->creation_time = dateTime; + track_add_wpt(track_head, thisWaypoint); + + if (gbfeof(psit_file)) { + break; + } + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } else { + break; + } + } } /* @@ -614,55 +631,57 @@ psit_track_r(gbfile *psit_file, route_head **trk) static void psit_trackhdr_w(gbfile *psit_file, const route_head *trk) { - char hdr[30]; - unsigned int trk_datapoints; - char *tname; - waypoint *testwpt; - time_t uniqueValue = 0; - - queue *elem, *tmp; - - if (psit_track_state == 2) { - /* total nodes (waypoints) this track */ - trk_datapoints = 0; - if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ - char *c; - - QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { - if (trk_datapoints == 0) { - testwpt = (waypoint *)elem; - uniqueValue = testwpt->creation_time; - } - trk_datapoints++; - } - - if (uniqueValue == 0) { - uniqueValue = current_time(); - } - - /* track name */ - if (!trk->rte_name) { - sprintf(hdr, "Track%04x", (unsigned) uniqueValue); - tname = xstrdup(hdr); - } - else - tname = xstrdup(trk->rte_name); - - /* check for psitrex comment sign; replace with '$' */ - while ((c = strchr(tname, '#'))) *c = '$'; - - gbfprintf (psit_file, "Track: %s\n", tname); - - xfree(tname); - } - } - psit_track_state = 1; + char hdr[30]; + unsigned int trk_datapoints; + char *tname; + waypoint *testwpt; + time_t uniqueValue = 0; + + queue *elem, *tmp; + + if (psit_track_state == 2) { + /* total nodes (waypoints) this track */ + trk_datapoints = 0; + if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ + char *c; + + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + if (trk_datapoints == 0) { + testwpt = (waypoint *)elem; + uniqueValue = testwpt->creation_time; + } + trk_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* track name */ + if (!trk->rte_name) { + sprintf(hdr, "Track%04x", (unsigned) uniqueValue); + tname = xstrdup(hdr); + } else { + tname = xstrdup(trk->rte_name); + } + + /* check for psitrex comment sign; replace with '$' */ + while ((c = strchr(tname, '#'))) { + *c = '$'; + } + + gbfprintf(psit_file, "Track: %s\n", tname); + + xfree(tname); + } + } + psit_track_state = 1; } static void psit_trackhdr_w_wrapper(const route_head *trk) { - psit_trackhdr_w(psit_file_out, trk); + psit_trackhdr_w(psit_file_out, trk); } @@ -673,136 +692,140 @@ psit_trackhdr_w_wrapper(const route_head *trk) static void psit_trackdatapoint_w(gbfile *psit_file, const waypoint *wpt) { - time_t t = wpt->creation_time; - struct tm *tmTime = gmtime(&t); - - gbfprintf(psit_file, "%11.6f,%11.6f,", - wpt->latitude, - wpt->longitude); - - if (wpt->altitude == unknown_alt) - gbfprintf(psit_file, "********, "); - else - gbfprintf(psit_file, "%8.2f, ", - wpt->altitude); - - /* Following date time format is fixed and reveals the origin of PsiTrex (i.e. the UK) */ - gbfprintf(psit_file, "%02d/%02d/%02d %02d:%02d:%02d,", - tmTime->tm_mday, - tmTime->tm_mon+1, - tmTime->tm_year % 100, - tmTime->tm_hour, - tmTime->tm_min, - tmTime->tm_sec); - - gbfprintf(psit_file," %d\n", psit_track_state); - psit_track_state = 0; + time_t t = wpt->creation_time; + struct tm *tmTime = gmtime(&t); + + gbfprintf(psit_file, "%11.6f,%11.6f,", + wpt->latitude, + wpt->longitude); + + if (wpt->altitude == unknown_alt) { + gbfprintf(psit_file, "********, "); + } else + gbfprintf(psit_file, "%8.2f, ", + wpt->altitude); + + /* Following date time format is fixed and reveals the origin of PsiTrex (i.e. the UK) */ + gbfprintf(psit_file, "%02d/%02d/%02d %02d:%02d:%02d,", + tmTime->tm_mday, + tmTime->tm_mon+1, + tmTime->tm_year % 100, + tmTime->tm_hour, + tmTime->tm_min, + tmTime->tm_sec); + + gbfprintf(psit_file," %d\n", psit_track_state); + psit_track_state = 0; } static void psit_trackdatapoint_w_wrapper(const waypoint *wpt) { - psit_trackdatapoint_w(psit_file_out, wpt); + psit_trackdatapoint_w(psit_file_out, wpt); } static void psit_read(void) { - waypoint *wpt; - route_head *rte; - route_head *trk; + waypoint *wpt; + route_head *rte; + route_head *trk; #ifdef DUMP_ICON_TABLE - printf("static icon_mapping_t icon_table[] = {\n"); + printf("static icon_mapping_t icon_table[] = {\n"); #endif - psit_getToken(psit_file_in, psit_current_token, sizeof(psit_current_token), whitespace); - - do { - if (strlen(psit_current_token) == 0) break; - - if (strcmp(psit_current_token, "Track:") == 0) { - if (global_opts.objective == trkdata) { - psit_track_r(psit_file_in, &trk); - } - else break; /* psitrex files only have one format in; */ - /* if this is a track file and we don't want them, them bail out */ - } - else if (strcmp(psit_current_token, "Route:") == 0) { - if (global_opts.objective == rtedata) { - psit_route_r(psit_file_in, &rte); - } - else break; /* ditto, but for routes */ - } - else { - /* Must be waypoints in this file */ - if (global_opts.objective == wptdata) { - psit_waypoint_r(psit_file_in, &wpt); + psit_getToken(psit_file_in, psit_current_token, sizeof(psit_current_token), whitespace); + + do { + if (strlen(psit_current_token) == 0) { + break; + } + + if (strcmp(psit_current_token, "Track:") == 0) { + if (global_opts.objective == trkdata) { + psit_track_r(psit_file_in, &trk); + } else { + break; /* psitrex files only have one format in; */ + } + /* if this is a track file and we don't want them, them bail out */ + } else if (strcmp(psit_current_token, "Route:") == 0) { + if (global_opts.objective == rtedata) { + psit_route_r(psit_file_in, &rte); + } else { + break; /* ditto, but for routes */ + } + } else { + /* Must be waypoints in this file */ + if (global_opts.objective == wptdata) { + psit_waypoint_r(psit_file_in, &wpt); #ifdef DUMP_ICON_TABLE - printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); + printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); #endif - } - else break; - } - } while (!gbfeof(psit_file_in)); + } else { + break; + } + } + } while (!gbfeof(psit_file_in)); - return; + return; #ifdef DUMP_ICON_TABLE - printf("\t{ -1, NULL },\n"); - printf("};\n"); + printf("\t{ -1, NULL },\n"); + printf("};\n"); #endif } -static void +static void psit_noop(const route_head *wp) { - /* no-op */ + /* no-op */ } void psit_write(void) { - int short_length; + int short_length; - if (snlen) - short_length = atoi(snlen); - else - short_length = 10; + if (snlen) { + short_length = atoi(snlen); + } else { + short_length = 10; + } - mkshort_handle = mkshort_new_handle(); + mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, short_length); - setshort_whitespace_ok(mkshort_handle, 0); + setshort_length(mkshort_handle, short_length); + setshort_whitespace_ok(mkshort_handle, 0); - psit_track_state = 2; + psit_track_state = 2; - if (global_opts.objective == wptdata) { - waypt_disp_all(psit_waypoint_w_wrapper); - } - if (global_opts.objective == rtedata) { - route_disp_all(psit_routehdr_w_wrapper, psit_noop, psit_waypoint_w_wrapper); - } - if (global_opts.objective == trkdata) { - track_disp_all(psit_trackhdr_w_wrapper, psit_noop, psit_trackdatapoint_w_wrapper); - } + if (global_opts.objective == wptdata) { + waypt_disp_all(psit_waypoint_w_wrapper); + } + if (global_opts.objective == rtedata) { + route_disp_all(psit_routehdr_w_wrapper, psit_noop, psit_waypoint_w_wrapper); + } + if (global_opts.objective == trkdata) { + track_disp_all(psit_trackhdr_w_wrapper, psit_noop, psit_trackdatapoint_w_wrapper); + } - mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_handle); } ff_vecs_t psit_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - psit_rd_init, - psit_wr_init, - psit_rd_deinit, - psit_wr_deinit, - psit_read, - psit_write, - NULL, - psit_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + psit_rd_init, + psit_wr_init, + psit_rd_deinit, + psit_wr_deinit, + psit_read, + psit_write, + NULL, + psit_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/psp.c b/gpsbabel/psp.c index 8934b4eb8..2008ab798 100644 --- a/gpsbabel/psp.c +++ b/gpsbabel/psp.c @@ -1,7 +1,7 @@ /* PocketStreets 2002 Pushpin Files Contributed to gpsbabel by Alex Mottram (geo_alexm at cox-internet.com) - + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -43,357 +43,364 @@ static short_handle mkshort_handle; static void psp_write_str(const char *str) { - if (str && *str) { - short *unicode; - int len; - - /* convert UTF-8 string into a unicode sequence */ - /* not perfect, but enough for us */ - unicode = cet_str_any_to_uni(str, global_opts.charset, &len); - if (len > MAXPSPSTRINGSIZE) len = MAXPSPSTRINGSIZE; - gbfputc((unsigned char)len, psp_file_out); - if (len) gbfwrite(unicode, 2, len, psp_file_out); - - xfree(unicode); - } - else - gbfputc(0, psp_file_out); + if (str && *str) { + short *unicode; + int len; + + /* convert UTF-8 string into a unicode sequence */ + /* not perfect, but enough for us */ + unicode = cet_str_any_to_uni(str, global_opts.charset, &len); + if (len > MAXPSPSTRINGSIZE) { + len = MAXPSPSTRINGSIZE; + } + gbfputc((unsigned char)len, psp_file_out); + if (len) { + gbfwrite(unicode, 2, len, psp_file_out); + } + + xfree(unicode); + } else { + gbfputc(0, psp_file_out); + } } /* ToDo: move the code inside to CET library */ static char * psp_read_str(gbfile *fin) { - int len; - gbint16 *buff; - char *res; - - len = (unsigned char)gbfgetc(fin); - if (len == 0) return NULL; - - buff = xmalloc(len * sizeof(*buff)); - gbfread(buff, sizeof(*buff), len, fin); - res = cet_str_uni_to_utf8(buff, len); - xfree(buff); - - return res; + int len; + gbint16 *buff; + char *res; + + len = (unsigned char)gbfgetc(fin); + if (len == 0) { + return NULL; + } + + buff = (gbint16*) xmalloc(len * sizeof(*buff)); + gbfread(buff, sizeof(*buff), len, fin); + res = cet_str_uni_to_utf8(buff, len); + xfree(buff); + + return res; } /* Implement the grid in ascii art... This makes a bit of sense if you stand on a point over the north pole and look down on the earth. --180 -90 0 90 180 +-180 -90 0 90 180 ------------------------------------ /\ | 0x03 U|S 0x02 U|k 0x00 | 0x01 | 90 |--------|--------|--------|--------| 0 | 0x07 | 0x06 | 0x04 | 0x05 | -90 ------------------------------------ \/ -*/ -static +*/ +static char grid_byte(double lat, double lon) { - char c = 0x00; - - if ((lon >= 0.0) && (lon < 90.0)) { - if (lat >= 0.0) { - c = 0x00; - } else { - c = 0x04; - } - } else - if (lon >= 90.0) { - if (lat >= 0.0) { - c = 0x01; - } else { - c = 0x05; - } - } else - if ((lon < 0.0) && (lon >= -90.0)) { - if (lat >= 0.0) { - c = 0x02; - } else { - c = 0x06; - } - } else - if (lon < -90.0) { - if (lat >= 0.0) { - c = 0x03; - } else { - c = 0x07; - } + char c = 0x00; + + if ((lon >= 0.0) && (lon < 90.0)) { + if (lat >= 0.0) { + c = 0x00; + } else { + c = 0x04; + } + } else if (lon >= 90.0) { + if (lat >= 0.0) { + c = 0x01; + } else { + c = 0x05; + } + } else if ((lon < 0.0) && (lon >= -90.0)) { + if (lat >= 0.0) { + c = 0x02; + } else { + c = 0x06; } - - return (c); -} + } else if (lon < -90.0) { + if (lat >= 0.0) { + c = 0x03; + } else { + c = 0x07; + } + } + + return (c); +} void decode_psp_coordinates(double * lat, double * lon, const char lonbyte) { - /* This is some sort of 1/2 Polar, 1/2 Cartesian coordinate mess in */ - /* the pin file. I really shouldn't have to do this. Zones 02 and 03 */ - /* work properly. The other zones are assumptions based on 02 and 03 */ - - if ((lonbyte == 0x02) || (lonbyte == 0x06)) { - /* one step west of zero longitude */ - if (*lon > 0.0) - *lon *= -1.0; - } else - if ((lonbyte == 0x03) || (lonbyte == 0x07)) { - /* two steps west of zero longitude */ - if (*lon > 0.0) - *lon -= 180.0; - } else - if ((lonbyte == 0x00) || (lonbyte == 0x04)) { - /* one step east of zero longitude */ - if (*lon < 0.0) - *lon *= -1.0; - } else - if ((lonbyte == 0x01) || (lonbyte == 0x05)) { - /* two steps east of zero longitude */ - if (*lon < 0.0) - *lon += 180.0; + /* This is some sort of 1/2 Polar, 1/2 Cartesian coordinate mess in */ + /* the pin file. I really shouldn't have to do this. Zones 02 and 03 */ + /* work properly. The other zones are assumptions based on 02 and 03 */ + + if ((lonbyte == 0x02) || (lonbyte == 0x06)) { + /* one step west of zero longitude */ + if (*lon > 0.0) { + *lon *= -1.0; + } + } else if ((lonbyte == 0x03) || (lonbyte == 0x07)) { + /* two steps west of zero longitude */ + if (*lon > 0.0) { + *lon -= 180.0; + } + } else if ((lonbyte == 0x00) || (lonbyte == 0x04)) { + /* one step east of zero longitude */ + if (*lon < 0.0) { + *lon *= -1.0; } + } else if ((lonbyte == 0x01) || (lonbyte == 0x05)) { + /* two steps east of zero longitude */ + if (*lon < 0.0) { + *lon += 180.0; + } + } } static int valid_psp_header(char * header) { - char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50 }; /* 1niP */ + char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50 }; /* 1niP */ + + return (memcmp(header_bytes, header, 4)); - return (memcmp(header_bytes, header, 4)); - } static void psp_rd_init(const char *fname) { - psp_file_in = gbfopen_le(fname, "rb", MYNAME); + psp_file_in = gbfopen_le(fname, "rb", MYNAME); } static void psp_rd_deinit(void) { - gbfclose(psp_file_in); + gbfclose(psp_file_in); } static void psp_wr_init(const char *fname) { - psp_file_out = gbfopen_le(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); + psp_file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void psp_wr_deinit(void) { - mkshort_del_handle(&mkshort_handle); - gbfclose(psp_file_out); + mkshort_del_handle(&mkshort_handle); + gbfclose(psp_file_out); } static void psp_read(void) { - char buff[MAXPSPSTRINGSIZE + 1]; - double radians; - double lat, lon; - waypoint *wpt_tmp; - short int pincount; - short int pindex; - char gridbyte = 0x00; - char *tmp; + char buff[MAXPSPSTRINGSIZE + 1]; + double radians; + double lat, lon; + waypoint *wpt_tmp; + short int pincount; + short int pindex; + char gridbyte = 0x00; + char *tmp; + + /* 32 bytes - file header */ + psp_fread(&buff[0], 1, 32, psp_file_in); - /* 32 bytes - file header */ - psp_fread(&buff[0], 1, 32, psp_file_in); + if (valid_psp_header(buff) != 0) { + fatal(MYNAME ": input file does not appear to be a valid .PSP file.\n"); + } - if (valid_psp_header(buff) != 0) { - fatal(MYNAME ": input file does not appear to be a valid .PSP file.\n"); - } + pincount = le_read16(&buff[12]); - pincount = le_read16(&buff[12]); + while (pincount--) { + wpt_tmp = waypt_new(); - while (pincount--) { - wpt_tmp = waypt_new(); + wpt_tmp->altitude = unknown_alt; - wpt_tmp->altitude = unknown_alt; - - /* offset 0x20 - 0x21 pin index */ - psp_fread(&pindex, 1, 2, psp_file_in); + /* offset 0x20 - 0x21 pin index */ + psp_fread(&pindex, 1, 2, psp_file_in); - /* offset 0x22 - 0x23 */ - psp_fread(&buff[0], 1, 2, psp_file_in); + /* offset 0x22 - 0x23 */ + psp_fread(&buff[0], 1, 2, psp_file_in); - /* offset 0x24 */ - /* 1 byte, the grid byte - needed for sign corrections later*/ - psp_fread(&gridbyte, 1, 1, psp_file_in); + /* offset 0x24 */ + /* 1 byte, the grid byte - needed for sign corrections later*/ + psp_fread(&gridbyte, 1, 1, psp_file_in); - /* 8 bytes - latitude in radians */ - radians = psp_fread_double(psp_file_in); - lat = DEG(radians); + /* 8 bytes - latitude in radians */ + radians = psp_fread_double(psp_file_in); + lat = DEG(radians); - /* 8 bytes - longitude in radians */ - radians = psp_fread_double(psp_file_in); - lon = DEG(radians); + /* 8 bytes - longitude in radians */ + radians = psp_fread_double(psp_file_in); + lon = DEG(radians); - /* since we don't know the origin of this PSP file, we use */ - /* the grid byte adjust longitude, if necessary, mimicing */ - /* the behavior of pocketstreets correcting the data. This */ - /* does not correct the fact that points in eastern US are */ - /* written with the wrong coordinates by S&T. (MS bug) */ + /* since we don't know the origin of this PSP file, we use */ + /* the grid byte adjust longitude, if necessary, mimicing */ + /* the behavior of pocketstreets correcting the data. This */ + /* does not correct the fact that points in eastern US are */ + /* written with the wrong coordinates by S&T. (MS bug) */ - decode_psp_coordinates(&lat, &lon, gridbyte); + decode_psp_coordinates(&lat, &lon, gridbyte); - wpt_tmp->latitude = lat; - wpt_tmp->longitude = lon; - - /* 1 byte - pin display properties */ - psp_fread(&buff[0], 1, 1, psp_file_in); + wpt_tmp->latitude = lat; + wpt_tmp->longitude = lon; - /* 3 bytes - unknown */ - psp_fread(&buff[0], 1, 3, psp_file_in); + /* 1 byte - pin display properties */ + psp_fread(&buff[0], 1, 1, psp_file_in); - /* 1 bytes - icon (values: 0x00 - 0x27) */ - psp_fread(&buff[0], 1, 1, psp_file_in); + /* 3 bytes - unknown */ + psp_fread(&buff[0], 1, 3, psp_file_in); - /* 3 bytes - unknown */ - psp_fread(&buff[0], 1, 3, psp_file_in); + /* 1 bytes - icon (values: 0x00 - 0x27) */ + psp_fread(&buff[0], 1, 1, psp_file_in); - wpt_tmp->shortname = psp_read_str(psp_file_in); - wpt_tmp->description = psp_read_str(psp_file_in); - tmp = psp_read_str(psp_file_in); /* (address?) */ - if (tmp) xfree(tmp); + /* 3 bytes - unknown */ + psp_fread(&buff[0], 1, 3, psp_file_in); + + wpt_tmp->shortname = psp_read_str(psp_file_in); + wpt_tmp->description = psp_read_str(psp_file_in); + tmp = psp_read_str(psp_file_in); /* (address?) */ + if (tmp) { + xfree(tmp); + } - waypt_add(wpt_tmp); - } + waypt_add(wpt_tmp); + } } static void psp_waypt_pr(const waypoint *wpt) { - double lon, lat; - char tbuf[64]; - char c; - static short int pindex = 0; - char *shortname; - char *description; - - if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { - if (wpt->description) { - if (global_opts.synthesize_shortnames) - shortname = mkshort_from_wpt(mkshort_handle, wpt); - else - shortname = xstrdup(wpt->description); - } else { - /* no description available */ - shortname = xstrdup(""); - } - } else{ - shortname = xstrdup(wpt->shortname); - } - - if (! wpt->description) { - if (shortname) { - description = xstrdup(shortname); - } else { - description = xstrdup(""); - } - } else{ - description = xstrdup(wpt->description); - } - - /* convert lat/long back to radians */ - lat = RAD(wpt->latitude); - lon = RAD(wpt->longitude); - - pindex++; - /* 2 bytes - pin index */ - gbfputint16(pindex, psp_file_out); - - /* 2 bytes - null bytes */ - gbfputint16(0, psp_file_out); - - - /* set the grid byte */ - c = grid_byte(wpt->latitude, - wpt->longitude); - - /* since the grid byte matches with what pocketstreets does to */ - /* input files, our output appears identical to a pin file that */ - /* has already been processed and corrected by pocketstreets. */ - /* Due to the grid and signs, it'll look different than one that */ - /* comes straight from S&T. */ - - /* the grid byte */ - gbfwrite(&c, 1, 1, psp_file_out); - - /* 8 bytes - latitude/radians */ - psp_fwrite_double(lat, psp_file_out); - - /* 8 bytes - longitude/radians */ - psp_fwrite_double(lon, psp_file_out); - - /* 1 byte - pin properties */ - c = 0x14; /* display pin name on, display notes on. 0x04 = no notes */ - gbfwrite(&c, 1, 1, psp_file_out); - - memset(tbuf, '\0', sizeof(tbuf)); - - /* 3 unknown bytes */ - gbfwrite(tbuf, 1, 3, psp_file_out); - - /* 1 icon byte 0x00 = PIN */ - gbfwrite(tbuf, 1, 1, psp_file_out); - - /* 3 unknown bytes */ - gbfwrite(tbuf, 1, 3, psp_file_out); /* 3 junk */ - - psp_write_str(shortname); - psp_write_str(description); - - /* just for the hell of it, we'll scrap the third string. */ - psp_write_str(""); - - xfree(shortname); - xfree(description); + double lon, lat; + char tbuf[64]; + char c; + static short int pindex = 0; + char *shortname; + char *description; + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) { + shortname = mkshort_from_wpt(mkshort_handle, wpt); + } else { + shortname = xstrdup(wpt->description); + } + } else { + /* no description available */ + shortname = xstrdup(""); + } + } else { + shortname = xstrdup(wpt->shortname); + } + + if (! wpt->description) { + if (shortname) { + description = xstrdup(shortname); + } else { + description = xstrdup(""); + } + } else { + description = xstrdup(wpt->description); + } + + /* convert lat/long back to radians */ + lat = RAD(wpt->latitude); + lon = RAD(wpt->longitude); + + pindex++; + /* 2 bytes - pin index */ + gbfputint16(pindex, psp_file_out); + + /* 2 bytes - null bytes */ + gbfputint16(0, psp_file_out); + + + /* set the grid byte */ + c = grid_byte(wpt->latitude, + wpt->longitude); + + /* since the grid byte matches with what pocketstreets does to */ + /* input files, our output appears identical to a pin file that */ + /* has already been processed and corrected by pocketstreets. */ + /* Due to the grid and signs, it'll look different than one that */ + /* comes straight from S&T. */ + + /* the grid byte */ + gbfwrite(&c, 1, 1, psp_file_out); + + /* 8 bytes - latitude/radians */ + psp_fwrite_double(lat, psp_file_out); + + /* 8 bytes - longitude/radians */ + psp_fwrite_double(lon, psp_file_out); + + /* 1 byte - pin properties */ + c = 0x14; /* display pin name on, display notes on. 0x04 = no notes */ + gbfwrite(&c, 1, 1, psp_file_out); + + memset(tbuf, '\0', sizeof(tbuf)); + + /* 3 unknown bytes */ + gbfwrite(tbuf, 1, 3, psp_file_out); + + /* 1 icon byte 0x00 = PIN */ + gbfwrite(tbuf, 1, 1, psp_file_out); + + /* 3 unknown bytes */ + gbfwrite(tbuf, 1, 3, psp_file_out); /* 3 junk */ + + psp_write_str(shortname); + psp_write_str(description); + + /* just for the hell of it, we'll scrap the third string. */ + psp_write_str(""); + + xfree(shortname); + xfree(description); } static void psp_write(void) { - short int s; - unsigned char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + short int s; + unsigned char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + /* the header: */ + /* 31 6E 69 50 20 00 00 00 08 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */ + /* offset 0x0C - 0x0D = 2 byte pin count */ - /* the header: */ - /* 31 6E 69 50 20 00 00 00 08 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */ - /* offset 0x0C - 0x0D = 2 byte pin count */ + s = waypt_count(); - s = waypt_count(); - - if (global_opts.synthesize_shortnames) { - setshort_length(mkshort_handle, 32); - setshort_whitespace_ok(mkshort_handle, 1); - } + if (global_opts.synthesize_shortnames) { + setshort_length(mkshort_handle, 32); + setshort_whitespace_ok(mkshort_handle, 1); + } - if (s > MAXPSPOUTPUTPINS) { - fatal(MYNAME ": attempt to output too many pushpins (%d). The max is %d. Sorry.\n", s, MAXPSPOUTPUTPINS); - } + if (s > MAXPSPOUTPUTPINS) { + fatal(MYNAME ": attempt to output too many pushpins (%d). The max is %d. Sorry.\n", s, MAXPSPOUTPUTPINS); + } - /* insert waypoint count into header */ - le_write16(&header_bytes[12], s); + /* insert waypoint count into header */ + le_write16(&header_bytes[12], s); - gbfwrite(header_bytes, 1, 32, psp_file_out); + gbfwrite(header_bytes, 1, 32, psp_file_out); - waypt_disp_all(psp_waypt_pr); + waypt_disp_all(psp_waypt_pr); } ff_vecs_t psp_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - psp_rd_init, - psp_wr_init, - psp_rd_deinit, - psp_wr_deinit, - psp_read, - psp_write, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* Fixed because of unicode strings in psp files (see psp_read_str / psp_write_str) */ + ff_type_file, + FF_CAP_RW_WPT, + psp_rd_init, + psp_wr_init, + psp_rd_deinit, + psp_wr_deinit, + psp_read, + psp_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* Fixed because of unicode strings in psp files (see psp_read_str / psp_write_str) */ }; diff --git a/gpsbabel/queue.c b/gpsbabel/queue.c index 3e8181159..3bd0c082c 100644 --- a/gpsbabel/queue.c +++ b/gpsbabel/queue.c @@ -25,23 +25,23 @@ void enqueue(queue *new_el, queue *old) { - new_el->next = old->next; - new_el->prev = old; - old->next->prev = new_el; - old->next = new_el; + new_el->next = old->next; + new_el->prev = old; + old->next->prev = new_el; + old->next = new_el; } queue * dequeue(queue *element) { - queue *prev = element->prev; - queue *next = element->next; - - next->prev = prev; - prev->next = next; - - QUEUE_INIT(element); - return element; + queue *prev = element->prev; + queue *next = element->next; + + next->prev = prev; + prev->next = next; + + QUEUE_INIT(element); + return element; } /* @@ -55,17 +55,17 @@ dequeue(queue *element) /* * Demonstration code for sorting a linked list. - * + * * The algorithm used is Mergesort, because that works really well * on linked lists, without requiring the O(N) extra space it needs * when you do it on arrays. - * - * ... + * + * ... */ /* * This file is copyright 2001 Simon Tatham. - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -74,10 +74,10 @@ dequeue(queue *element) * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -90,114 +90,133 @@ dequeue(queue *element) void -sortqueue (queue *qh, int (*cmp)(const queue *, const queue *)) +sortqueue(queue *qh, int (*cmp)(const queue *, const queue *)) { - queue *p, *q, *e, *tail, *oldhead, *list; - int insize, nmerges, psize, qsize, i; - - /* - * Special case: if `list' is empty, we're done. - */ - if (QUEUE_EMPTY(qh)) - return; - - /* - * The algorithm doesn't really want the extra list head - * element. So remove the list head for now. Put it back later. - */ - - list = QUEUE_FIRST(qh); - dequeue(qh); - - insize = 1; - - while (1) { - p = list; - oldhead = list; /* only used for circular linkage */ - list = NULL; - tail = NULL; - - nmerges = 0; /* count number of merges we do in this pass */ - - while (p) { - nmerges++; /* there exists a merge to be done */ - /* step `insize' places along from p */ - q = p; - psize = 0; - for (i = 0; i < insize; i++) { - psize++; - q = (q->next == oldhead ? NULL : q->next); - if (!q) break; - } - - /* if q hasn't fallen off end, we have - * two lists to merge */ - qsize = insize; - - /* now we have two lists; merge them */ - while (psize > 0 || (qsize > 0 && q)) { - - /* decide whether next element of - * merge comes from p or q - */ - if (psize == 0) { - /* p is empty; e must come from q. */ - e = q; q = q->next; qsize--; - if (q == oldhead) q = NULL; - } else if (qsize == 0 || !q) { - /* q is empty; e must come from p. */ - e = p; p = p->next; psize--; - if (p == oldhead) p = NULL; - } else if (cmp(p,q) <= 0) { - /* First element of p is - * lower (or same); e must - * come from p. - */ - e = p; p = p->next; psize--; - if (p == oldhead) p = NULL; - } else { - /* First element of q is - * lower; e must come from - * q. - */ - e = q; q = q->next; qsize--; - if (q == oldhead) q = NULL; - } - - /* add the next element to the merged list */ - if (tail) { - tail->next = e; - } else { - list = e; - } - - /* Maintain reverse pointers in a - * doubly linked list. */ - e->prev = tail; - - tail = e; - } - - /* now p has stepped `insize' places - * along, and q has too */ - p = q; - } - tail->next = list; - list->prev = tail; - - /* If we have done only one merge, we're finished. - * Allow for nmerges==0, the empty list case. - */ - if (nmerges <= 1) { - - /* Put the list head back at the start of the list */ - ENQUEUE_TAIL(list, qh); - return; - - } - - /* Otherwise repeat, merging lists twice the size */ - insize *= 2; - } + queue *p, *q, *e, *tail, *oldhead, *list; + int insize, nmerges, psize, qsize, i; + + /* + * Special case: if `list' is empty, we're done. + */ + if (QUEUE_EMPTY(qh)) { + return; + } + + /* + * The algorithm doesn't really want the extra list head + * element. So remove the list head for now. Put it back later. + */ + + list = QUEUE_FIRST(qh); + dequeue(qh); + + insize = 1; + + while (1) { + p = list; + oldhead = list; /* only used for circular linkage */ + list = NULL; + tail = NULL; + + nmerges = 0; /* count number of merges we do in this pass */ + + while (p) { + nmerges++; /* there exists a merge to be done */ + /* step `insize' places along from p */ + q = p; + psize = 0; + for (i = 0; i < insize; i++) { + psize++; + q = (q->next == oldhead ? NULL : q->next); + if (!q) { + break; + } + } + + /* if q hasn't fallen off end, we have + * two lists to merge */ + qsize = insize; + + /* now we have two lists; merge them */ + while (psize > 0 || (qsize > 0 && q)) { + + /* decide whether next element of + * merge comes from p or q + */ + if (psize == 0) { + /* p is empty; e must come from q. */ + e = q; + q = q->next; + qsize--; + if (q == oldhead) { + q = NULL; + } + } else if (qsize == 0 || !q) { + /* q is empty; e must come from p. */ + e = p; + p = p->next; + psize--; + if (p == oldhead) { + p = NULL; + } + } else if (cmp(p,q) <= 0) { + /* First element of p is + * lower (or same); e must + * come from p. + */ + e = p; + p = p->next; + psize--; + if (p == oldhead) { + p = NULL; + } + } else { + /* First element of q is + * lower; e must come from + * q. + */ + e = q; + q = q->next; + qsize--; + if (q == oldhead) { + q = NULL; + } + } + + /* add the next element to the merged list */ + if (tail) { + tail->next = e; + } else { + list = e; + } + + /* Maintain reverse pointers in a + * doubly linked list. */ + e->prev = tail; + + tail = e; + } + + /* now p has stepped `insize' places + * along, and q has too */ + p = q; + } + tail->next = list; + list->prev = tail; + + /* If we have done only one merge, we're finished. + * Allow for nmerges==0, the empty list case. + */ + if (nmerges <= 1) { + + /* Put the list head back at the start of the list */ + ENQUEUE_TAIL(list, qh); + return; + + } + + /* Otherwise repeat, merging lists twice the size */ + insize *= 2; + } } diff --git a/gpsbabel/queue.h b/gpsbabel/queue.h index 5b53ab9e1..48771efbc 100644 --- a/gpsbabel/queue.h +++ b/gpsbabel/queue.h @@ -20,14 +20,14 @@ */ typedef struct queue { - struct queue *next; - struct queue *prev; + struct queue* next; + struct queue* prev; } queue; -void enqueue(queue *new_el, queue *old); -queue * dequeue(queue *element); +void enqueue(queue* new_el, queue* old); +queue* dequeue(queue* element); -void sortqueue (queue *qh, int (*cmp)(const queue *, const queue *)); +void sortqueue(queue* qh, int (*cmp)(const queue*, const queue*)); #define QUEUE_INIT(head) (head)->next = ((head)->prev = head) #define QUEUE_FIRST(head) ((head)->next) diff --git a/gpsbabel/quovadis.c b/gpsbabel/quovadis.c index 295e272d2..67dd99d87 100644 --- a/gpsbabel/quovadis.c +++ b/gpsbabel/quovadis.c @@ -32,238 +32,238 @@ static char *dbname = NULL; static arglist_t quovadis_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static struct qv_icon_mapping mapping[] = { - { gt_unknown, QUESTION_ICON }, - { gt_traditional, HOSPITAL_ICON }, - { gt_multi, DOCUMENT_ICON }, - { gt_virtual, CAMERA_ICON }, - { gt_letterbox, MAILBOX_ICON }, - { gt_event, MEETING_ICON }, - { gt_suprise, GIFTSHOP_ICON }, + { gt_unknown, QUESTION_ICON }, + { gt_traditional, HOSPITAL_ICON }, + { gt_multi, DOCUMENT_ICON }, + { gt_virtual, CAMERA_ICON }, + { gt_letterbox, MAILBOX_ICON }, + { gt_event, MEETING_ICON }, + { gt_suprise, GIFTSHOP_ICON }, }; #define num_mappings (sizeof(mapping) / sizeof(struct qv_icon_mapping)) -static geocache_type icon_to_wpt(int icon_bitmap) { - unsigned int i; +static geocache_type icon_to_wpt(int icon_bitmap) +{ + unsigned int i; - for (i = 0; i < num_mappings; i++) { - if (icon_bitmap == mapping[i].bitmap_id) { - return mapping[i].gc_type; - } + for (i = 0; i < num_mappings; i++) { + if (icon_bitmap == mapping[i].bitmap_id) { + return mapping[i].gc_type; } - return gt_unknown; + } + return gt_unknown; } -static int wpt_to_icon(geocache_type type) { - unsigned int i; +static int wpt_to_icon(geocache_type type) +{ + unsigned int i; - for (i = 0; i < num_mappings; i++) { - if (type == mapping[i].gc_type) { - return mapping[i].bitmap_id; - } + for (i = 0; i < num_mappings; i++) { + if (type == mapping[i].gc_type) { + return mapping[i].bitmap_id; } - return QUESTION_ICON; + } + return QUESTION_ICON; } static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_in); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - ct = 0; + file_out = pdb_create(fname, MYNAME); + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; - int i; + struct record *rec; + pdbrec_t *pdb_rec; + int i; - if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { - fatal(MYNAME ": Not a QuoVadis file.\n"); - } - - /* Ignore the first record, it contains one zero byte */ - for(pdb_rec = file_in->rec_list->next; pdb_rec; pdb_rec = pdb_rec->next) { - int num_recs = pdb_rec->size / sizeof(struct record); - for (i = 0; i < num_recs; i++) { - waypoint *wpt_tmp; - - wpt_tmp = waypt_new(); - - rec = (struct record *) - &(pdb_rec->data[i * sizeof(struct record)]); - - wpt_tmp->longitude = - (be_read32(&rec->longitude) / 1000000.0) - 180.0; - wpt_tmp->latitude = - 90.0 - (be_read32(&rec->latitude) / 1000000.0); - wpt_tmp->shortname = xstrdup(rec->name); - - waypt_alloc_gc_data(wpt_tmp)->type = - icon_to_wpt(be_read16(&rec->icon_bitmap)); - - waypt_add(wpt_tmp); - } - } -} + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a QuoVadis file.\n"); + } + /* Ignore the first record, it contains one zero byte */ + for (pdb_rec = file_in->rec_list->next; pdb_rec; pdb_rec = pdb_rec->next) { + int num_recs = pdb_rec->size / sizeof(struct record); + for (i = 0; i < num_recs; i++) { + waypoint *wpt_tmp; -static void -quovadis_writewpt(waypoint *wpt) -{ - struct record *rec; - int i; + wpt_tmp = waypt_new(); - if (current_rec == NULL) { - gbuint8 dummy = 0; - - pdb_write_rec(file_out, 0, 0, ct++, &dummy, 1); + rec = (struct record *) + &(pdb_rec->data[i * sizeof(struct record)]); - current_rec = (gbuint8 *) xcalloc(MAXCHUNKSIZE, 1); - rec_index = 0; - rec_ptr = current_rec; - } + wpt_tmp->longitude = + (be_read32(&rec->longitude) / 1000000.0) - 180.0; + wpt_tmp->latitude = + 90.0 - (be_read32(&rec->latitude) / 1000000.0); + wpt_tmp->shortname = xstrdup(rec->name); - rec = (struct record *) xcalloc(sizeof(*rec),1); + waypt_alloc_gc_data(wpt_tmp)->type = + icon_to_wpt(be_read16(&rec->icon_bitmap)); - be_write32(&rec->longitude, (unsigned int) ((wpt->longitude + - 180.0) * 1000000.0)); - be_write32(&rec->latitude, (unsigned int) ((90.0 - wpt->latitude) * 1000000.0)); - if ( wpt->shortname ) { - strncpy(rec->name, wpt->shortname, 32 ); - rec->name[31] = '\0'; - } - else { - rec->name[0] = '\0'; - } - be_write16(&rec->icon_bitmap, wpt_to_icon(wpt->gc_data->type)); - be_write32(&rec->note_id, 0); - rec->name_scale = DEFAULT_NAME_SCALE; - rec->icon_scale = DEFAULT_ICON_SCALE; - for (i = 0; i < 7; i++) { - rec->reserved[i] = 0; + waypt_add(wpt_tmp); } + } +} - memcpy(rec_ptr, rec, sizeof(*rec)); - rec_ptr += sizeof(*rec); - rec_index += 1; - xfree(rec); - if (rec_index == MAXRECORDS) { - fatal(MYNAME ": cannot store more than %lu records at this time.\n", - (unsigned long) MAXRECORDS); - } +static void +quovadis_writewpt(waypoint *wpt) +{ + struct record *rec; + int i; + + if (current_rec == NULL) { + gbuint8 dummy = 0; + + pdb_write_rec(file_out, 0, 0, ct++, &dummy, 1); + + current_rec = (gbuint8 *) xcalloc(MAXCHUNKSIZE, 1); + rec_index = 0; + rec_ptr = current_rec; + } + + rec = (struct record *) xcalloc(sizeof(*rec),1); + + be_write32(&rec->longitude, (unsigned int)((wpt->longitude + + 180.0) * 1000000.0)); + be_write32(&rec->latitude, (unsigned int)((90.0 - wpt->latitude) * 1000000.0)); + if (wpt->shortname) { + strncpy(rec->name, wpt->shortname, 32); + rec->name[31] = '\0'; + } else { + rec->name[0] = '\0'; + } + be_write16(&rec->icon_bitmap, wpt_to_icon(wpt->gc_data->type)); + be_write32(&rec->note_id, 0); + rec->name_scale = DEFAULT_NAME_SCALE; + rec->icon_scale = DEFAULT_ICON_SCALE; + for (i = 0; i < 7; i++) { + rec->reserved[i] = 0; + } + + memcpy(rec_ptr, rec, sizeof(*rec)); + rec_ptr += sizeof(*rec); + rec_index += 1; + xfree(rec); + + if (rec_index == MAXRECORDS) { + fatal(MYNAME ": cannot store more than %lu records at this time.\n", + (unsigned long) MAXRECORDS); + } } -struct hdr{ - char *wpt_name; - waypoint *wpt; +struct hdr { + char *wpt_name; + waypoint *wpt; }; static -int +int compare(const void *a, const void *b) { - const struct hdr *wa = (const struct hdr *) a; - const struct hdr *wb = (const struct hdr *) b; + const struct hdr *wa = (const struct hdr *) a; + const struct hdr *wb = (const struct hdr *) b; - return strcmp(wa->wpt->shortname, wb->wpt->shortname); + return strcmp(wa->wpt->shortname, wb->wpt->shortname); } static void data_write(void) { - int i, ct = waypt_count(); - struct hdr *htable, *bh; - queue *elem, *tmp; - extern queue waypt_head; - waypoint *waypointp; - - if ( dbname ) { - strncpy( file_out->name, dbname, PDB_DBNAMELEN ); - } - else { - strncpy(file_out->name, "QuoVadisMarkerDB", PDB_DBNAMELEN); - } - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - - /* - * All this is to sort by waypoint names before going to QuoVadis. - * Turns out plain old strcmp will do the trick... - */ - - htable = (struct hdr *) xmalloc(ct * sizeof(*htable)); - bh = htable; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - bh->wpt = waypointp; - bh->wpt_name = waypointp->shortname; - bh ++; - } - qsort(htable, ct, sizeof(*bh), compare); - - for (i=0;iname, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, "QuoVadisMarkerDB", PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + /* + * All this is to sort by waypoint names before going to QuoVadis. + * Turns out plain old strcmp will do the trick... + */ + + htable = (struct hdr *) xmalloc(ct * sizeof(*htable)); + bh = htable; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + bh->wpt = waypointp; + bh->wpt_name = waypointp->shortname; + bh ++; + } + qsort(htable, ct, sizeof(*bh), compare); + + for (i=0; i 18.12 miles, 26 => 46 feet */ - char icon_scale; /* As above. */ - unsigned char reserved[8]; + char icon_scale; /* As above. */ + unsigned char reserved[8]; }; struct qv_icon_mapping { - const geocache_type gc_type; - const int bitmap_id; + const geocache_type gc_type; + const int bitmap_id; }; /* Icon Types */ diff --git a/gpsbabel/radius.c b/gpsbabel/radius.c index 831c4a8f4..dde26d064 100644 --- a/gpsbabel/radius.c +++ b/gpsbabel/radius.c @@ -41,183 +41,204 @@ static int maxct; static waypoint * home_pos; typedef struct { - double distance; + double distance; } extra_data; static arglist_t radius_args[] = { - {"lat", &latopt, "Latitude for center point (D.DDDDD)", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"lon", &lonopt, "Longitude for center point (D.DDDDD)", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"distance", &distopt, "Maximum distance from center", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"exclude", &exclopt, "Exclude points close to center", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"nosort", &nosort, "Inhibit sort by distance to center", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"maxcount", &maxctarg,"Output no more than this number of points", - NULL, ARGTYPE_INT, "1", NULL }, - {"asroute", &routename,"Put resulting waypoints in route of this name", - NULL, ARGTYPE_STRING, NULL, NULL }, - ARG_TERMINATOR + { + "lat", &latopt, "Latitude for center point (D.DDDDD)", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "lon", &lonopt, "Longitude for center point (D.DDDDD)", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "distance", &distopt, "Maximum distance from center", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "exclude", &exclopt, "Exclude points close to center", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "nosort", &nosort, "Inhibit sort by distance to center", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "maxcount", &maxctarg,"Output no more than this number of points", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "asroute", &routename,"Put resulting waypoints in route of this name", + NULL, ARGTYPE_STRING, NULL, NULL + }, + ARG_TERMINATOR }; static double gc_distance(double lat1, double lon1, double lat2, double lon2) { - return gcdist( - RAD(lat1), - RAD(lon1), - RAD(lat2), - RAD(lon2) - ); + return gcdist( + RAD(lat1), + RAD(lon1), + RAD(lat2), + RAD(lon2) + ); } static int dist_comp(const void * a, const void * b) { - const waypoint *x1 = *(waypoint **)a; - const waypoint *x2 = *(waypoint **)b; - extra_data *x1e = (extra_data *) x1->extra_data; - extra_data *x2e = (extra_data *) x2->extra_data; - - if (x1e->distance > x2e->distance) - return 1; - if (x1e->distance < x2e->distance) - return -1; - return 0; + const waypoint *x1 = *(waypoint **)a; + const waypoint *x2 = *(waypoint **)b; + extra_data *x1e = (extra_data *) x1->extra_data; + extra_data *x2e = (extra_data *) x2->extra_data; + + if (x1e->distance > x2e->distance) { + return 1; + } + if (x1e->distance < x2e->distance) { + return -1; + } + return 0; } -void +void radius_process(void) { - queue * elem, * tmp; - waypoint * waypointp; - double dist; - waypoint ** comp; - int i, wc; - queue temp_head; - route_head *rte_head = NULL; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - extra_data *ed; - - waypointp = (waypoint *)elem; - dist = gc_distance(waypointp->latitude, - waypointp->longitude, - home_pos->latitude, - home_pos->longitude); - - /* convert radians to float point statute miles */ - dist = radtomiles(dist); - - if ((dist >= pos_dist) == (exclopt == NULL)) { - waypt_del(waypointp); - waypt_free(waypointp); - continue; - } - - ed = (extra_data *) xcalloc(1, sizeof(*ed)); - ed->distance = dist; - waypointp->extra_data = ed; - } - - wc = waypt_count(); - QUEUE_INIT(&temp_head); - - comp = (waypoint **) xcalloc(wc, sizeof(*comp)); - - i = 0; - - /* - * Create an array of remaining waypoints, popping them off the - * master queue as we go. This gives us something reasonable - * for qsort. - */ - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wp = (waypoint *) elem; - comp[i] = wp; - waypt_del(wp); - i++; - } - - if (!nosort) { - qsort(comp, wc, sizeof(waypoint *), dist_comp); - } - - if (routename) { - rte_head = route_head_alloc(); - rte_head->rte_name = xstrdup(routename); - route_add_head(rte_head); - } - - /* - * The comp array is now sorted by distance. As we run through it, - * we push them back onto the master wp list, letting us pass them - * on through in the modified order. - */ - for (i = 0; i < wc; i++) { - waypoint * wp = comp[i]; - - xfree(wp->extra_data); - wp->extra_data = NULL; - - if (maxctarg && i >= maxct) { - continue; - } - if (routename) { - route_add_wpt(rte_head, wp); - } else { - waypt_add(wp); - } - } - - xfree(comp); + queue * elem, * tmp; + waypoint * waypointp; + double dist; + waypoint ** comp; + int i, wc; + queue temp_head; + route_head *rte_head = NULL; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + extra_data *ed; + + waypointp = (waypoint *)elem; + dist = gc_distance(waypointp->latitude, + waypointp->longitude, + home_pos->latitude, + home_pos->longitude); + + /* convert radians to float point statute miles */ + dist = radtomiles(dist); + + if ((dist >= pos_dist) == (exclopt == NULL)) { + waypt_del(waypointp); + waypt_free(waypointp); + continue; + } + + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->distance = dist; + waypointp->extra_data = ed; + } + + wc = waypt_count(); + QUEUE_INIT(&temp_head); + + comp = (waypoint **) xcalloc(wc, sizeof(*comp)); + + i = 0; + + /* + * Create an array of remaining waypoints, popping them off the + * master queue as we go. This gives us something reasonable + * for qsort. + */ + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + comp[i] = wp; + waypt_del(wp); + i++; + } + + if (!nosort) { + qsort(comp, wc, sizeof(waypoint *), dist_comp); + } + + if (routename) { + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(routename); + route_add_head(rte_head); + } + + /* + * The comp array is now sorted by distance. As we run through it, + * we push them back onto the master wp list, letting us pass them + * on through in the modified order. + */ + for (i = 0; i < wc; i++) { + waypoint * wp = comp[i]; + + xfree(wp->extra_data); + wp->extra_data = NULL; + + if (maxctarg && i >= maxct) { + continue; + } + if (routename) { + route_add_wpt(rte_head, wp); + } else { + waypt_add(wp); + } + } + + xfree(comp); } void -radius_init(const char *args) { - char *fm; +radius_init(const char *args) +{ + char *fm; - pos_dist = 0; + pos_dist = 0; - if (distopt) { - pos_dist = strtod(distopt, &fm); + if (distopt) { + pos_dist = strtod(distopt, &fm); - if ((*fm == 'k') || (*fm == 'K')) { - /* distance is kilometers, convert to feet */ - pos_dist *= .6214; - } - } + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to feet */ + pos_dist *= .6214; + } + } - if (maxctarg) { - maxct = atoi(maxctarg); - } else { - maxct = 0; - } + if (maxctarg) { + maxct = atoi(maxctarg); + } else { + maxct = 0; + } - home_pos = (waypoint *) xcalloc(sizeof(*home_pos), 1); + home_pos = (waypoint *) xcalloc(sizeof(*home_pos), 1); - if (latopt) - home_pos->latitude = atof(latopt); - if (lonopt) - home_pos->longitude = atof(lonopt); + if (latopt) { + home_pos->latitude = atof(latopt); + } + if (lonopt) { + home_pos->longitude = atof(lonopt); + } } void -radius_deinit(void) { - if (home_pos) - xfree(home_pos); +radius_deinit(void) +{ + if (home_pos) { + xfree(home_pos); + } } filter_vecs_t radius_vecs = { - radius_init, - radius_process, - radius_deinit, - NULL, - radius_args + radius_init, + radius_process, + radius_deinit, + NULL, + radius_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/random.c b/gpsbabel/random.c index 199aa5b4c..20f62ffd6 100644 --- a/gpsbabel/random.c +++ b/gpsbabel/random.c @@ -1,6 +1,6 @@ /* random - GPS data generator - + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -27,25 +27,29 @@ static char *opt_points, *opt_seed; -static arglist_t random_args[] = { - { "points", &opt_points, "Generate # points", NULL, - ARGTYPE_INT, "1", NULL }, - { "seed", &opt_seed, "Starting seed of the internal number generator", NULL, - ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR +static arglist_t random_args[] = { + { + "points", &opt_points, "Generate # points", NULL, + ARGTYPE_INT, "1", NULL + }, + { + "seed", &opt_seed, "Starting seed of the internal number generator", NULL, + ARGTYPE_INT, "1", NULL + }, + ARG_TERMINATOR }; static double rand_dbl(const double max) { - return max * rand() / (((double)RAND_MAX) + 1); + return max * rand() / (((double)RAND_MAX) + 1); } static int rand_int(const int max) { - return (int)((double)max * rand() / (((double)RAND_MAX) + 1)); + return (int)((double)max * rand() / (((double)RAND_MAX) + 1)); } /* rand_str always returns a valid string with len >= 0 */ @@ -53,32 +57,33 @@ rand_int(const int max) static char * rand_str(const int maxlen, const char *fmt) { - char *res; - int i, len; - - len = rand_int(maxlen) + 1; - - res = xmalloc(len + 1); - res[len] = '\0'; - - for (i = 0; i < len; i++) { - int c = rand_int(26 + 26 + 10); - if ( c < 26 ) - c += 'a'; - else if (c < 52) - c = (c - 26) + 'A'; - else - c = (c - 52) + '0'; - res[i] = c; - } - if (fmt) { - char *tmp; - xasprintf(&tmp, fmt, res); - xfree(res); - return tmp; - } - else - return res; + char *res; + int i, len; + + len = rand_int(maxlen) + 1; + + res = (char*) xmalloc(len + 1); + res[len] = '\0'; + + for (i = 0; i < len; i++) { + int c = rand_int(26 + 26 + 10); + if (c < 26) { + c += 'a'; + } else if (c < 52) { + c = (c - 26) + 'A'; + } else { + c = (c - 52) + '0'; + } + res[i] = c; + } + if (fmt) { + char *tmp; + xasprintf(&tmp, fmt, res); + xfree(res); + return tmp; + } else { + return res; + } } static void @@ -91,118 +96,154 @@ random_rd_deinit(void) { } -static void +static void random_read(void) { #define RND(a) (rand_int(a) > 0) - int i, points; - route_head *head; - waypoint *prev = NULL; - time_t time = gpsbabel_time; - - if (opt_seed) - srand(atoi(opt_seed)); - else - srand(gpsbabel_now); - - - points = (opt_points) ? atoi(opt_points) : rand_int(128) + 1; - if (doing_trks || doing_rtes) { - head = route_head_alloc(); - if (doing_trks) { - head->rte_name = rand_str(8, "Trk_%s"); - track_add_head(head); - } - else { - head->rte_name = rand_str(8, "Rte_%s"); - route_add_head(head); - } - head->rte_desc = rand_str(16, NULL); - } - else head = NULL; - - for (i = 0; i < points; i++) { - - waypoint *wpt; - garmin_fs_t *gmsd; - - wpt = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - do { - wpt->shortname = rand_str(8, "Wpt_%s"); - } while (wpt->shortname == NULL); - - wpt->latitude = rand_dbl(180) - 90; - wpt->longitude = rand_dbl(360) - 180; - - /* !!! "if RND(3) ..." produces some leaks in generated data !!! */ - - if RND(3) wpt->altitude = rand_int(1000) / 10; - if RND(3) WAYPT_SET(wpt, temperature, rand_int(320) / 10.0); - if RND(3) WAYPT_SET(wpt, proximity, rand_int(10000) / 10.0); - if RND(3) WAYPT_SET(wpt, depth, rand_int(10000) / 10.0); - - wpt->creation_time = time; - if RND(3) wpt->microseconds = rand_int(1000) * 1000; - time += rand_int(10) + 1; - - if (doing_trks) { - if (i > 0) { - wpt->latitude = prev->latitude + (rand_dbl(1) / 1000); - wpt->longitude = prev->longitude + (rand_dbl(1) / 1000); - WAYPT_SET(wpt, course, waypt_course(prev, wpt)); - WAYPT_SET(wpt, speed, waypt_speed(prev, wpt)); - } - wpt->sat = rand_int(12 + 1); - wpt->hdop = (rand_int(500)) / 10.0; - wpt->vdop = (rand_int(500)) / 10.0; - wpt->pdop = (rand_int(500)) / 10.0; - wpt->fix = rand_int(6) - 1; - if RND(3) wpt->cadence = rand_int(255); - if RND(3) wpt->heartrate = rand_int(255); - } - else { - if (doing_rtes && (i > 0)) { - wpt->latitude = prev->latitude + (rand_dbl(1) / 100); - wpt->longitude = prev->longitude + (rand_dbl(1) / 100); - } - if RND(3) wpt->description = rand_str(16, "Des_%s"); - if RND(3) wpt->notes = rand_str(16, "Nts_%s"); - if RND(3) GMSD_SET(addr, rand_str(8, "Adr_%s")); - if RND(3) GMSD_SET(city, rand_str(8, "Cty_%s")); - if RND(3) GMSD_SET(facility, rand_str(8, "Fac_%s")); - if RND(3) GMSD_SET(country, rand_str(8, "Ctr_%s")); - if RND(3) GMSD_SET(state, rand_str(8, "Sta_%s")); - if RND(3) GMSD_SET(phone_nr, rand_str(8, "Pnr_%s")); - if RND(3) GMSD_SET(postal_code, rand_str(8, "Pcd_%s")); - } - - if (doing_trks) track_add_wpt(head, wpt); - else if (doing_rtes) route_add_wpt(head, wpt); - else waypt_add(wpt); - - prev = wpt; - } + int i, points; + route_head *head; + waypoint *prev = NULL; + time_t time = gpsbabel_time; + + if (opt_seed) { + srand(atoi(opt_seed)); + } else { + srand(gpsbabel_now); + } + + + points = (opt_points) ? atoi(opt_points) : rand_int(128) + 1; + if (doing_trks || doing_rtes) { + head = route_head_alloc(); + if (doing_trks) { + head->rte_name = rand_str(8, "Trk_%s"); + track_add_head(head); + } else { + head->rte_name = rand_str(8, "Rte_%s"); + route_add_head(head); + } + head->rte_desc = rand_str(16, NULL); + } else { + head = NULL; + } + + for (i = 0; i < points; i++) { + + waypoint *wpt; + garmin_fs_t *gmsd; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + do { + wpt->shortname = rand_str(8, "Wpt_%s"); + } while (wpt->shortname == NULL); + + wpt->latitude = rand_dbl(180) - 90; + wpt->longitude = rand_dbl(360) - 180; + + /* !!! "if RND(3) ..." produces some leaks in generated data !!! */ + + if RND(3) { + wpt->altitude = rand_int(1000) / 10; + } + if RND(3) { + WAYPT_SET(wpt, temperature, rand_int(320) / 10.0); + } + if RND(3) { + WAYPT_SET(wpt, proximity, rand_int(10000) / 10.0); + } + if RND(3) { + WAYPT_SET(wpt, depth, rand_int(10000) / 10.0); + } + + wpt->creation_time = time; + if RND(3) { + wpt->microseconds = rand_int(1000) * 1000; + } + time += rand_int(10) + 1; + + if (doing_trks) { + if (i > 0) { + wpt->latitude = prev->latitude + (rand_dbl(1) / 1000); + wpt->longitude = prev->longitude + (rand_dbl(1) / 1000); + WAYPT_SET(wpt, course, waypt_course(prev, wpt)); + WAYPT_SET(wpt, speed, waypt_speed(prev, wpt)); + } + wpt->sat = rand_int(12 + 1); + wpt->hdop = (rand_int(500)) / 10.0; + wpt->vdop = (rand_int(500)) / 10.0; + wpt->pdop = (rand_int(500)) / 10.0; + wpt->fix = (fix_type)(rand_int(6) - 1); + if RND(3) { + wpt->cadence = rand_int(255); + } + if RND(3) { + wpt->heartrate = rand_int(255); + } + } else { + if (doing_rtes && (i > 0)) { + wpt->latitude = prev->latitude + (rand_dbl(1) / 100); + wpt->longitude = prev->longitude + (rand_dbl(1) / 100); + } + if RND(3) { + wpt->description = rand_str(16, "Des_%s"); + } + if RND(3) { + wpt->notes = rand_str(16, "Nts_%s"); + } + if RND(3) { + GMSD_SET(addr, rand_str(8, "Adr_%s")); + } + if RND(3) { + GMSD_SET(city, rand_str(8, "Cty_%s")); + } + if RND(3) { + GMSD_SET(facility, rand_str(8, "Fac_%s")); + } + if RND(3) { + GMSD_SET(country, rand_str(8, "Ctr_%s")); + } + if RND(3) { + GMSD_SET(state, rand_str(8, "Sta_%s")); + } + if RND(3) { + GMSD_SET(phone_nr, rand_str(8, "Pnr_%s")); + } + if RND(3) { + GMSD_SET(postal_code, rand_str(8, "Pcd_%s")); + } + } + + if (doing_trks) { + track_add_wpt(head, wpt); + } else if (doing_rtes) { + route_add_wpt(head, wpt); + } else { + waypt_add(wpt); + } + + prev = wpt; + } } ff_vecs_t random_vecs = { - ff_type_internal, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_read /* routes */ - }, - random_rd_init, - NULL, /* wr_init */ - random_rd_deinit, - NULL, /* wr_deinit */ - random_read, - NULL, /* write */ - NULL, /* exit */ - random_args, - CET_CHARSET_ASCII, 1 /* fixed */ + ff_type_internal, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_read /* routes */ + }, + random_rd_init, + NULL, /* wr_init */ + random_rd_deinit, + NULL, /* wr_deinit */ + random_read, + NULL, /* write */ + NULL, /* exit */ + random_args, + CET_CHARSET_ASCII, 1 /* fixed */ }; diff --git a/gpsbabel/raymarine.c b/gpsbabel/raymarine.c index d9d4aa54d..8b426ac57 100644 --- a/gpsbabel/raymarine.c +++ b/gpsbabel/raymarine.c @@ -1,25 +1,25 @@ - /* +/* - Support for Raymarine Waypoint File (.rwf). + Support for Raymarine Waypoint File (.rwf). - Copyright (C) 2006,2007 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2006,2007 Olaf Klein, o.b.klein@gpsbabel.org - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -/* +/* Known format limits: Waypoint name: max. 16 characters @@ -28,9 +28,9 @@ ???: the character set may be only a subset of std. ASCII History: - + 2006/10/30: Initial release (not yet in GPSBabel source tree) - 2006/11/08: + 2006/11/08: 2007/03/17: Remove GUIDs from writer (not really valid) Fix "PredictedTwa" output Initialize location with "My Waypoints" @@ -64,10 +64,9 @@ static char *opt_location; #define MYNAME "raymarine" static -arglist_t raymarine_args[] = -{ - { "location", &opt_location, "Default location", "My Waypoints", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR +arglist_t raymarine_args[] = { + { "location", &opt_location, "Default location", "My Waypoints", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; /* from csv_util.c: convert excel time (days since 1900) to time_t and back again */ @@ -80,61 +79,61 @@ arglist_t raymarine_args[] = /* Bitmaps */ typedef struct { - const char *name; - const char *mps_name; + const char *name; + const char *mps_name; } raymarine_symbol_mapping_t; static raymarine_symbol_mapping_t raymarine_symbols[] = { - { /* 0 */ "Unknown Symbol 0" }, - { /* 1 */ "Unknown Symbol 1" }, - { /* 2 */ "Unknown Symbol 2" }, - { /* 3 */ "Red Square" }, - { /* 4 */ "Big Fish" }, - { /* 5 */ "Anchor" }, - { /* 6 */ "Smiley", "Contact, Smiley" }, - { /* 7 */ "Sad" }, - { /* 8 */ "Red Button", "Navaid, Red" }, - { /* 9 */ "Sailfish" }, - { /* 10 */ "Danger", "Skull and Crossbones" }, - { /* 11 */ "Attention" }, - { /* 12 */ "Black Square" }, - { /* 13 */ "Intl. Dive Flag", "Diver Down Flag 2" }, - { /* 14 */ "Vessel", "Marina" }, - { /* 15 */ "Lobster" }, - { /* 16 */ "Buoy", "Buoy, White" }, - { /* 17 */ "Exclamation" }, - { /* 18 */ "Red X" }, - { /* 19 */ "Check Mark" }, - { /* 20 */ "Black Plus" }, - { /* 21 */ "Black Cross" }, - { /* 22 */ "MOB" }, - { /* 23 */ "Billfish" }, - { /* 24 */ "Bottom Mark" }, - { /* 25 */ "Circle", "Circle, Red" }, - { /* 26 */ "Diamond", "Block, Red" }, - { /* 27 */ "Diamond Quarters", "Diamond, Red" }, - { /* 28 */ "U.S. Dive Flag", "Diver Down Flag 1" }, - { /* 29 */ "Dolphin" }, - { /* 30 */ "Few Fish" }, - { /* 31 */ "Multiple Fish" }, - { /* 32 */ "Many Fish" }, - { /* 33 */ "Single Fish" }, - { /* 34 */ "Small Fish" }, - { /* 35 */ "Marker" }, - { /* 36 */ "Cocktails", "Bar" }, - { /* 37 */ "Red Box Marker" }, - { /* 38 */ "Reef" }, - { /* 39 */ "Rocks" }, - { /* 40 */ "Fish School" }, - { /* 41 */ "Seaweed", "Weed Bed" }, - { /* 42 */ "Shark" }, - { /* 43 */ "Sportfisher" }, - { /* 44 */ "Swimmer", "Swimming Area" }, - { /* 45 */ "Top Mark" }, - { /* 46 */ "Trawler" }, - { /* 47 */ "Tree" }, - { /* 48 */ "Triangle", "Triangle, Red" }, - { /* 49 */ "Wreck", "Shipwreck" } + { /* 0 */ "Unknown Symbol 0" }, + { /* 1 */ "Unknown Symbol 1" }, + { /* 2 */ "Unknown Symbol 2" }, + { /* 3 */ "Red Square" }, + { /* 4 */ "Big Fish" }, + { /* 5 */ "Anchor" }, + { /* 6 */ "Smiley", "Contact, Smiley" }, + { /* 7 */ "Sad" }, + { /* 8 */ "Red Button", "Navaid, Red" }, + { /* 9 */ "Sailfish" }, + { /* 10 */ "Danger", "Skull and Crossbones" }, + { /* 11 */ "Attention" }, + { /* 12 */ "Black Square" }, + { /* 13 */ "Intl. Dive Flag", "Diver Down Flag 2" }, + { /* 14 */ "Vessel", "Marina" }, + { /* 15 */ "Lobster" }, + { /* 16 */ "Buoy", "Buoy, White" }, + { /* 17 */ "Exclamation" }, + { /* 18 */ "Red X" }, + { /* 19 */ "Check Mark" }, + { /* 20 */ "Black Plus" }, + { /* 21 */ "Black Cross" }, + { /* 22 */ "MOB" }, + { /* 23 */ "Billfish" }, + { /* 24 */ "Bottom Mark" }, + { /* 25 */ "Circle", "Circle, Red" }, + { /* 26 */ "Diamond", "Block, Red" }, + { /* 27 */ "Diamond Quarters", "Diamond, Red" }, + { /* 28 */ "U.S. Dive Flag", "Diver Down Flag 1" }, + { /* 29 */ "Dolphin" }, + { /* 30 */ "Few Fish" }, + { /* 31 */ "Multiple Fish" }, + { /* 32 */ "Many Fish" }, + { /* 33 */ "Single Fish" }, + { /* 34 */ "Small Fish" }, + { /* 35 */ "Marker" }, + { /* 36 */ "Cocktails", "Bar" }, + { /* 37 */ "Red Box Marker" }, + { /* 38 */ "Reef" }, + { /* 39 */ "Rocks" }, + { /* 40 */ "Fish School" }, + { /* 41 */ "Seaweed", "Weed Bed" }, + { /* 42 */ "Shark" }, + { /* 43 */ "Sportfisher" }, + { /* 44 */ "Swimmer", "Swimming Area" }, + { /* 45 */ "Top Mark" }, + { /* 46 */ "Trawler" }, + { /* 47 */ "Tree" }, + { /* 48 */ "Triangle", "Triangle, Red" }, + { /* 49 */ "Wreck", "Shipwreck" } }; #define RAYMARINE_SYMBOL_CT sizeof(raymarine_symbols) / sizeof(raymarine_symbol_mapping_t) @@ -143,20 +142,24 @@ static raymarine_symbol_mapping_t raymarine_symbols[] = { static int find_symbol_num(const char *descr) { - if ((descr != NULL) && (*descr)) { - - int i; - raymarine_symbol_mapping_t *a; - - a = &raymarine_symbols[0]; - - for (i = 0; i < RAYMARINE_SYMBOL_CT; i++, a++) { - if (case_ignore_strcmp(descr, a->name) == 0) return i; - if (a->mps_name && (case_ignore_strcmp(descr, a->mps_name) == 0)) return i; - } - } - - return RAYMARINE_STD_SYMBOL; + if ((descr != NULL) && (*descr)) { + + int i; + raymarine_symbol_mapping_t *a; + + a = &raymarine_symbols[0]; + + for (i = 0; i < RAYMARINE_SYMBOL_CT; i++, a++) { + if (case_ignore_strcmp(descr, a->name) == 0) { + return i; + } + if (a->mps_name && (case_ignore_strcmp(descr, a->mps_name) == 0)) { + return i; + } + } + } + + return RAYMARINE_STD_SYMBOL; } /* ============================================= */ @@ -166,86 +169,103 @@ find_symbol_num(const char *descr) static void raymarine_rd_init(const char *fname) { - fin = inifile_init(fname, MYNAME); - if (fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); + fin = inifile_init(fname, MYNAME); + if (fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } } static void raymarine_rd_done(void) { - inifile_done(fin); + inifile_done(fin); } static void raymarine_read(void) { - waypoint *wpt; - int ix, rx; - - /* Read all waypoints */ - - for (ix = 0; ix < 0x3FFF; ix++) { - char sect[10]; - char *str, *name, *lat, *lon; - - /* built section identifier */ - snprintf(sect, sizeof(sect), "Wp%d", ix); - - /* try to read our most expected values */ - if (NULL == (name = inifile_readstr(fin, sect, "Name"))) break; - if (NULL == (lat = inifile_readstr(fin, sect, "Lat"))) break; - if (NULL == (lon = inifile_readstr(fin, sect, "Long"))) break; - - wpt = waypt_new(); - wpt->shortname = xstrdup(name); - wpt->latitude = atof(lat); - wpt->longitude = atof(lon); - waypt_add(wpt); - - /* try to read optional values */ - if (((str = inifile_readstr(fin, sect, "Notes"))) && *str) wpt->notes = xstrdup(str); - if (((str = inifile_readstr(fin, sect, "Time"))) && *str) wpt->creation_time = EXCEL_TO_TIMET(atof(str)); - if (((str = inifile_readstr(fin, sect, "Bmp"))) && *str) { - int symbol = atoi(str); - - if ((symbol < 3) && (symbol >= RAYMARINE_SYMBOL_CT)) - symbol = RAYMARINE_STD_SYMBOL; - wpt->icon_descr = raymarine_symbols[symbol].name; - } - } - - /* Read all routes */ - - for (rx = 0; rx < 0x3FFF; rx++) { - char sect[10]; - char *name; - route_head *rte; - int wx; - - snprintf(sect, sizeof(sect), "Rt%d", rx); - if (NULL == (name = inifile_readstr(fin, sect, "Name"))) break; - - rte = route_head_alloc(); - rte->rte_name = xstrdup(name); - route_add_head(rte); - - for (wx = 0; wx < 0x3FFF; wx++) { - char buff[32]; - char *str; - waypoint * wpt; - - snprintf(buff, sizeof(buff), "Mk%d", wx); - str = inifile_readstr(fin, sect, buff); - if ((str == NULL) || (*str == '\0')) break; - - wpt = find_waypt_by_name(str); - if (wpt == NULL) - fatal(MYNAME ": No associated waypoint for route point %s (Route %s)!\n", - str, rte->rte_name); - - route_add_wpt(rte, waypt_dupe(wpt)); - } - } + waypoint *wpt; + int ix, rx; + + /* Read all waypoints */ + + for (ix = 0; ix < 0x3FFF; ix++) { + char sect[10]; + char *str, *name, *lat, *lon; + + /* built section identifier */ + snprintf(sect, sizeof(sect), "Wp%d", ix); + + /* try to read our most expected values */ + if (NULL == (name = inifile_readstr(fin, sect, "Name"))) { + break; + } + if (NULL == (lat = inifile_readstr(fin, sect, "Lat"))) { + break; + } + if (NULL == (lon = inifile_readstr(fin, sect, "Long"))) { + break; + } + + wpt = waypt_new(); + wpt->shortname = xstrdup(name); + wpt->latitude = atof(lat); + wpt->longitude = atof(lon); + waypt_add(wpt); + + /* try to read optional values */ + if (((str = inifile_readstr(fin, sect, "Notes"))) && *str) { + wpt->notes = xstrdup(str); + } + if (((str = inifile_readstr(fin, sect, "Time"))) && *str) { + wpt->creation_time = EXCEL_TO_TIMET(atof(str)); + } + if (((str = inifile_readstr(fin, sect, "Bmp"))) && *str) { + int symbol = atoi(str); + + if ((symbol < 3) && (symbol >= RAYMARINE_SYMBOL_CT)) { + symbol = RAYMARINE_STD_SYMBOL; + } + wpt->icon_descr = raymarine_symbols[symbol].name; + } + } + + /* Read all routes */ + + for (rx = 0; rx < 0x3FFF; rx++) { + char sect[10]; + char *name; + route_head *rte; + int wx; + + snprintf(sect, sizeof(sect), "Rt%d", rx); + if (NULL == (name = inifile_readstr(fin, sect, "Name"))) { + break; + } + + rte = route_head_alloc(); + rte->rte_name = xstrdup(name); + route_add_head(rte); + + for (wx = 0; wx < 0x3FFF; wx++) { + char buff[32]; + char *str; + waypoint * wpt; + + snprintf(buff, sizeof(buff), "Mk%d", wx); + str = inifile_readstr(fin, sect, buff); + if ((str == NULL) || (*str == '\0')) { + break; + } + + wpt = find_waypt_by_name(str); + if (wpt == NULL) + fatal(MYNAME ": No associated waypoint for route point %s (Route %s)!\n", + str, rte->rte_name); + + route_add_wpt(rte, waypt_dupe(wpt)); + } + } } /* ============================================= */ @@ -257,234 +277,241 @@ raymarine_read(void) static char same_points(const waypoint *A, const waypoint *B) { - return ( /* !!! We are case-sensitive !!! */ - (strcmp(A->shortname, B->shortname) == 0) && - (A->latitude == B->latitude) && - (A->longitude == B->longitude)); + return ( /* !!! We are case-sensitive !!! */ + (strcmp(A->shortname, B->shortname) == 0) && + (A->latitude == B->latitude) && + (A->longitude == B->longitude)); } static void register_waypt(const waypoint *ref, const char is_rtept) { - int i; - waypoint *wpt = (waypoint *) ref; - - for (i = 0; i < waypt_table_ct; i++) { - waypoint *cmp = waypt_table[i]; - - if (same_points(wpt, cmp)) { - wpt->extra_data = cmp->extra_data; - return; - } - } - - if (waypt_table_ct >= waypt_table_sz) { - waypt_table_sz += 32; - if (waypt_table) - waypt_table = (void *) xrealloc(waypt_table, waypt_table_sz * sizeof(wpt)); - else - waypt_table = (void *) xmalloc(waypt_table_sz * sizeof(wpt)); - } - - wpt->extra_data = (void *)mkshort(hshort_wpt, wpt->shortname); - - waypt_table[waypt_table_ct] = (waypoint *)wpt; - waypt_table_ct++; + int i; + waypoint *wpt = (waypoint *) ref; + + for (i = 0; i < waypt_table_ct; i++) { + waypoint *cmp = waypt_table[i]; + + if (same_points(wpt, cmp)) { + wpt->extra_data = cmp->extra_data; + return; + } + } + + if (waypt_table_ct >= waypt_table_sz) { + waypt_table_sz += 32; + if (waypt_table) { + waypt_table = (waypoint**) xrealloc(waypt_table, waypt_table_sz * sizeof(wpt)); + } else { + waypt_table = (waypoint**) xmalloc(waypt_table_sz * sizeof(wpt)); + } + } + + wpt->extra_data = (void *)mkshort(hshort_wpt, wpt->shortname); + + waypt_table[waypt_table_ct] = (waypoint *)wpt; + waypt_table_ct++; } static void enum_waypt_cb(const waypoint *wpt) { - register_waypt((waypoint *) wpt, 0); + register_waypt((waypoint *) wpt, 0); } static void enum_rtept_cb(const waypoint *wpt) { - register_waypt((waypoint *) wpt, 1); + register_waypt((waypoint *) wpt, 1); } -static int +static int qsort_cb(const void *a, const void *b) { - const waypoint *wa = *(waypoint **)a; - const waypoint *wb = *(waypoint **)b; - - return strcmp(wa->shortname, wb->shortname); + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return strcmp(wa->shortname, wb->shortname); } static void write_waypoint(gbfile *fout, const waypoint *wpt, const int waypt_no, const char *location) { - char *notes; - char *name; - double time; - - notes = wpt->notes; - if (notes == NULL) { - notes = wpt->description; - if (notes == NULL) notes = ""; - } - notes = csv_stringclean(notes, LINE_FEED); - time = (wpt->creation_time > 0) ? TIMET_TO_EXCEL(wpt->creation_time) : TIMET_TO_EXCEL(gpsbabel_time); - name = (char *)wpt->extra_data; - - gbfprintf(fout, "[Wp%d]" LINE_FEED - "Loc=%s" LINE_FEED - "Name=%s" LINE_FEED - "Lat=%.15f" LINE_FEED - "Long=%.15f" LINE_FEED, - waypt_no, location, name, wpt->latitude, wpt->longitude - ); - gbfprintf(fout, "Rng=%.15f" LINE_FEED - "Bear=%.15f" LINE_FEED - "Bmp=%d" LINE_FEED - "Fixed=1" LINE_FEED - "Locked=0" LINE_FEED - "Notes=%s" LINE_FEED, - 0.0, 0.0, - find_symbol_num(wpt->icon_descr), - notes - ); - gbfprintf(fout, "Rel=" LINE_FEED - "RelSet=0" LINE_FEED - "RcCount=0" LINE_FEED - "RcRadius=%.15f" LINE_FEED - "Show=1" LINE_FEED - "RcShow=0" LINE_FEED - "SeaTemp=%.15f" LINE_FEED - "Depth=%.15f" LINE_FEED - "Time=%.10f00000" LINE_FEED, - 0.0, -32678.0, 65535.0, time - ); - xfree(notes); + char *notes; + char *name; + double time; + + notes = wpt->notes; + if (notes == NULL) { + notes = wpt->description; + if (notes == NULL) { + notes = ""; + } + } + notes = csv_stringclean(notes, LINE_FEED); + time = (wpt->creation_time > 0) ? TIMET_TO_EXCEL(wpt->creation_time) : TIMET_TO_EXCEL(gpsbabel_time); + name = (char *)wpt->extra_data; + + gbfprintf(fout, "[Wp%d]" LINE_FEED + "Loc=%s" LINE_FEED + "Name=%s" LINE_FEED + "Lat=%.15f" LINE_FEED + "Long=%.15f" LINE_FEED, + waypt_no, location, name, wpt->latitude, wpt->longitude + ); + gbfprintf(fout, "Rng=%.15f" LINE_FEED + "Bear=%.15f" LINE_FEED + "Bmp=%d" LINE_FEED + "Fixed=1" LINE_FEED + "Locked=0" LINE_FEED + "Notes=%s" LINE_FEED, + 0.0, 0.0, + find_symbol_num(wpt->icon_descr), + notes + ); + gbfprintf(fout, "Rel=" LINE_FEED + "RelSet=0" LINE_FEED + "RcCount=0" LINE_FEED + "RcRadius=%.15f" LINE_FEED + "Show=1" LINE_FEED + "RcShow=0" LINE_FEED + "SeaTemp=%.15f" LINE_FEED + "Depth=%.15f" LINE_FEED + "Time=%.10f00000" LINE_FEED, + 0.0, -32678.0, 65535.0, time + ); + xfree(notes); } static void write_route_head_cb(const route_head *rte) { - char buff[32]; - char *name; - - name = rte->rte_name; - if ((name == NULL) || (*name == '\0')) { - snprintf(buff, sizeof(buff), "Route%d", rte_index); - name = buff; - } - name = mkshort(hshort_rte, name); - gbfprintf(fout, "[Rt%d]" LINE_FEED - "Name=%s" LINE_FEED - "Visible=1" LINE_FEED, - rte_index, - name - ); - xfree(name); - - rte_index++; - rte_wpt_index = 0; + char buff[32]; + char *name; + + name = rte->rte_name; + if ((name == NULL) || (*name == '\0')) { + snprintf(buff, sizeof(buff), "Route%d", rte_index); + name = buff; + } + name = mkshort(hshort_rte, name); + gbfprintf(fout, "[Rt%d]" LINE_FEED + "Name=%s" LINE_FEED + "Visible=1" LINE_FEED, + rte_index, + name + ); + xfree(name); + + rte_index++; + rte_wpt_index = 0; } static void write_route_wpt_cb(const waypoint *wpt) { - int i; - static const char *items[] = { - "Cog", - "Eta", - "Length", - "PredictedDrift", - "PredictedSet", - "PredictedSog", - "PredictedTime", - "PredictedTwa", - "PredictedTwd", - "PredictedTws" }; - - gbfprintf(fout, "Mk%d=%s" LINE_FEED, rte_wpt_index, (char *)wpt->extra_data); - for (i = 0; i < sizeof(items) / sizeof(char *); i++) - gbfprintf(fout, "%s%d=%.15f" LINE_FEED, items[i], rte_wpt_index, 0.0); - - rte_wpt_index++; - return; + int i; + static const char *items[] = { + "Cog", + "Eta", + "Length", + "PredictedDrift", + "PredictedSet", + "PredictedSog", + "PredictedTime", + "PredictedTwa", + "PredictedTwd", + "PredictedTws" + }; + + gbfprintf(fout, "Mk%d=%s" LINE_FEED, rte_wpt_index, (char *)wpt->extra_data); + for (i = 0; i < sizeof(items) / sizeof(char *); i++) { + gbfprintf(fout, "%s%d=%.15f" LINE_FEED, items[i], rte_wpt_index, 0.0); + } + + rte_wpt_index++; + return; } static void enum_route_hdr_cb(const route_head *rte) { - is_fatal(rte->rte_waypt_ct > 50, - MYNAME ": Routes with more than 50 points are not supported by Waymarine!"); + is_fatal(rte->rte_waypt_ct > 50, + MYNAME ": Routes with more than 50 points are not supported by Waymarine!"); } static short_handle raymarine_new_short_handle(void) { - short_handle res; - - res = mkshort_new_handle(); - - setshort_length(res, 16); - setshort_badchars(res, ","); - setshort_mustupper(res, 0); - setshort_mustuniq(res, 1); - setshort_whitespace_ok(res, 1); - setshort_repeating_whitespace_ok(res, 1); - - return res; + short_handle res; + + res = mkshort_new_handle(); + + setshort_length(res, 16); + setshort_badchars(res, ","); + setshort_mustupper(res, 0); + setshort_mustuniq(res, 1); + setshort_whitespace_ok(res, 1); + setshort_repeating_whitespace_ok(res, 1); + + return res; } static void raymarine_wr_init(const char *fname) { - fout = gbfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); - hshort_wpt = raymarine_new_short_handle(); - hshort_rte = raymarine_new_short_handle(); + hshort_wpt = raymarine_new_short_handle(); + hshort_rte = raymarine_new_short_handle(); } static void raymarine_wr_done(void) { - mkshort_del_handle(&hshort_wpt); - mkshort_del_handle(&hshort_rte); + mkshort_del_handle(&hshort_wpt); + mkshort_del_handle(&hshort_rte); - gbfclose(fout); + gbfclose(fout); } static void raymarine_write(void) { - int i; - waypoint *wpt; - - waypt_table_sz = 0; - waypt_table_ct = 0; - waypt_table = NULL; - - /* enumerate all possible waypoints */ - waypt_disp_all(enum_waypt_cb); - route_disp_all(enum_route_hdr_cb, NULL, enum_rtept_cb); - - if (waypt_table_ct == 0) return; - - qsort(waypt_table, waypt_table_ct, sizeof(*waypt_table), qsort_cb); - - /* write out waypoint summary */ - for (i = 0; i < waypt_table_ct; i++) { - waypoint *wpt = waypt_table[i]; - write_waypoint(fout, wpt, i, opt_location); - } - - /* write out all routes with their waypoints */ - rte_index = 0; - route_disp_all(write_route_head_cb, NULL, write_route_wpt_cb); - - /* release local used data */ - for (i = 0; i < waypt_table_ct; i++) { - wpt = waypt_table[i]; - xfree(wpt->extra_data); - wpt->extra_data = NULL; - } - xfree(waypt_table); + int i; + waypoint *wpt; + + waypt_table_sz = 0; + waypt_table_ct = 0; + waypt_table = NULL; + + /* enumerate all possible waypoints */ + waypt_disp_all(enum_waypt_cb); + route_disp_all(enum_route_hdr_cb, NULL, enum_rtept_cb); + + if (waypt_table_ct == 0) { + return; + } + + qsort(waypt_table, waypt_table_ct, sizeof(*waypt_table), qsort_cb); + + /* write out waypoint summary */ + for (i = 0; i < waypt_table_ct; i++) { + waypoint *wpt = waypt_table[i]; + write_waypoint(fout, wpt, i, opt_location); + } + + /* write out all routes with their waypoints */ + rte_index = 0; + route_disp_all(write_route_head_cb, NULL, write_route_wpt_cb); + + /* release local used data */ + for (i = 0; i < waypt_table_ct; i++) { + wpt = waypt_table[i]; + xfree(wpt->extra_data); + wpt->extra_data = NULL; + } + xfree(waypt_table); } /* ================================================== */ @@ -492,19 +519,19 @@ raymarine_write(void) /* ================================================== */ ff_vecs_t raymarine_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_read | ff_cap_write /* routes */, - }, - raymarine_rd_init, - raymarine_wr_init, - raymarine_rd_done, - raymarine_wr_done, - raymarine_read, - raymarine_write, - NULL, - raymarine_args, - CET_CHARSET_ASCII, 0 /* should we force this to 1 ? */ + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write) /* waypoints */, + ff_cap_none /* tracks */, + (ff_cap)(ff_cap_read | ff_cap_write) /* routes */, + }, + raymarine_rd_init, + raymarine_wr_init, + raymarine_rd_done, + raymarine_wr_done, + raymarine_read, + raymarine_write, + NULL, + raymarine_args, + CET_CHARSET_ASCII, 0 /* should we force this to 1 ? */ }; diff --git a/gpsbabel/reference/arc-project.gpx b/gpsbabel/reference/arc-project.gpx new file mode 100644 index 000000000..b3061f381 --- /dev/null +++ b/gpsbabel/reference/arc-project.gpx @@ -0,0 +1,311 @@ + + + + + + Derecha + Derecha + Derecha + right + + + LAP001 + LAP001 + LAP001 + + + Valle + Valle + Valle + valley + + + wpt1 + wpt1 + wpt1 + flag, green + + + wpt2 + wpt2 + wpt2 + flag, red + + + wpt3 + wpt3 + wpt3 + flag, green + + + wpt4 + wpt4 + wpt4 + flag, green + + + wpt5 + wpt5 + wpt5 + flag, green + + + wpt6 + wpt6 + wpt6 + flag, green + + + Route1 + + RPT001 + + + RPT002 + + + RPT003 + + + RPT004 + + + RPT005 + + + RPT006 + + + RPT007 + + + RPT008 + + + RPT009 + + + RPT010 + + + RPT011 + + + RPT012 + + + RPT013 + + + RPT014 + + + RPT015 + + + RPT016 + + + RPT017 + + + RPT018 + + + RPT019 + + + RPT020 + + + RPT021 + + + RPT022 + + + RPT023 + + + RPT024 + + + RPT025 + + + RPT026 + + + RPT027 + + + RPT028 + + + RPT029 + + + RPT030 + + + + Track1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gpsbabel/reference/arc-project1.gpx b/gpsbabel/reference/arc-project1.gpx new file mode 100644 index 000000000..b45f7b117 --- /dev/null +++ b/gpsbabel/reference/arc-project1.gpx @@ -0,0 +1,270 @@ + + + + + + wpt2 + wpt2 + wpt2 + flag, red + + + wpt3 + wpt3 + wpt3 + flag, green + + + Route1 + + RPT001 + + + RPT002 + + + RPT003 + + + RPT004 + + + RPT005 + + + RPT006 + + + RPT007 + + + RPT008 + + + RPT009 + + + RPT010 + + + RPT011 + + + RPT012 + + + RPT013 + + + RPT014 + + + RPT015 + + + RPT016 + + + RPT017 + + + RPT018 + + + RPT019 + + + RPT020 + + + RPT021 + + + RPT022 + + + RPT023 + + + RPT024 + + + RPT025 + + + RPT026 + + + RPT027 + + + RPT028 + + + RPT029 + + + RPT030 + + + + Track1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gpsbabel/reference/arc-project2.gpx b/gpsbabel/reference/arc-project2.gpx new file mode 100644 index 000000000..fedf58346 --- /dev/null +++ b/gpsbabel/reference/arc-project2.gpx @@ -0,0 +1,282 @@ + + + + + + wpt1 + wpt1 + wpt1 + flag, green + + + wpt4 + wpt4 + wpt4 + flag, green + + + wpt5 + wpt5 + wpt5 + flag, green + + + wpt6 + wpt6 + wpt6 + flag, green + + + Route1 + + RPT001 + + + RPT002 + + + RPT003 + + + RPT004 + + + RPT005 + + + RPT006 + + + RPT007 + + + RPT008 + + + RPT009 + + + RPT010 + + + RPT011 + + + RPT012 + + + RPT013 + + + RPT014 + + + RPT015 + + + RPT016 + + + RPT017 + + + RPT018 + + + RPT019 + + + RPT020 + + + RPT021 + + + RPT022 + + + RPT023 + + + RPT024 + + + RPT025 + + + RPT026 + + + RPT027 + + + RPT028 + + + RPT029 + + + RPT030 + + + + Track1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gpsbabel/reference/arc-project3.gpx b/gpsbabel/reference/arc-project3.gpx new file mode 100644 index 000000000..188cd58b0 --- /dev/null +++ b/gpsbabel/reference/arc-project3.gpx @@ -0,0 +1,299 @@ + + + + + + + Derecha + Derecha + Derecha + right + + + + LAP001 + LAP001 + LAP001 + + + + Valle + Valle + Valle + valley + + + + wpt1 + wpt1 + wpt1 + flag, green + + + + wpt5 + wpt5 + wpt5 + flag, green + + + + wpt6 + wpt6 + wpt6 + flag, green + + + Route1 + + RPT001 + + + RPT002 + + + RPT003 + + + RPT004 + + + RPT005 + + + RPT006 + + + RPT007 + + + RPT008 + + + RPT009 + + + RPT010 + + + RPT011 + + + RPT012 + + + RPT013 + + + RPT014 + + + RPT015 + + + RPT016 + + + RPT017 + + + RPT018 + + + RPT019 + + + RPT020 + + + RPT021 + + + RPT022 + + + RPT023 + + + RPT024 + + + RPT025 + + + RPT026 + + + RPT027 + + + RPT028 + + + RPT029 + + + RPT030 + + + + Track1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gpsbabel/reference/bounds-test.gpx b/gpsbabel/reference/bounds-test.gpx new file mode 100644 index 000000000..dd69a0740 --- /dev/null +++ b/gpsbabel/reference/bounds-test.gpx @@ -0,0 +1,499 @@ + + + + + 479.3 + Head east on CA-190 E/Nadeau Trail Continue to follow CA-190 E + go 52.3&#160;mi + go 52.3&#160;mi + + + -55.6 + Turn right at Airport Rd + go 0.8&#160;mi + go 0.8&#160;mi + + + -67.3 + Arrive at: Furnace Creek Airport-L06, Death Valley National Park, Death Valley, CA 92328 + Arrive at: Furnace Creek Airport-L06, Death Valley National Park, Death Valley, CA 92328 + Arrive at: Furnace Creek Airport-L06, Death Valley National Park, Death Valley, CA 92328 + + + 2272.300000 + Head northwest + go 3.0&#160;mi + go 3.0&#160;mi + + + 1734.200000 + Continue straight onto Charcoal Kiln Rd + go 4.2&#160;mi + go 4.2&#160;mi + + + 1304.100000 + Continue onto Wood Canyon Rd + go 0.7&#160;mi + go 0.7&#160;mi + + + 1226.400000 + Continue onto Wildrose Rd + go 7.9&#160;mi + go 7.9&#160;mi + + + 1595.800000 + Slight left to stay on Wildrose Rd + go 13.2&#160;mi + go 13.2&#160;mi + + + 669.800000 + Arrive at: Wildrose Rd + Arrive at: Wildrose Rd + Arrive at: Wildrose Rd + + + Head east on Airport Rd + go 0.8&#160;mi + go 0.8&#160;mi + + + Arrive at: Airport Rd + Arrive at: Airport Rd + Arrive at: Airport Rd + + + Low Road + Generated from track Route + + 479.3 + RPT001 + + + 624.3 + RPT005 + + + 663.7 + RPT011 + + + 762.1 + RPT019 + + + 927.4 + RPT027 + + + 940.4 + RPT032 + + + 969.3 + RPT038 + + + 1028.2 + RPT046 + + + 1094.5 + RPT054 + + + 1132.7 + RPT060 + + + 1184.9 + RPT065 + + + 1201.8 + RPT068 + + + 1281.7 + RPT076 + + + 1311.3 + RPT081 + + + 1493.9 + RPT096 + + + 1439.5 + RPT104 + + + 1395.5 + RPT107 + + + 1377.7 + RPT112 + + + 1291.5 + RPT125 + + + 1226.0 + RPT130 + + + 1089.0 + RPT138 + + + 926.0 + RPT147 + + + 669.9 + RPT152 + + + 514.4 + RPT160 + + + 449.5 + RPT163 + + + 216.3 + RPT169 + + + 3.4 + RPT176 + + + -4.4 + RPT182 + + + -5.4 + RPT185 + + + -0.2 + RPT190 + + + -2.6 + RPT194 + + + -1.3 + RPT200 + + + -4.9 + RPT205 + + + -8.9 + RPT209 + + + -13.0 + RPT212 + + + -21.2 + RPT223 + + + 36.8 + RPT224 + + + 39.9 + RPT229 + + + 45.0 + RPT232 + + + 45.9 + RPT236 + + + 45.2 + RPT241 + + + 42.5 + RPT246 + + + -49.1 + RPT259 + + + -55.9 + RPT265 + + + -60.4 + RPT279 + + + -67.9 + RPT287 + + + -69.8 + RPT298 + + + -68.7 + RPT307 + + + -69.1 + RPT312 + + + -67.6 + RPT320 + + + -69.3 + RPT326 + + + -69.9 + RPT331 + + + -63.6 + RPT344 + + + -61.0 + RPT352 + + + -57.9 + RPT356 + + + -39.8 + RPT362 + + + -57.7 + RPT371 + + + -64.4 + RPT377 + + + -55.6 + RPT386 + + + -67.3 + RPT399 + + + + High Road + Generated from track Route + + 2272.300000 + RPT001 + + + 2128.600000 + RPT014 + + + 2025.200000 + RPT025 + + + 1721.800000 + RPT056 + + + 1661.600000 + RPT063 + + + 1593.300000 + RPT067 + + + 1510.700000 + RPT075 + + + 1315.700000 + RPT089 + + + 1224.500000 + RPT112 + + + 1265.600000 + RPT119 + + + 1333.500000 + RPT140 + + + 1390.900000 + RPT147 + + + 1422.700000 + RPT152 + + + 1480.300000 + RPT162 + + + 1495.400000 + RPT167 + + + 1590.200000 + RPT189 + + + 1655.700000 + RPT218 + + + 1626.500000 + RPT263 + + + 1594.100000 + RPT279 + + + 1515.200000 + RPT286 + + + 1495.800000 + RPT294 + + + 1467.700000 + RPT309 + + + 1447.900000 + RPT317 + + + 1352.700000 + RPT340 + + + 1322.000000 + RPT350 + + + 1264.800000 + RPT356 + + + 1220.000000 + RPT362 + + + 1178.100000 + RPT370 + + + 1034.900000 + RPT389 + + + 1012.300000 + RPT393 + + + 836.700000 + RPT409 + + + 815.300000 + RPT414 + + + 739.100000 + RPT419 + + + 685.000000 + RPT426 + + + 669.800000 + RPT430 + + + + No Elevation Route + Generated from track No Elevation Route + + RPT001 + + + RPT002 + + + RPT003 + + + RPT004 + + + RPT005 + + + RPT006 + + + RPT007 + + + RPT008 + + + RPT009 + + + RPT010 + + + RPT011 + + + RPT012 + + + RPT013 + + + diff --git a/gpsbabel/reference/bounds-test.kml b/gpsbabel/reference/bounds-test.kml new file mode 100644 index 000000000..a0a66ae0e --- /dev/null +++ b/gpsbabel/reference/bounds-test.kml @@ -0,0 +1,2463 @@ + + + + GPS device + + -117.144015 + 36.438270 + 87257.203848 + + + + + + + + normal + #route_n + + + highlight + #route_h + + + + + + + + + normal + #waypoint_n + + + highlight + #waypoint_h + + + + + Waypoints + + Head east on CA-190 E/Nadeau Trail Continue to follow CA-190 E + go 52.3&#160;mi + #waypoint + + -117.422570,36.339560,479.30 + + + + Turn right at Airport Rd + go 0.8&#160;mi + #waypoint + + -116.865460,36.460850,-55.60 + + + + Arrive at: Furnace Creek Airport-L06, Death Valley National Park, Death Valley, CA 92328 + #waypoint + + -116.879200,36.463640,-67.30 + + + + Head northwest + go 3.0&#160;mi + #waypoint + + -117.072030,36.236600,2272.30 + + + + Continue straight onto Charcoal Kiln Rd + go 4.2&#160;mi + #waypoint + + -117.113260,36.253260,1734.20 + + + + Continue onto Wood Canyon Rd + go 0.7&#160;mi + #waypoint + + -117.179860,36.264610,1304.10 + + + + Continue onto Wildrose Rd + go 7.9&#160;mi + #waypoint + + -117.192050,36.265430,1226.40 + + + + Slight left to stay on Wildrose Rd + go 13.2&#160;mi + #waypoint + + -117.135520,36.335600,1595.80 + + + + Arrive at: Wildrose Rd + #waypoint + + -117.226936,36.494947,669.80 + + + + Head east on Airport Rd + go 0.8&#160;mi + #waypoint + + -116.879080,36.463670 + + + + Arrive at: Airport Rd + #waypoint + + -116.865720,36.460860 + + + + + Routes + + Low Road + + Points + + RPT001 + + + Longitude: -117.422570 + Latitude: 36.339560 + Altitude: 1572.507 ft + + ]]> + + -117.422570 + 36.339560 + 66 + + #route + + -117.422570,36.339560,479.30 + + + + RPT005 + + + Longitude: -117.354270 + Latitude: 36.345010 + Altitude: 2048.228 ft + + ]]> + + -117.354270 + 36.345010 + 66 + + #route + + -117.354270,36.345010,624.30 + + + + RPT011 + + + Longitude: -117.349030 + Latitude: 36.344640 + Altitude: 2177.493 ft + + ]]> + + -117.349030 + 36.344640 + 66 + + #route + + -117.349030,36.344640,663.70 + + + + RPT019 + + + Longitude: -117.335270 + Latitude: 36.348710 + Altitude: 2500.328 ft + + ]]> + + -117.335270 + 36.348710 + 66 + + #route + + -117.335270,36.348710,762.10 + + + + RPT027 + + + Longitude: -117.316960 + Latitude: 36.346040 + Altitude: 3042.651 ft + + ]]> + + -117.316960 + 36.346040 + 66 + + #route + + -117.316960,36.346040,927.40 + + + + RPT032 + + + Longitude: -117.314020 + Latitude: 36.343080 + Altitude: 3085.302 ft + + ]]> + + -117.314020 + 36.343080 + 66 + + #route + + -117.314020,36.343080,940.40 + + + + RPT038 + + + Longitude: -117.311530 + Latitude: 36.342480 + Altitude: 3180.118 ft + + ]]> + + -117.311530 + 36.342480 + 66 + + #route + + -117.311530,36.342480,969.30 + + + + RPT046 + + + Longitude: -117.307620 + Latitude: 36.346880 + Altitude: 3373.360 ft + + ]]> + + -117.307620 + 36.346880 + 66 + + #route + + -117.307620,36.346880,1028.20 + + + + RPT054 + + + Longitude: -117.301180 + Latitude: 36.347060 + Altitude: 3590.879 ft + + ]]> + + -117.301180 + 36.347060 + 66 + + #route + + -117.301180,36.347060,1094.50 + + + + RPT060 + + + Longitude: -117.295650 + Latitude: 36.351920 + Altitude: 3716.207 ft + + ]]> + + -117.295650 + 36.351920 + 66 + + #route + + -117.295650,36.351920,1132.70 + + + + RPT065 + + + Longitude: -117.292270 + Latitude: 36.357050 + Altitude: 3887.467 ft + + ]]> + + -117.292270 + 36.357050 + 66 + + #route + + -117.292270,36.357050,1184.90 + + + + RPT068 + + + Longitude: -117.289430 + Latitude: 36.358440 + Altitude: 3942.913 ft + + ]]> + + -117.289430 + 36.358440 + 66 + + #route + + -117.289430,36.358440,1201.80 + + + + RPT076 + + + Longitude: -117.286380 + Latitude: 36.364320 + Altitude: 4205.052 ft + + ]]> + + -117.286380 + 36.364320 + 66 + + #route + + -117.286380,36.364320,1281.70 + + + + RPT081 + + + Longitude: -117.287070 + Latitude: 36.367970 + Altitude: 4302.165 ft + + ]]> + + -117.287070 + 36.367970 + 66 + + #route + + -117.287070,36.367970,1311.30 + + + + RPT096 + + + Longitude: -117.278460 + Latitude: 36.406150 + Altitude: 4901.247 ft + + ]]> + + -117.278460 + 36.406150 + 66 + + #route + + -117.278460,36.406150,1493.90 + + + + RPT104 + + + Longitude: -117.274150 + Latitude: 36.414650 + Altitude: 4722.769 ft + + ]]> + + -117.274150 + 36.414650 + 66 + + #route + + -117.274150,36.414650,1439.50 + + + + RPT107 + + + Longitude: -117.270260 + Latitude: 36.419620 + Altitude: 4578.412 ft + + ]]> + + -117.270260 + 36.419620 + 66 + + #route + + -117.270260,36.419620,1395.50 + + + + RPT112 + + + Longitude: -117.267430 + Latitude: 36.419700 + Altitude: 4520.013 ft + + ]]> + + -117.267430 + 36.419700 + 66 + + #route + + -117.267430,36.419700,1377.70 + + + + RPT125 + + + Longitude: -117.260620 + Latitude: 36.428730 + Altitude: 4237.205 ft + + ]]> + + -117.260620 + 36.428730 + 66 + + #route + + -117.260620,36.428730,1291.50 + + + + RPT130 + + + Longitude: -117.251140 + Latitude: 36.434140 + Altitude: 4022.310 ft + + ]]> + + -117.251140 + 36.434140 + 66 + + #route + + -117.251140,36.434140,1226.00 + + + + RPT138 + + + Longitude: -117.243900 + Latitude: 36.446250 + Altitude: 3572.835 ft + + ]]> + + -117.243900 + 36.446250 + 66 + + #route + + -117.243900,36.446250,1089.00 + + + + RPT147 + + + Longitude: -117.236110 + Latitude: 36.463810 + Altitude: 3038.058 ft + + ]]> + + -117.236110 + 36.463810 + 66 + + #route + + -117.236110,36.463810,926.00 + + + + RPT152 + + + Longitude: -117.226980 + Latitude: 36.494960 + Altitude: 2197.835 ft + + ]]> + + -117.226980 + 36.494960 + 66 + + #route + + -117.226980,36.494960,669.90 + + + + RPT160 + + + Longitude: -117.222650 + Latitude: 36.519980 + Altitude: 1687.664 ft + + ]]> + + -117.222650 + 36.519980 + 66 + + #route + + -117.222650,36.519980,514.40 + + + + RPT163 + + + Longitude: -117.218940 + Latitude: 36.529870 + Altitude: 1474.738 ft + + ]]> + + -117.218940 + 36.529870 + 66 + + #route + + -117.218940,36.529870,449.50 + + + + RPT169 + + + Longitude: -117.199580 + Latitude: 36.563200 + Altitude: 709.646 ft + + ]]> + + -117.199580 + 36.563200 + 66 + + #route + + -117.199580,36.563200,216.30 + + + + RPT176 + + + Longitude: -117.147410 + Latitude: 36.605940 + Altitude: 11.155 ft + + ]]> + + -117.147410 + 36.605940 + 66 + + #route + + -117.147410,36.605940,3.40 + + + + RPT182 + + + Longitude: -117.143600 + Latitude: 36.607880 + Altitude: -14.436 ft + + ]]> + + -117.143600 + 36.607880 + 66 + + #route + + -117.143600,36.607880,-4.40 + + + + RPT185 + + + Longitude: -117.137140 + Latitude: 36.607210 + Altitude: -17.717 ft + + ]]> + + -117.137140 + 36.607210 + 66 + + #route + + -117.137140,36.607210,-5.40 + + + + RPT190 + + + Longitude: -117.127830 + Latitude: 36.603590 + Altitude: -0.656 ft + + ]]> + + -117.127830 + 36.603590 + 66 + + #route + + -117.127830,36.603590,-0.20 + + + + RPT194 + + + Longitude: -117.117700 + Latitude: 36.605420 + Altitude: -8.530 ft + + ]]> + + -117.117700 + 36.605420 + 66 + + #route + + -117.117700,36.605420,-2.60 + + + + RPT200 + + + Longitude: -117.106740 + Latitude: 36.604640 + Altitude: -4.265 ft + + ]]> + + -117.106740 + 36.604640 + 66 + + #route + + -117.106740,36.604640,-1.30 + + + + RPT205 + + + Longitude: -117.097480 + Latitude: 36.601210 + Altitude: -16.076 ft + + ]]> + + -117.097480 + 36.601210 + 66 + + #route + + -117.097480,36.601210,-4.90 + + + + RPT209 + + + Longitude: -117.094200 + Latitude: 36.601720 + Altitude: -29.199 ft + + ]]> + + -117.094200 + 36.601720 + 66 + + #route + + -117.094200,36.601720,-8.90 + + + + RPT212 + + + Longitude: -117.082040 + Latitude: 36.611300 + Altitude: -42.651 ft + + ]]> + + -117.082040 + 36.611300 + 66 + + #route + + -117.082040,36.611300,-13.00 + + + + RPT223 + + + Longitude: -117.067710 + Latitude: 36.617900 + Altitude: -69.554 ft + + ]]> + + -117.067710 + 36.617900 + 66 + + #route + + -117.067710,36.617900,-21.20 + + + + RPT224 + + + Longitude: -117.035740 + Latitude: 36.639210 + Altitude: 120.735 ft + + ]]> + + -117.035740 + 36.639210 + 66 + + #route + + -117.035740,36.639210,36.80 + + + + RPT229 + + + Longitude: -117.031520 + Latitude: 36.639940 + Altitude: 130.906 ft + + ]]> + + -117.031520 + 36.639940 + 66 + + #route + + -117.031520,36.639940,39.90 + + + + RPT232 + + + Longitude: -117.029010 + Latitude: 36.638970 + Altitude: 147.638 ft + + ]]> + + -117.029010 + 36.638970 + 66 + + #route + + -117.029010,36.638970,45.00 + + + + RPT236 + + + Longitude: -117.024030 + Latitude: 36.633800 + Altitude: 150.591 ft + + ]]> + + -117.024030 + 36.633800 + 66 + + #route + + -117.024030,36.633800,45.90 + + + + RPT241 + + + Longitude: -117.016190 + Latitude: 36.628480 + Altitude: 148.294 ft + + ]]> + + -117.016190 + 36.628480 + 66 + + #route + + -117.016190,36.628480,45.20 + + + + RPT246 + + + Longitude: -117.006890 + Latitude: 36.625430 + Altitude: 139.436 ft + + ]]> + + -117.006890 + 36.625430 + 66 + + #route + + -117.006890,36.625430,42.50 + + + + RPT259 + + + Longitude: -116.969890 + Latitude: 36.596550 + Altitude: -161.089 ft + + ]]> + + -116.969890 + 36.596550 + 66 + + #route + + -116.969890,36.596550,-49.10 + + + + RPT265 + + + Longitude: -116.954760 + Latitude: 36.592470 + Altitude: -183.399 ft + + ]]> + + -116.954760 + 36.592470 + 66 + + #route + + -116.954760,36.592470,-55.90 + + + + RPT279 + + + Longitude: -116.936270 + Latitude: 36.584200 + Altitude: -198.163 ft + + ]]> + + -116.936270 + 36.584200 + 66 + + #route + + -116.936270,36.584200,-60.40 + + + + RPT287 + + + Longitude: -116.927060 + Latitude: 36.575990 + Altitude: -222.769 ft + + ]]> + + -116.927060 + 36.575990 + 66 + + #route + + -116.927060,36.575990,-67.90 + + + + RPT298 + + + Longitude: -116.909750 + Latitude: 36.568520 + Altitude: -229.003 ft + + ]]> + + -116.909750 + 36.568520 + 66 + + #route + + -116.909750,36.568520,-69.80 + + + + RPT307 + + + Longitude: -116.904380 + Latitude: 36.561450 + Altitude: -225.394 ft + + ]]> + + -116.904380 + 36.561450 + 66 + + #route + + -116.904380,36.561450,-68.70 + + + + RPT312 + + + Longitude: -116.894840 + Latitude: 36.557140 + Altitude: -226.706 ft + + ]]> + + -116.894840 + 36.557140 + 66 + + #route + + -116.894840,36.557140,-69.10 + + + + RPT320 + + + Longitude: -116.891610 + Latitude: 36.549690 + Altitude: -221.785 ft + + ]]> + + -116.891610 + 36.549690 + 66 + + #route + + -116.891610,36.549690,-67.60 + + + + RPT326 + + + Longitude: -116.886030 + Latitude: 36.543000 + Altitude: -227.362 ft + + ]]> + + -116.886030 + 36.543000 + 66 + + #route + + -116.886030,36.543000,-69.30 + + + + RPT331 + + + Longitude: -116.882770 + Latitude: 36.532760 + Altitude: -229.331 ft + + ]]> + + -116.882770 + 36.532760 + 66 + + #route + + -116.882770,36.532760,-69.90 + + + + RPT344 + + + Longitude: -116.881860 + Latitude: 36.513990 + Altitude: -208.661 ft + + ]]> + + -116.881860 + 36.513990 + 66 + + #route + + -116.881860,36.513990,-63.60 + + + + RPT352 + + + Longitude: -116.875450 + Latitude: 36.502030 + Altitude: -200.131 ft + + ]]> + + -116.875450 + 36.502030 + 66 + + #route + + -116.875450,36.502030,-61.00 + + + + RPT356 + + + Longitude: -116.875070 + Latitude: 36.498060 + Altitude: -189.961 ft + + ]]> + + -116.875070 + 36.498060 + 66 + + #route + + -116.875070,36.498060,-57.90 + + + + RPT362 + + + Longitude: -116.868420 + Latitude: 36.487220 + Altitude: -130.577 ft + + ]]> + + -116.868420 + 36.487220 + 66 + + #route + + -116.868420,36.487220,-39.80 + + + + RPT371 + + + Longitude: -116.871370 + Latitude: 36.482910 + Altitude: -189.304 ft + + ]]> + + -116.871370 + 36.482910 + 66 + + #route + + -116.871370,36.482910,-57.70 + + + + RPT377 + + + Longitude: -116.868950 + Latitude: 36.479500 + Altitude: -211.286 ft + + ]]> + + -116.868950 + 36.479500 + 66 + + #route + + -116.868950,36.479500,-64.40 + + + + RPT386 + + + Longitude: -116.865460 + Latitude: 36.460850 + Altitude: -182.415 ft + + ]]> + + -116.865460 + 36.460850 + 66 + + #route + + -116.865460,36.460850,-55.60 + + + + RPT399 + + + Longitude: -116.879200 + Latitude: 36.463640 + Altitude: -220.801 ft + + ]]> + + -116.879200 + 36.463640 + 66 + + #route + + -116.879200,36.463640,-67.30 + + + + + Path + #lineStyle + + 1 + + -117.422570,36.339560,479.30 + -117.354270,36.345010,624.30 + -117.349030,36.344640,663.70 + -117.335270,36.348710,762.10 + -117.316960,36.346040,927.40 + -117.314020,36.343080,940.40 + -117.311530,36.342480,969.30 + -117.307620,36.346880,1028.20 + -117.301180,36.347060,1094.50 + -117.295650,36.351920,1132.70 + -117.292270,36.357050,1184.90 + -117.289430,36.358440,1201.80 + -117.286380,36.364320,1281.70 + -117.287070,36.367970,1311.30 + -117.278460,36.406150,1493.90 + -117.274150,36.414650,1439.50 + -117.270260,36.419620,1395.50 + -117.267430,36.419700,1377.70 + -117.260620,36.428730,1291.50 + -117.251140,36.434140,1226.00 + -117.243900,36.446250,1089.00 + -117.236110,36.463810,926.00 + -117.226980,36.494960,669.90 + -117.222650,36.519980,514.40 + -117.218940,36.529870,449.50 + -117.199580,36.563200,216.30 + -117.147410,36.605940,3.40 + -117.143600,36.607880,-4.40 + -117.137140,36.607210,-5.40 + -117.127830,36.603590,-0.20 + -117.117700,36.605420,-2.60 + -117.106740,36.604640,-1.30 + -117.097480,36.601210,-4.90 + -117.094200,36.601720,-8.90 + -117.082040,36.611300,-13.00 + -117.067710,36.617900,-21.20 + -117.035740,36.639210,36.80 + -117.031520,36.639940,39.90 + -117.029010,36.638970,45.00 + -117.024030,36.633800,45.90 + -117.016190,36.628480,45.20 + -117.006890,36.625430,42.50 + -116.969890,36.596550,-49.10 + -116.954760,36.592470,-55.90 + -116.936270,36.584200,-60.40 + -116.927060,36.575990,-67.90 + -116.909750,36.568520,-69.80 + -116.904380,36.561450,-68.70 + -116.894840,36.557140,-69.10 + -116.891610,36.549690,-67.60 + -116.886030,36.543000,-69.30 + -116.882770,36.532760,-69.90 + -116.881860,36.513990,-63.60 + -116.875450,36.502030,-61.00 + -116.875070,36.498060,-57.90 + -116.868420,36.487220,-39.80 + -116.871370,36.482910,-57.70 + -116.868950,36.479500,-64.40 + -116.865460,36.460850,-55.60 + -116.879200,36.463640,-67.30 + + + + + + High Road + + Points + + RPT001 + + + Longitude: -117.072030 + Latitude: 36.236600 + Altitude: 7455.053 ft + + ]]> + + -117.072030 + 36.236600 + 66 + + #route + + -117.072030,36.236600,2272.30 + + + + RPT014 + + + Longitude: -117.074910 + Latitude: 36.245280 + Altitude: 6983.596 ft + + ]]> + + -117.074910 + 36.245280 + 66 + + #route + + -117.074910,36.245280,2128.60 + + + + RPT025 + + + Longitude: -117.082060 + Latitude: 36.250720 + Altitude: 6644.357 ft + + ]]> + + -117.082060 + 36.250720 + 66 + + #route + + -117.082060,36.250720,2025.20 + + + + RPT056 + + + Longitude: -117.114930 + Latitude: 36.253250 + Altitude: 5648.950 ft + + ]]> + + -117.114930 + 36.253250 + 66 + + #route + + -117.114930,36.253250,1721.80 + + + + RPT063 + + + Longitude: -117.124070 + Latitude: 36.249180 + Altitude: 5451.444 ft + + ]]> + + -117.124070 + 36.249180 + 66 + + #route + + -117.124070,36.249180,1661.60 + + + + RPT067 + + + Longitude: -117.140500 + Latitude: 36.248030 + Altitude: 5227.362 ft + + ]]> + + -117.140500 + 36.248030 + 66 + + #route + + -117.140500,36.248030,1593.30 + + + + RPT075 + + + Longitude: -117.154180 + Latitude: 36.250220 + Altitude: 4956.365 ft + + ]]> + + -117.154180 + 36.250220 + 66 + + #route + + -117.154180,36.250220,1510.70 + + + + RPT089 + + + Longitude: -117.178010 + Latitude: 36.264660 + Altitude: 4316.601 ft + + ]]> + + -117.178010 + 36.264660 + 66 + + #route + + -117.178010,36.264660,1315.70 + + + + RPT112 + + + Longitude: -117.195180 + Latitude: 36.265950 + Altitude: 4017.388 ft + + ]]> + + -117.195180 + 36.265950 + 66 + + #route + + -117.195180,36.265950,1224.50 + + + + RPT119 + + + Longitude: -117.195290 + Latitude: 36.268100 + Altitude: 4152.231 ft + + ]]> + + -117.195290 + 36.268100 + 66 + + #route + + -117.195290,36.268100,1265.60 + + + + RPT140 + + + Longitude: -117.186690 + Latitude: 36.271540 + Altitude: 4375.000 ft + + ]]> + + -117.186690 + 36.271540 + 66 + + #route + + -117.186690,36.271540,1333.50 + + + + RPT147 + + + Longitude: -117.187690 + Latitude: 36.283430 + Altitude: 4563.320 ft + + ]]> + + -117.187690 + 36.283430 + 66 + + #route + + -117.187690,36.283430,1390.90 + + + + RPT152 + + + Longitude: -117.184800 + Latitude: 36.288060 + Altitude: 4667.651 ft + + ]]> + + -117.184800 + 36.288060 + 66 + + #route + + -117.184800,36.288060,1422.70 + + + + RPT162 + + + Longitude: -117.175450 + Latitude: 36.292430 + Altitude: 4856.627 ft + + ]]> + + -117.175450 + 36.292430 + 66 + + #route + + -117.175450,36.292430,1480.30 + + + + RPT167 + + + Longitude: -117.174710 + Latitude: 36.299830 + Altitude: 4906.168 ft + + ]]> + + -117.174710 + 36.299830 + 66 + + #route + + -117.174710,36.299830,1495.40 + + + + RPT189 + + + Longitude: -117.147920 + Latitude: 36.307650 + Altitude: 5217.192 ft + + ]]> + + -117.147920 + 36.307650 + 66 + + #route + + -117.147920,36.307650,1590.20 + + + + RPT218 + + + Longitude: -117.155360 + Latitude: 36.315930 + Altitude: 5432.087 ft + + ]]> + + -117.155360 + 36.315930 + 66 + + #route + + -117.155360,36.315930,1655.70 + + + + RPT263 + + + Longitude: -117.147000 + Latitude: 36.332460 + Altitude: 5336.286 ft + + ]]> + + -117.147000 + 36.332460 + 66 + + #route + + -117.147000,36.332460,1626.50 + + + + RPT279 + + + Longitude: -117.135460 + Latitude: 36.335790 + Altitude: 5229.987 ft + + ]]> + + -117.135460 + 36.335790 + 66 + + #route + + -117.135460,36.335790,1594.10 + + + + RPT286 + + + Longitude: -117.133870 + Latitude: 36.359960 + Altitude: 4971.129 ft + + ]]> + + -117.133870 + 36.359960 + 66 + + #route + + -117.133870,36.359960,1515.20 + + + + RPT294 + + + Longitude: -117.142570 + Latitude: 36.376850 + Altitude: 4907.480 ft + + ]]> + + -117.142570 + 36.376850 + 66 + + #route + + -117.142570,36.376850,1495.80 + + + + RPT309 + + + Longitude: -117.156910 + Latitude: 36.394590 + Altitude: 4815.289 ft + + ]]> + + -117.156910 + 36.394590 + 66 + + #route + + -117.156910,36.394590,1467.70 + + + + RPT317 + + + Longitude: -117.166230 + Latitude: 36.398990 + Altitude: 4750.328 ft + + ]]> + + -117.166230 + 36.398990 + 66 + + #route + + -117.166230,36.398990,1447.90 + + + + RPT340 + + + Longitude: -117.177600 + Latitude: 36.413520 + Altitude: 4437.992 ft + + ]]> + + -117.177600 + 36.413520 + 66 + + #route + + -117.177600,36.413520,1352.70 + + + + RPT350 + + + Longitude: -117.185560 + Latitude: 36.415730 + Altitude: 4337.270 ft + + ]]> + + -117.185560 + 36.415730 + 66 + + #route + + -117.185560,36.415730,1322.00 + + + + RPT356 + + + Longitude: -117.187740 + Latitude: 36.421720 + Altitude: 4149.606 ft + + ]]> + + -117.187740 + 36.421720 + 66 + + #route + + -117.187740,36.421720,1264.80 + + + + RPT362 + + + Longitude: -117.192970 + Latitude: 36.426060 + Altitude: 4002.625 ft + + ]]> + + -117.192970 + 36.426060 + 66 + + #route + + -117.192970,36.426060,1220.00 + + + + RPT370 + + + Longitude: -117.191580 + Latitude: 36.431930 + Altitude: 3865.157 ft + + ]]> + + -117.191580 + 36.431930 + 66 + + #route + + -117.191580,36.431930,1178.10 + + + + RPT389 + + + Longitude: -117.200850 + Latitude: 36.450210 + Altitude: 3395.341 ft + + ]]> + + -117.200850 + 36.450210 + 66 + + #route + + -117.200850,36.450210,1034.90 + + + + RPT393 + + + Longitude: -117.204490 + Latitude: 36.451910 + Altitude: 3321.194 ft + + ]]> + + -117.204490 + 36.451910 + 66 + + #route + + -117.204490,36.451910,1012.30 + + + + RPT409 + + + Longitude: -117.211120 + Latitude: 36.475590 + Altitude: 2745.079 ft + + ]]> + + -117.211120 + 36.475590 + 66 + + #route + + -117.211120,36.475590,836.70 + + + + RPT414 + + + Longitude: -117.214550 + Latitude: 36.476240 + Altitude: 2674.869 ft + + ]]> + + -117.214550 + 36.476240 + 66 + + #route + + -117.214550,36.476240,815.30 + + + + RPT419 + + + Longitude: -117.222200 + Latitude: 36.485010 + Altitude: 2424.869 ft + + ]]> + + -117.222200 + 36.485010 + 66 + + #route + + -117.222200,36.485010,739.10 + + + + RPT426 + + + Longitude: -117.224040 + Latitude: 36.492950 + Altitude: 2247.375 ft + + ]]> + + -117.224040 + 36.492950 + 66 + + #route + + -117.224040,36.492950,685.00 + + + + RPT430 + + + Longitude: -117.226940 + Latitude: 36.494950 + Altitude: 2197.507 ft + + ]]> + + -117.226940 + 36.494950 + 66 + + #route + + -117.226940,36.494950,669.80 + + + + + Path + #lineStyle + + 1 + + -117.072030,36.236600,2272.30 + -117.074910,36.245280,2128.60 + -117.082060,36.250720,2025.20 + -117.114930,36.253250,1721.80 + -117.124070,36.249180,1661.60 + -117.140500,36.248030,1593.30 + -117.154180,36.250220,1510.70 + -117.178010,36.264660,1315.70 + -117.195180,36.265950,1224.50 + -117.195290,36.268100,1265.60 + -117.186690,36.271540,1333.50 + -117.187690,36.283430,1390.90 + -117.184800,36.288060,1422.70 + -117.175450,36.292430,1480.30 + -117.174710,36.299830,1495.40 + -117.147920,36.307650,1590.20 + -117.155360,36.315930,1655.70 + -117.147000,36.332460,1626.50 + -117.135460,36.335790,1594.10 + -117.133870,36.359960,1515.20 + -117.142570,36.376850,1495.80 + -117.156910,36.394590,1467.70 + -117.166230,36.398990,1447.90 + -117.177600,36.413520,1352.70 + -117.185560,36.415730,1322.00 + -117.187740,36.421720,1264.80 + -117.192970,36.426060,1220.00 + -117.191580,36.431930,1178.10 + -117.200850,36.450210,1034.90 + -117.204490,36.451910,1012.30 + -117.211120,36.475590,836.70 + -117.214550,36.476240,815.30 + -117.222200,36.485010,739.10 + -117.224040,36.492950,685.00 + -117.226940,36.494950,669.80 + + + + + + No Elevation Route + + Points + + RPT001 + + + Longitude: -116.879080 + Latitude: 36.463670 + + ]]> + + -116.879080 + 36.463670 + 66 + + #route + + -116.879080,36.463670 + + + + RPT002 + + + Longitude: -116.878300 + Latitude: 36.463860 + + ]]> + + -116.878300 + 36.463860 + 66 + + #route + + -116.878300,36.463860 + + + + RPT003 + + + Longitude: -116.878140 + Latitude: 36.463880 + + ]]> + + -116.878140 + 36.463880 + 66 + + #route + + -116.878140,36.463880 + + + + RPT004 + + + Longitude: -116.877910 + Latitude: 36.463840 + + ]]> + + -116.877910 + 36.463840 + 66 + + #route + + -116.877910,36.463840 + + + + RPT005 + + + Longitude: -116.876800 + Latitude: 36.463450 + + ]]> + + -116.876800 + 36.463450 + 66 + + #route + + -116.876800,36.463450 + + + + RPT006 + + + Longitude: -116.872870 + Latitude: 36.462240 + + ]]> + + -116.872870 + 36.462240 + 66 + + #route + + -116.872870,36.462240 + + + + RPT007 + + + Longitude: -116.868650 + Latitude: 36.460990 + + ]]> + + -116.868650 + 36.460990 + 66 + + #route + + -116.868650,36.460990 + + + + RPT008 + + + Longitude: -116.868250 + Latitude: 36.461010 + + ]]> + + -116.868250 + 36.461010 + 66 + + #route + + -116.868250,36.461010 + + + + RPT009 + + + Longitude: -116.867660 + Latitude: 36.461210 + + ]]> + + -116.867660 + 36.461210 + 66 + + #route + + -116.867660,36.461210 + + + + RPT010 + + + Longitude: -116.867020 + Latitude: 36.460950 + + ]]> + + -116.867020 + 36.460950 + 66 + + #route + + -116.867020,36.460950 + + + + RPT011 + + + Longitude: -116.866830 + Latitude: 36.460910 + + ]]> + + -116.866830 + 36.460910 + 66 + + #route + + -116.866830,36.460910 + + + + RPT012 + + + Longitude: -116.866460 + Latitude: 36.460860 + + ]]> + + -116.866460 + 36.460860 + 66 + + #route + + -116.866460,36.460860 + + + + RPT013 + + + Longitude: -116.865720 + Latitude: 36.460860 + + ]]> + + -116.865720 + 36.460860 + 66 + + #route + + -116.865720,36.460860 + + + + + Path + #lineStyle + + 1 + + -116.879080,36.463670 + -116.878300,36.463860 + -116.878140,36.463880 + -116.877910,36.463840 + -116.876800,36.463450 + -116.872870,36.462240 + -116.868650,36.460990 + -116.868250,36.461010 + -116.867660,36.461210 + -116.867020,36.460950 + -116.866830,36.460910 + -116.866460,36.460860 + -116.865720,36.460860 + + + + + + + diff --git a/gpsbabel/reference/earth-expertgps-track.kml b/gpsbabel/reference/earth-expertgps-track.kml index 597948f08..b80b4ac5a 100644 --- a/gpsbabel/reference/earth-expertgps-track.kml +++ b/gpsbabel/reference/earth-expertgps-track.kml @@ -3,6 +3,15 @@ xmlns:gx="http://www.google.com/kml/ext/2.2"> GPS device + + + 2001-06-02T00:18:13Z + 2002-05-25T19:05:57Z + + -81.356770 + 36.257086 + 2979727.763965 + - - + + @@ -991,7 +1000,7 @@ - + Distance 4.8 mi @@ -1011,7 +1020,7 @@ Points -0 - + Longitude: -91.610350 @@ -1035,7 +1044,7 @@ -1 - + Longitude: -91.610567 @@ -1058,7 +1067,7 @@ -2 - + Longitude: -91.608267 @@ -1081,7 +1090,7 @@ -3 - + Longitude: -91.607383 @@ -1104,7 +1113,7 @@ -4 - + Longitude: -91.605283 @@ -1127,7 +1136,7 @@ -5 - + Longitude: -91.599400 @@ -1150,7 +1159,7 @@ -6 - + Longitude: -91.596683 @@ -1173,7 +1182,7 @@ -7 - + Longitude: -91.594900 @@ -1196,7 +1205,7 @@ -8 - + Longitude: -91.592617 @@ -1219,7 +1228,7 @@ -9 - + Longitude: -91.589750 @@ -1242,7 +1251,7 @@ -10 - + Longitude: -91.589883 @@ -1265,7 +1274,7 @@ -11 - + Longitude: -91.592933 @@ -1288,7 +1297,7 @@ -12 - + Longitude: -91.596450 @@ -1311,7 +1320,7 @@ -13 - + Longitude: -91.598717 @@ -1334,7 +1343,7 @@ -14 - + Longitude: -91.600267 @@ -1357,7 +1366,7 @@ -15 - + Longitude: -91.599633 @@ -1381,7 +1390,7 @@ -16 - + Longitude: -91.599467 @@ -1404,7 +1413,7 @@ -17 - + Longitude: -91.598950 @@ -1428,7 +1437,7 @@ -18 - + Longitude: -91.597733 @@ -1451,7 +1460,7 @@ -19 - + Longitude: -91.597167 @@ -1474,7 +1483,7 @@ -20 - + Longitude: -91.596333 @@ -1497,7 +1506,7 @@ -21 - + Longitude: -91.595200 @@ -1520,7 +1529,7 @@ -22 - + Longitude: -91.594767 @@ -1544,7 +1553,7 @@ -23 - + Longitude: -91.594083 @@ -1568,7 +1577,7 @@ -24 - + Longitude: -91.593800 @@ -1592,7 +1601,7 @@ -25 - + Longitude: -91.593850 @@ -1615,7 +1624,7 @@ -26 - + Longitude: -91.593983 @@ -1639,7 +1648,7 @@ -27 - + Longitude: -91.594117 @@ -1662,7 +1671,7 @@ -28 - + Longitude: -91.594367 @@ -1685,7 +1694,7 @@ -29 - + Longitude: -91.594367 @@ -1708,7 +1717,7 @@ -30 - + Longitude: -91.594667 @@ -1731,7 +1740,7 @@ -31 - + Longitude: -91.594683 @@ -1754,7 +1763,7 @@ -32 - + Longitude: -91.595200 @@ -1778,7 +1787,7 @@ -33 - + Longitude: -91.594933 @@ -1802,7 +1811,7 @@ -34 - + Longitude: -91.594783 @@ -1825,7 +1834,7 @@ -35 - + Longitude: -91.594833 @@ -1848,7 +1857,7 @@ -36 - + Longitude: -91.595433 @@ -1871,7 +1880,7 @@ -37 - + Longitude: -91.595967 @@ -1894,7 +1903,7 @@ -38 - + Longitude: -91.596783 @@ -1918,7 +1927,7 @@ -39 - + Longitude: -91.597850 @@ -1941,7 +1950,7 @@ -40 - + Longitude: -91.597967 @@ -1964,7 +1973,7 @@ -41 - + Longitude: -91.597767 @@ -1988,7 +1997,7 @@ -42 - + Longitude: -91.598083 @@ -2011,7 +2020,7 @@ -43 - + Longitude: -91.597917 @@ -2034,7 +2043,7 @@ -44 - + Longitude: -91.597517 @@ -2057,7 +2066,7 @@ -45 - + Longitude: -91.596933 @@ -2080,7 +2089,7 @@ -46 - + Longitude: -91.596433 @@ -2103,7 +2112,7 @@ -47 - + Longitude: -91.595683 @@ -2126,7 +2135,7 @@ -48 - + Longitude: -91.595017 @@ -2149,7 +2158,7 @@ -49 - + Longitude: -91.594700 @@ -2172,7 +2181,7 @@ -50 - + Longitude: -91.594400 @@ -2195,7 +2204,7 @@ -51 - + Longitude: -91.594233 @@ -2218,7 +2227,7 @@ -52 - + Longitude: -91.594100 @@ -2241,7 +2250,7 @@ -53 - + Longitude: -91.593717 @@ -2264,7 +2273,7 @@ -54 - + Longitude: -91.594250 @@ -2287,7 +2296,7 @@ -55 - + Longitude: -91.594750 @@ -2310,7 +2319,7 @@ -56 - + Longitude: -91.595450 @@ -2334,7 +2343,7 @@ -57 - + Longitude: -91.596000 @@ -2357,7 +2366,7 @@ -58 - + Longitude: -91.596600 @@ -2380,7 +2389,7 @@ -59 - + Longitude: -91.597650 @@ -2403,7 +2412,7 @@ -60 - + Longitude: -91.598467 @@ -2426,7 +2435,7 @@ -61 - + Longitude: -91.598967 @@ -2449,7 +2458,7 @@ -62 - + Longitude: -91.599283 @@ -2472,7 +2481,7 @@ -63 - + Longitude: -91.599667 @@ -2501,132 +2510,68 @@ 1 -91.610350,30.062183,1.00 - -91.610350,30.062183,1.000000 - -91.610567,30.062783 -91.610567,30.062783 -91.608267,30.062700 - -91.608267,30.062700 - -91.607383,30.062333 -91.607383,30.062333 -91.605283,30.061533 - -91.605283,30.061533 -91.599400,30.059783 - -91.599400,30.059783 - -91.596683,30.057800 -91.596683,30.057800 -91.594900,30.055383 - -91.594900,30.055383 -91.592617,30.053883 - -91.592617,30.053883 - -91.589750,30.049733 -91.589750,30.049733 -91.589883,30.049017 - -91.589883,30.049017 -91.592933,30.048800 - -91.592933,30.048800 - -91.596450,30.046233 -91.596450,30.046233 -91.598717,30.045517 - -91.598717,30.045517 - -91.600267,30.047300 -91.600267,30.047300 -91.599633,30.047000,2.00 - -91.599633,30.047000,2.000000 - -91.599467,30.046433 -91.599467,30.046433 -91.598950,30.046200,1.00 - -91.598950,30.046200,1.000000 -91.597733,30.046367 - -91.597733,30.046367 - -91.597167,30.046350 -91.597167,30.046350 -91.596333,30.046783 - -91.596333,30.046783 - -91.595200,30.047450 -91.595200,30.047450 -91.594767,30.047800,2.00 - -91.594767,30.047800,2.000000 -91.594083,30.048250,1.00 - -91.594083,30.048250,1.000000 -91.593800,30.048683,1.00 - -91.593800,30.048683,1.000000 - -91.593850,30.049350 -91.593850,30.049350 -91.593983,30.050317,2.00 - -91.593983,30.050317,2.000000 - -91.594117,30.050783 -91.594117,30.050783 -91.594367,30.051233 - -91.594367,30.051233 - -91.594367,30.051800 -91.594367,30.051800 -91.594667,30.052217 - -91.594667,30.052217 - -91.594683,30.053017 -91.594683,30.053017 -91.595200,30.054867,6.00 - -91.595200,30.054867,6.000000 -91.594933,30.053733,2.00 - -91.594933,30.053733,2.000000 - -91.594783,30.053183 -91.594783,30.053183 -91.594833,30.052633 - -91.594833,30.052633 -91.595433,30.052450 - -91.595433,30.052450 - -91.595967,30.052483 -91.595967,30.052483 -91.596783,30.052650,1.00 - -91.596783,30.052650,1.000000 - -91.597850,30.053133 -91.597850,30.053133 -91.597967,30.053617 - -91.597967,30.053617 -91.597767,30.053967,6.00 - -91.597767,30.053967,6.000000 - -91.598083,30.053617 -91.598083,30.053617 -91.597917,30.053200 - -91.597917,30.053200 -91.597517,30.052817 - -91.597517,30.052817 - -91.596933,30.052567 -91.596933,30.052567 -91.596433,30.052333 - -91.596433,30.052333 -91.595683,30.052250 - -91.595683,30.052250 - -91.595017,30.052217 -91.595017,30.052217 -91.594700,30.051883 - -91.594700,30.051883 - -91.594400,30.051050 -91.594400,30.051050 -91.594233,30.050567 - -91.594233,30.050567 -91.594100,30.050183 - -91.594100,30.050183 - -91.593717,30.049100 -91.593717,30.049100 -91.594250,30.048450 - -91.594250,30.048450 - -91.594750,30.048083 -91.594750,30.048083 -91.595450,30.047500,7.00 - -91.595450,30.047500,7.000000 - -91.596000,30.047067 -91.596000,30.047067 -91.596600,30.046633 - -91.596600,30.046633 -91.597650,30.046400 - -91.597650,30.046400 - -91.598467,30.046233 -91.598467,30.046233 -91.598967,30.046317 - -91.598967,30.046317 -91.599283,30.046783 - -91.599283,30.046783 - -91.599667,30.047133 -91.599667,30.047133 @@ -2641,7 +2586,7 @@ Points BELLEVUE - + Longitude: -71.107628 @@ -2663,7 +2608,7 @@ GATE6 - + Longitude: -71.109236 @@ -2685,7 +2630,7 @@ PANTHRCAVE - + Longitude: -71.109942 @@ -2707,7 +2652,7 @@ 6014MEADOW - + Longitude: -71.113223 @@ -2729,7 +2674,7 @@ 6006 - + Longitude: -71.114456 @@ -2751,7 +2696,7 @@ 6006BLUE - + Longitude: -71.114803 @@ -2773,7 +2718,7 @@ 5096 - + Longitude: -71.116146 @@ -2795,7 +2740,7 @@ 5066 - + Longitude: -71.119277 @@ -2817,7 +2762,7 @@ 5067 - + Longitude: -71.119689 @@ -2839,7 +2784,7 @@ 5058ROAD - + Longitude: -71.120925 @@ -2861,7 +2806,7 @@ 5150TANK - + Longitude: -71.121676 @@ -2883,7 +2828,7 @@ 5142 - + Longitude: -71.122044 @@ -2905,7 +2850,7 @@ 5144SUMMIT - + Longitude: -71.122845 @@ -2927,7 +2872,7 @@ 5156 - + Longitude: -71.121447 @@ -2949,7 +2894,7 @@ 5148NANEPA - + Longitude: -71.122320 @@ -2971,7 +2916,7 @@ 5258 - + Longitude: -71.121746 @@ -2993,7 +2938,7 @@ 5252PURPLE - + Longitude: -71.121211 @@ -3015,7 +2960,7 @@ 527631 - + Longitude: -71.119356 @@ -3037,7 +2982,7 @@ 527614 - + Longitude: -71.119676 @@ -3059,7 +3004,7 @@ 5267OBSTAC - + Longitude: -71.119845 @@ -3081,7 +3026,7 @@ 5278 - + Longitude: -71.119135 @@ -3103,7 +3048,7 @@ 5289 - + Longitude: -71.117693 @@ -3125,7 +3070,7 @@ 5374FIRE - + Longitude: -71.119828 @@ -3147,7 +3092,7 @@ 5376 - + Longitude: -71.119399 @@ -3169,7 +3114,7 @@ 5376STREAM - + Longitude: -71.119328 @@ -3191,7 +3136,7 @@ 6328 - + Longitude: -71.113574 @@ -3213,7 +3158,7 @@ 635722 - + Longitude: -71.110067 @@ -3235,7 +3180,7 @@ 635783 - + Longitude: -71.109410 @@ -3257,7 +3202,7 @@ 6373 - + Longitude: -71.107117 @@ -3279,7 +3224,7 @@ BEAR HILL - + Longitude: -71.107360 @@ -3301,7 +3246,7 @@ 6289 - + Longitude: -71.106170 @@ -3323,7 +3268,7 @@ 6297 - + Longitude: -71.105116 @@ -3345,7 +3290,7 @@ 6283 - + Longitude: -71.105206 @@ -3367,7 +3312,7 @@ 6280 - + Longitude: -71.105413 @@ -3389,7 +3334,7 @@ 6177 - + Longitude: -71.106158 @@ -3411,7 +3356,7 @@ 6176 - + Longitude: -71.106624 @@ -3433,7 +3378,7 @@ 6153 - + Longitude: -71.108882 @@ -3455,7 +3400,7 @@ 6171 - + Longitude: -71.106301 @@ -3477,7 +3422,7 @@ 6131 - + Longitude: -71.111441 @@ -3499,7 +3444,7 @@ 6130 - + Longitude: -71.110975 @@ -3521,7 +3466,7 @@ 6029 - + Longitude: -71.113220 @@ -3543,7 +3488,7 @@ 6006 - + Longitude: -71.114456 @@ -3565,7 +3510,7 @@ 6014MEADOW - + Longitude: -71.113223 @@ -3587,7 +3532,7 @@ PANTHRCAVE - + Longitude: -71.109942 @@ -3609,7 +3554,7 @@ GATE6 - + Longitude: -71.109236 @@ -3631,7 +3576,7 @@ BELLEVUE - + Longitude: -71.107628 @@ -3659,110 +3604,55 @@ 1 -71.107628,42.430950,23.47 - -71.107628,42.430950,23.469600 -71.109236,42.431240,26.56 - -71.109236,42.431240,26.561890 -71.109942,42.434980,45.31 - -71.109942,42.434980,45.307495 -71.113223,42.436757,37.62 - -71.113223,42.436757,37.616943 -71.114456,42.439018,56.39 - -71.114456,42.439018,56.388000 -71.114803,42.438594,46.03 - -71.114803,42.438594,46.028564 -71.116146,42.438917,44.83 - -71.116146,42.438917,44.826904 -71.119277,42.438878,44.59 - -71.119277,42.438878,44.586548 -71.119689,42.439227,57.61 - -71.119689,42.439227,57.607200 -71.120925,42.439993,53.95 - -71.120925,42.439993,53.949600 -71.121676,42.441727,67.36 - -71.121676,42.441727,67.360800 -71.122044,42.443904,50.59 - -71.122044,42.443904,50.594727 -71.122845,42.445359,61.65 - -71.122845,42.445359,61.649902 -71.121447,42.447298,127.71 - -71.121447,42.447298,127.711200 -71.122320,42.449765,119.81 - -71.122320,42.449765,119.809082 -71.121746,42.451442,74.63 - -71.121746,42.451442,74.627442 -71.121211,42.453256,77.99 - -71.121211,42.453256,77.992066 -71.119356,42.456252,78.71 - -71.119356,42.456252,78.713135 -71.119676,42.456592,78.71 - -71.119676,42.456592,78.713135 -71.119845,42.457388,73.76 - -71.119845,42.457388,73.761600 -71.119135,42.458148,68.28 - -71.119135,42.458148,68.275200 -71.117693,42.459377,64.01 - -71.117693,42.459377,64.008000 -71.119828,42.464183,53.00 - -71.119828,42.464183,52.997925 -71.119399,42.465650,56.39 - -71.119399,42.465650,56.388000 -71.119328,42.465913,64.53 - -71.119328,42.465913,64.533692 -71.113574,42.467110,53.64 - -71.113574,42.467110,53.644800 -71.110067,42.466459,48.77 - -71.110067,42.466459,48.768000 -71.109410,42.466557,49.07 - -71.109410,42.466557,49.072800 -71.107117,42.463495,62.48 - -71.107117,42.463495,62.484000 -71.107360,42.465687,87.78 - -71.107360,42.465687,87.782400 -71.106170,42.459986,72.95 - -71.106170,42.459986,72.945191 -71.105116,42.457616,72.85 - -71.105116,42.457616,72.847200 -71.105206,42.453845,66.70 - -71.105206,42.453845,66.696655 -71.105413,42.451430,57.56 - -71.105413,42.451430,57.564209 -71.106158,42.448448,62.18 - -71.106158,42.448448,62.179200 -71.106624,42.447804,62.48 - -71.106624,42.447804,62.484000 -71.108882,42.444773,62.79 - -71.108882,42.444773,62.788800 -71.106301,42.443592,55.47 - -71.106301,42.443592,55.473600 -71.111441,42.442981,64.01 - -71.111441,42.442981,64.008000 -71.110975,42.442196,64.01 - -71.110975,42.442196,64.008000 -71.113220,42.441754,56.39 - -71.113220,42.441754,56.388000 -71.114456,42.439018,56.39 - -71.114456,42.439018,56.388000 -71.113223,42.436757,37.62 - -71.113223,42.436757,37.616943 -71.109942,42.434980,45.31 - -71.109942,42.434980,45.307495 -71.109236,42.431240,26.56 - -71.109236,42.431240,26.561890 -71.107628,42.430950,23.47 - -71.107628,42.430950,23.469600 - - - 2001-06-02T00:18:13Z - 2002-05-25T19:05:57Z - - -81.356770 - 36.257086 - 2979727.763965 - diff --git a/gpsbabel/reference/earth-expertgps.kml b/gpsbabel/reference/earth-expertgps.kml index 789678233..9b2a85d4c 100644 --- a/gpsbabel/reference/earth-expertgps.kml +++ b/gpsbabel/reference/earth-expertgps.kml @@ -3,6 +3,15 @@ xmlns:gx="http://www.google.com/kml/ext/2.2"> GPS device + + + 2001-06-02T00:18:13Z + 2002-05-25T19:05:57Z + + -81.356770 + 36.257086 + 2979727.763965 + + + + + + normal + #geocache_n + + + highlight + #geocache_h + + Waypoints @@ -62,11 +241,15 @@ Points géodésiques du Québec Sverdrup2 6293 + 15-Aug-2002 stars1 stars1 virtual - + + 46.133333 + -73.000000 Locationless (Reverse) Cache + http://www.geocaching.com/images/kml/8.png + Found it by Christopher R & Pooh B 2005-07-12
This marker is not in Quebec but it is a Geodesic marker in Clarenville, Newfoundland, Canada! + +Found this one while hunting a traditional cache and thought of this cache right away! + +It is located on Bare Mountain in Clarenville - There are aactually two markers within 15 feet of one another on Bare Mountain... + +Smiles Pooh Bear + +Ce marqueur n'est pas au Québec mais c'est un marqueur géodésique dans Clarenville, Terre-Neuve, Canada! + +A trouvé celui-ci tandis que chasse une cachette traditionnelle et pensé à cette cachette tout de suite! Elle est située sur la montagne nue dans Clarenville - il y a aactually deux marqueurs à moins de 15 pieds d'un des autres sur la montagne nue... Ours De Pooh De Sourires + + +

Found it by TravelBen 2005-06-26
[:D] 14h22 + +Marqueur du Service de la Géodégie (c'est bien un "g" pas un "s") du Québec. + +Position Average (100 échantillons): +N 45° 26.872 W 075° 56.410, 21 mètres d'altitude +UTM: 18T E 582877 N 5033250 + +Ce marqueur se trouve dans le ville de Senneville, sur un monument décrivant une page d'histoire du Québec, sur le bas côté avant droit. + +Près de la cache: Exo-07 La Jumelle de Loudiver (GCP3VE)

Found it by etasse 2005-06-03
MRN marker 94K4731 in Gatineau, QC. corner of Du Rhone and Gatineau Ave. + +Position Average +N 45° 29.5247 W 075° 43.0049 59.49m +UTM 18T 0443995 5037866 + +Least Squares Average +N 45° 29.5257 W 075° 43.0043 55.74m +UTM 18T 0443996 5037868 + +This pole has everything: An underground cable warning, a geodesic mark, a bus stop and a garage sale sign. + +Judging by the coordinates it looks like the coords should be 45°29'31.5" -75°43'0" I placed the GPS antenna right against the marker, to no avail. + +

Found it by Katou 2005-06-03
Un bo point géodésique a Lotbinière..en allant faire une nouvelle cache a l'île richelieu ;-) + +

Found it by Gps_Gulliver&DauphinBleu 2005-05-29
Point Geodesique situe near Port de Plaisance de Longueuil +sur le bord du fleuve st-laurent. +Il y a des sentiers et une grande piste cyclable +Enjoy !

]]>
-73.000000,46.133333 @@ -127,11 +353,15 @@ Good luck!]]> Oozy rat in a sanitary zoo robertlipe 32733 + 29-Jun-2003 stars3 stars2 not_chosen - + + 35.921667 + -86.861667 Unknown Cache + http://www.geocaching.com/images/kml/8.png Now that it's intuitively obvious to even the most casual observer where the cache is, turn on your geo-mojo and go find it.
Member of Middle Tennessee GeoCachers Club [www.mtgc.org]

]]> + Found it by littlepod 2005-07-03
Enjoyed the puzzle. We seemed to be about 50ft off though. TFTC.

Write note by robertlipe 2005-04-29
TB Drop to show he's hanging out in Nashville until we blast off for Geowoodstock in a few weeks.

Found it by Big Bumblebee 2005-04-18
Found it a while ago. Thanks.

Write note by robertlipe 2005-03-27
I had to renew my permit with the CDC and in doing so, I trolled out here verified that the infectious ooze is fully within specification and industry accepted tolerance. Ooze On!

Found it by Virtual Babe 2004-12-27
This was a great cache, however on this day I considered it a FIFM cache (Fun, Invigorating, Frustrating and Maddening), especially when the cache was not replaced in the proper spot by the previous cacher! Thanks anyway!! +

Write note by robertlipe 2004-01-12
I got a complaint from the CDC about oozy rat this weekend. I went out tonight in the dark and verified that the infectious ooze is fully within specification and industry accepted tolerance. (Although I realize now I did misstate the cache container to the reporting officer when confronted. It's, uuuuh, smaller than I said.)

Write note by robertlipe 2003-10-04
In the expectation that this cache will get some traffic in the next 48 hours, Ryan and I checked it earlier today. The Rat is Oozing just as we planned it.

Write note by robertlipe 2003-07-03
It won't earn him a smiley face, but I've confirmed that rickrich would have indeed sunk the battleship! Thanx for playing. You get a copy of the home game and some rice-a-roni...

]]>
-86.861667,35.921667 - - - 2002-08-15T07:00:00Z - 2003-06-29T07:00:00Z - - -79.930833 - 41.027500 - 2109328.437865 - diff --git a/gpsbabel/reference/navicache.ref b/gpsbabel/reference/navicache.ref index b74e217a4..21b5b40b8 100644 --- a/gpsbabel/reference/navicache.ref +++ b/gpsbabel/reference/navicache.ref @@ -1,2 +1,2 @@ -2343 3334.415N 11146.587W 0000000m Eagle's Nest a -2342 3431.053N 11146.178W 0000000m Clear Creek Cache a +N00927 3334.415N 11146.587W 0000000m Eagle's Nest a +N00926 3431.053N 11146.178W 0000000m Clear Creek Cache a diff --git a/gpsbabel/reference/pocketfms_wp.txt b/gpsbabel/reference/pocketfms_wp.txt old mode 100755 new mode 100644 diff --git a/gpsbabel/reference/psitwpts.txt b/gpsbabel/reference/psitwpts.txt old mode 100755 new mode 100644 diff --git a/gpsbabel/reference/route/bend-expected.gpx b/gpsbabel/reference/route/bend-expected.gpx new file mode 100644 index 000000000..f8e7f9075 --- /dev/null +++ b/gpsbabel/reference/route/bend-expected.gpx @@ -0,0 +1,1770 @@ + + + + + + santander + Generated from track santander + + 34.733154 + RPT001 + + + 34.252441 + RPT002 + + + 34.252441 + RPT002 + + + 31.368530 + RPT003 + + + 31.368530 + RPT003 + + + 28.965332 + RPT004 + + + 24.158569 + RPT005 + + + 24.158569 + RPT005 + + + 22.235962 + RPT006 + + + 22.235962 + RPT006 + + + 29.926514 + RPT007 + + + 29.926514 + RPT007 + + + 37.616943 + RPT008 + + + 37.616943 + RPT008 + + + 56.843140 + RPT009 + + + 56.843140 + RPT009 + + + 52.997925 + RPT010 + + + 52.997925 + RPT010 + + + 52.997925 + RPT011 + + + 52.997925 + RPT011 + + + 43.384766 + RPT012 + + + 43.384766 + RPT012 + + + 29.926514 + RPT013 + + + 29.926514 + RPT013 + + + 20.794067 + RPT014 + + + 20.794067 + RPT014 + + + 19.832764 + RPT015 + + + 19.832764 + RPT015 + + + 15.506958 + RPT016 + + + 15.506958 + RPT016 + + + 15.026245 + RPT017 + + + 15.026245 + RPT017 + + + 11.661621 + RPT018 + + + 11.661621 + RPT018 + + + 11.180908 + RPT019 + + + 11.180908 + RPT019 + + + 11.661621 + RPT020 + + + 11.661621 + RPT020 + + + 7.816406 + RPT021 + + + 7.816406 + RPT021 + + + 14.545532 + RPT022 + + + 14.545532 + RPT022 + + + 17.429565 + RPT023 + + + 17.429565 + RPT023 + + + 16.468140 + RPT024 + + + 16.468140 + RPT024 + + + 19.352173 + RPT025 + + + 19.352173 + RPT025 + + + 17.910156 + RPT026 + + + 17.910156 + RPT026 + + + 26.081177 + RPT027 + + + 26.081177 + RPT027 + + + 27.523193 + RPT028 + + + 27.523193 + RPT028 + + + 28.965332 + RPT029 + + + 28.965332 + RPT029 + + + 36.175049 + RPT030 + + + 36.175049 + RPT030 + + + 40.500977 + RPT031 + + + 40.500977 + RPT031 + + + 51.075317 + RPT032 + + + 51.075317 + RPT032 + + + 49.152710 + RPT033 + + + 49.152710 + RPT033 + + + 52.036743 + RPT034 + + + 52.036743 + RPT034 + + + 56.843140 + RPT035 + + + 56.843140 + RPT035 + + + 59.246460 + RPT036 + + + 59.246460 + RPT036 + + + 58.765747 + RPT037 + + + 58.765747 + RPT037 + + + 62.611084 + RPT038 + + + 62.611084 + RPT038 + + + 65.014404 + RPT039 + + + 65.014404 + RPT039 + + + 65.014404 + RPT040 + + + 65.014404 + RPT040 + + + 67.417725 + RPT041 + + + 67.417725 + RPT041 + + + 62.130493 + RPT042 + + + 62.130493 + RPT042 + + + 64.533691 + RPT043 + + + 64.533691 + RPT043 + + + 66.456299 + RPT044 + + + 66.456299 + RPT044 + + + 53.478638 + RPT045 + + + 53.478638 + RPT045 + + + 46.749512 + RPT046 + + + 46.749512 + RPT046 + + + 56.843140 + RPT047 + + + 56.843140 + RPT047 + + + 58.765747 + RPT048 + + + 62.611084 + RPT049 + + + 62.611084 + RPT049 + + + 60.688477 + RPT050 + + + 29.926514 + RPT051 + + + 29.926514 + RPT051 + + + 29.445923 + RPT052 + + + 29.445923 + RPT052 + + + 12.622925 + RPT053 + + + 12.622925 + RPT053 + + + 35.213745 + RPT054 + + + 35.213745 + RPT054 + + + 26.081177 + RPT055 + + + 35.694336 + RPT056 + + + 36.655762 + RPT057 + + + 36.655762 + RPT057 + + + 38.578369 + RPT058 + + + 38.578369 + RPT058 + + + 32.810547 + RPT059 + + + 32.810547 + RPT059 + + + 32.810547 + RPT060 + + + 32.810547 + RPT060 + + + 31.368530 + RPT061 + + + 31.368530 + RPT061 + + + 29.926514 + RPT062 + + + 29.926514 + RPT062 + + + 25.119995 + RPT063 + + + 25.119995 + RPT063 + + + 9.258301 + RPT064 + + + 9.258301 + RPT064 + + + 6.374390 + RPT065 + + + 6.374390 + RPT065 + + + 5.413086 + RPT066 + + + 5.413086 + RPT066 + + + 5.893799 + RPT067 + + + 5.893799 + RPT067 + + + 7.816406 + RPT068 + + + 7.816406 + RPT068 + + + 6.374390 + RPT069 + + + 6.374390 + RPT069 + + + 2.529175 + RPT070 + + + 2.529175 + RPT070 + + + 2.529175 + RPT071 + + + 2.529175 + RPT071 + + + 3.971191 + RPT072 + + + 3.971191 + RPT072 + + + 1.567871 + RPT073 + + + 1.567871 + RPT073 + + + 0.125977 + RPT074 + + + 0.125977 + RPT074 + + + 2.048584 + RPT075 + + + 2.048584 + RPT075 + + + 0.125977 + RPT076 + + + 0.125977 + RPT076 + + + 2.048584 + RPT077 + + + 2.048584 + RPT077 + + + 3.490479 + RPT078 + + + 3.971191 + RPT079 + + + 3.971191 + RPT079 + + + 4.932373 + RPT080 + + + 2.048584 + RPT081 + + + 2.048584 + RPT081 + + + 0.606567 + RPT082 + + + 0.606567 + RPT082 + + + 2.529175 + RPT083 + + + 1.567871 + RPT084 + + + 1.567871 + RPT084 + + + 2.529175 + RPT085 + + + 2.529175 + RPT085 + + + 3.971191 + RPT086 + + + 5.413086 + RPT087 + + + 5.413086 + RPT087 + + + 1.087158 + RPT088 + + + 1.087158 + RPT088 + + + 3.971191 + RPT089 + + + 12.142334 + RPT090 + + + 12.142334 + RPT090 + + + 8.296997 + RPT091 + + + 8.296997 + RPT091 + + + -0.835449 + RPT092 + + + -0.835449 + RPT092 + + + 5.413086 + RPT093 + + + 5.413086 + RPT093 + + + 25.119995 + RPT094 + + + 25.119995 + RPT094 + + + 25.119995 + RPT095 + + + 25.119995 + RPT095 + + + 23.197388 + RPT096 + + + 26.561890 + RPT097 + + + 26.561890 + RPT097 + + + 26.081177 + RPT098 + + + 26.081177 + RPT098 + + + 26.561890 + RPT099 + + + 26.561890 + RPT099 + + + 26.081177 + RPT100 + + + 26.081177 + RPT100 + + + 30.887940 + RPT101 + + + 30.887940 + RPT101 + + + 25.600586 + RPT102 + + + 25.600586 + RPT102 + + + 20.794067 + RPT103 + + + 20.794067 + RPT103 + + + 17.429565 + RPT104 + + + 17.429565 + RPT104 + + + 6.374390 + RPT105 + + + 6.374390 + RPT105 + + + 4.932373 + RPT106 + + + 4.932373 + RPT106 + + + 2.529175 + RPT107 + + + 2.529175 + RPT107 + + + 15.506958 + RPT108 + + + 15.506958 + RPT108 + + + 19.832764 + RPT109 + + + 19.832764 + RPT109 + + + 20.313354 + RPT110 + + + 11.180908 + RPT111 + + + 11.180908 + RPT111 + + + 2.048584 + RPT112 + + + 2.048584 + RPT112 + + + 6.374390 + RPT113 + + + 6.374390 + RPT113 + + + 7.335693 + RPT114 + + + 7.335693 + RPT114 + + + 11.661621 + RPT115 + + + 11.661621 + RPT115 + + + 12.142334 + RPT116 + + + 12.142334 + RPT116 + + + 15.026245 + RPT117 + + + 15.026245 + RPT117 + + + 13.584351 + RPT118 + + + 13.584351 + RPT118 + + + 10.219605 + RPT119 + + + 10.219605 + RPT119 + + + 9.258301 + RPT120 + + + 14.064941 + RPT121 + + + 14.064941 + RPT121 + + + 11.661621 + RPT122 + + + 11.661621 + RPT122 + + + 6.854980 + RPT123 + + + 6.854980 + RPT123 + + + 4.932373 + RPT124 + + + 3.971191 + RPT125 + + + 3.971191 + RPT125 + + + 5.893799 + RPT126 + + + 5.893799 + RPT126 + + + 5.413086 + RPT127 + + + 5.413086 + RPT127 + + + 22.716675 + RPT128 + + + 22.716675 + RPT128 + + + 38.578369 + RPT129 + + + 38.578369 + RPT129 + + + 58.765747 + RPT130 + + + 58.765747 + RPT130 + + + 66.456299 + RPT131 + + + 66.456299 + RPT131 + + + 62.611084 + RPT132 + + + 62.611084 + RPT132 + + + 64.053101 + RPT133 + + + 64.053101 + RPT133 + + + 65.975708 + RPT134 + + + 65.975708 + RPT134 + + + 66.456299 + RPT135 + + + 66.456299 + RPT135 + + + 61.169190 + RPT136 + + + 61.169190 + RPT136 + + + 62.611084 + RPT137 + + + 62.611084 + RPT137 + + + 61.649902 + RPT138 + + + 61.649902 + RPT138 + + + 46.268921 + RPT139 + + + 46.268921 + RPT139 + + + 36.175049 + RPT140 + + + 36.175049 + RPT140 + + + 18.390747 + RPT141 + + + 18.390747 + RPT141 + + + 10.219605 + RPT142 + + + 18.390747 + RPT143 + + + 18.390747 + RPT143 + + + 37.136353 + RPT144 + + + 37.136353 + RPT144 + + + 31.368530 + RPT145 + + + 31.368530 + RPT145 + + + 4.932373 + RPT146 + + + 13.584351 + RPT147 + + + 13.584351 + RPT147 + + + 24.639282 + RPT148 + + + 24.639282 + RPT148 + + + 27.523193 + RPT149 + + + 27.523193 + RPT149 + + + 22.716675 + RPT150 + + + 22.716675 + RPT150 + + + 45.307495 + RPT151 + + + 45.307495 + RPT151 + + + 26.561890 + RPT152 + + + 26.561890 + RPT152 + + + 34.733154 + RPT153 + + + 34.733154 + RPT153 + + + 26.561890 + RPT154 + + + 26.561890 + RPT154 + + + 34.252441 + RPT155 + + + 34.252441 + RPT155 + + + 28.965332 + RPT156 + + + 28.965332 + RPT156 + + + 24.158569 + RPT157 + + + 24.158569 + RPT157 + + + 23.197388 + RPT158 + + + 23.197388 + RPT158 + + + 21.755371 + RPT159 + + + 21.755371 + RPT160 + + + 23.197388 + RPT161 + + + 23.197388 + RPT161 + + + 9.739014 + RPT162 + + + 9.739014 + RPT162 + + + 11.180908 + RPT163 + + + 11.180908 + RPT163 + + + 12.622925 + RPT164 + + + 12.622925 + RPT164 + + + 22.235962 + RPT165 + + + 22.235962 + RPT165 + + + 38.097656 + RPT166 + + + 38.097656 + RPT166 + + + 24.639282 + RPT167 + + + 24.639282 + RPT167 + + + 16.948853 + RPT168 + + + 16.948853 + RPT168 + + + 19.832764 + RPT169 + + + 19.832764 + RPT169 + + + 3.009766 + RPT170 + + + 18.871460 + RPT171 + + + 18.871460 + RPT171 + + + 15.506958 + RPT172 + + + 15.506958 + RPT172 + + + 23.677978 + RPT173 + + + 23.677978 + RPT173 + + + 36.655762 + RPT174 + + + 36.655762 + RPT174 + + + 39.539551 + RPT175 + + + 40.500977 + RPT176 + + + 40.500977 + RPT176 + + + 46.268921 + RPT177 + + + 46.268921 + RPT177 + + + 55.709473 + RPT178 + + + 55.709473 + RPT178 + + + 70.709473 + RPT179 + + + 70.709473 + RPT179 + + + 75.709473 + RPT180 + + + 90.267456 + RPT181 + + + 90.267456 + RPT181 + + + 95.963867 + RPT182 + + + 95.963867 + RPT182 + + + 100.102295 + RPT183 + + + 100.102295 + RPT183 + + + 93.373047 + RPT184 + + + 93.373047 + RPT184 + + + 90.969727 + RPT185 + + + 90.969727 + RPT185 + + + 88.085815 + RPT186 + + + 88.085815 + RPT186 + + + 87.605103 + RPT187 + + + 87.605103 + RPT187 + + + 102.986084 + RPT188 + + + 102.986084 + RPT188 + + + 126.057617 + RPT189 + + + 126.057617 + RPT189 + + + 144.803223 + RPT190 + + + 144.803223 + RPT190 + + + 180.371704 + RPT191 + + + 180.371704 + RPT191 + + + 191.426758 + RPT192 + + + 191.426758 + RPT192 + + + 197.194580 + RPT193 + + + 210.652954 + RPT194 + + + 210.652954 + RPT194 + + + 231.801758 + RPT195 + + + 208.730347 + RPT196 + + + 208.730347 + RPT196 + + + 195.271973 + RPT197 + + + 195.271973 + RPT197 + + + 187.100830 + RPT198 + + + 187.100830 + RPT198 + + + 155.377564 + RPT199 + + + 155.377564 + RPT199 + + + 148.167847 + RPT200 + + + 148.167847 + RPT200 + + + 183.736206 + RPT201 + + + 183.736206 + RPT201 + + + 200.078613 + RPT202 + + + 200.078613 + RPT202 + + + 208.730347 + RPT203 + + + 208.730347 + RPT203 + + + 221.227539 + RPT204 + + + 221.227539 + RPT204 + + + 235.166382 + RPT205 + + + 235.166382 + RPT205 + + + 226.033936 + RPT206 + + + 226.033936 + RPT206 + + + 201.520508 + RPT207 + + + 201.520508 + RPT207 + + + 188.542969 + RPT208 + + + 188.542969 + RPT208 + + + 144.803223 + RPT209 + + + 144.803223 + RPT209 + + + 141.919311 + RPT210 + + + 141.919311 + RPT210 + + + 136.151367 + RPT211 + + + 136.151367 + RPT211 + + + 110.196045 + RPT212 + + + 110.196045 + RPT212 + + + 86.163208 + RPT213 + + + 86.163208 + RPT213 + + + 75.588745 + RPT214 + + + 75.588745 + RPT214 + + + 71.262940 + RPT215 + + + 71.262940 + RPT215 + + + 66.937012 + RPT216 + + + 66.937012 + RPT216 + + + 63.091797 + RPT217 + + + 63.091797 + RPT217 + + + 61.649902 + RPT218 + + + 61.649902 + RPT218 + + + 59.727173 + RPT219 + + + 59.727173 + RPT219 + + + 55.881958 + RPT220 + + + 55.881958 + RPT220 + + + 53.478638 + RPT221 + + + 53.478638 + RPT221 + + + 55.401245 + RPT222 + + + 55.401245 + RPT222 + + + 52.036743 + RPT223 + + + 52.036743 + RPT223 + + + 49.152710 + RPT224 + + + 49.152710 + RPT224 + + + 46.749512 + RPT225 + + + 46.749512 + RPT225 + + + 48.672119 + RPT226 + + + 48.672119 + RPT226 + + + 44.826904 + RPT227 + + + 44.826904 + RPT227 + + + 44.826904 + RPT228 + + + 44.826904 + RPT228 + + + 44.346314 + RPT229 + + + 44.346314 + RPT229 + + + 45.307495 + RPT230 + + + 45.307495 + RPT230 + + + 42.904175 + RPT231 + + + 42.904175 + RPT231 + + + 33.771729 + RPT232 + + + diff --git a/gpsbabel/reference/route/bend-input.gpx b/gpsbabel/reference/route/bend-input.gpx new file mode 100644 index 000000000..5512d6e8b --- /dev/null +++ b/gpsbabel/reference/route/bend-input.gpx @@ -0,0 +1,942 @@ + + + + + + santander + Generated from track santander + + 34.733154 + RPT001 + + + 34.252441 + RPT002 + + + 31.368530 + RPT003 + + + 28.965332 + RPT004 + + + 24.158569 + RPT005 + + + 22.235962 + RPT006 + + + 29.926514 + RPT007 + + + 37.616943 + RPT008 + + + 56.843140 + RPT009 + + + 52.997925 + RPT010 + + + 52.997925 + RPT011 + + + 43.384766 + RPT012 + + + 29.926514 + RPT013 + + + 20.794067 + RPT014 + + + 19.832764 + RPT015 + + + 15.506958 + RPT016 + + + 15.026245 + RPT017 + + + 11.661621 + RPT018 + + + 11.180908 + RPT019 + + + 11.661621 + RPT020 + + + 7.816406 + RPT021 + + + 14.545532 + RPT022 + + + 17.429565 + RPT023 + + + 16.468140 + RPT024 + + + 19.352173 + RPT025 + + + 17.910156 + RPT026 + + + 26.081177 + RPT027 + + + 27.523193 + RPT028 + + + 28.965332 + RPT029 + + + 36.175049 + RPT030 + + + 40.500977 + RPT031 + + + 51.075317 + RPT032 + + + 49.152710 + RPT033 + + + 52.036743 + RPT034 + + + 56.843140 + RPT035 + + + 59.246460 + RPT036 + + + 58.765747 + RPT037 + + + 62.611084 + RPT038 + + + 65.014404 + RPT039 + + + 65.014404 + RPT040 + + + 67.417725 + RPT041 + + + 62.130493 + RPT042 + + + 64.533691 + RPT043 + + + 66.456299 + RPT044 + + + 53.478638 + RPT045 + + + 46.749512 + RPT046 + + + 56.843140 + RPT047 + + + 58.765747 + RPT048 + + + 62.611084 + RPT049 + + + 60.688477 + RPT050 + + + 29.926514 + RPT051 + + + 29.445923 + RPT052 + + + 12.622925 + RPT053 + + + 35.213745 + RPT054 + + + 26.081177 + RPT055 + + + 35.694336 + RPT056 + + + 36.655762 + RPT057 + + + 38.578369 + RPT058 + + + 32.810547 + RPT059 + + + 32.810547 + RPT060 + + + 31.368530 + RPT061 + + + 29.926514 + RPT062 + + + 25.119995 + RPT063 + + + 9.258301 + RPT064 + + + 6.374390 + RPT065 + + + 5.413086 + RPT066 + + + 5.893799 + RPT067 + + + 7.816406 + RPT068 + + + 6.374390 + RPT069 + + + 2.529175 + RPT070 + + + 2.529175 + RPT071 + + + 3.971191 + RPT072 + + + 1.567871 + RPT073 + + + 0.125977 + RPT074 + + + 2.048584 + RPT075 + + + 0.125977 + RPT076 + + + 2.048584 + RPT077 + + + 3.490479 + RPT078 + + + 3.971191 + RPT079 + + + 4.932373 + RPT080 + + + 2.048584 + RPT081 + + + 0.606567 + RPT082 + + + 2.529175 + RPT083 + + + 1.567871 + RPT084 + + + 2.529175 + RPT085 + + + 3.971191 + RPT086 + + + 5.413086 + RPT087 + + + 1.087158 + RPT088 + + + 3.971191 + RPT089 + + + 12.142334 + RPT090 + + + 8.296997 + RPT091 + + + -0.835449 + RPT092 + + + 5.413086 + RPT093 + + + 25.119995 + RPT094 + + + 25.119995 + RPT095 + + + 23.197388 + RPT096 + + + 26.561890 + RPT097 + + + 26.081177 + RPT098 + + + 26.561890 + RPT099 + + + 26.081177 + RPT100 + + + 30.887940 + RPT101 + + + 25.600586 + RPT102 + + + 20.794067 + RPT103 + + + 17.429565 + RPT104 + + + 6.374390 + RPT105 + + + 4.932373 + RPT106 + + + 2.529175 + RPT107 + + + 15.506958 + RPT108 + + + 19.832764 + RPT109 + + + 20.313354 + RPT110 + + + 11.180908 + RPT111 + + + 2.048584 + RPT112 + + + 6.374390 + RPT113 + + + 7.335693 + RPT114 + + + 11.661621 + RPT115 + + + 12.142334 + RPT116 + + + 15.026245 + RPT117 + + + 13.584351 + RPT118 + + + 10.219605 + RPT119 + + + 9.258301 + RPT120 + + + 14.064941 + RPT121 + + + 11.661621 + RPT122 + + + 6.854980 + RPT123 + + + 4.932373 + RPT124 + + + 3.971191 + RPT125 + + + 5.893799 + RPT126 + + + 5.413086 + RPT127 + + + 22.716675 + RPT128 + + + 38.578369 + RPT129 + + + 58.765747 + RPT130 + + + 66.456299 + RPT131 + + + 62.611084 + RPT132 + + + 64.053101 + RPT133 + + + 65.975708 + RPT134 + + + 66.456299 + RPT135 + + + 61.169190 + RPT136 + + + 62.611084 + RPT137 + + + 61.649902 + RPT138 + + + 46.268921 + RPT139 + + + 36.175049 + RPT140 + + + 18.390747 + RPT141 + + + 10.219605 + RPT142 + + + 18.390747 + RPT143 + + + 37.136353 + RPT144 + + + 31.368530 + RPT145 + + + 4.932373 + RPT146 + + + 13.584351 + RPT147 + + + 24.639282 + RPT148 + + + 27.523193 + RPT149 + + + 22.716675 + RPT150 + + + 45.307495 + RPT151 + + + 26.561890 + RPT152 + + + 34.733154 + RPT153 + + + 26.561890 + RPT154 + + + 34.252441 + RPT155 + + + 28.965332 + RPT156 + + + 24.158569 + RPT157 + + + 23.197388 + RPT158 + + + 21.755371 + RPT159 + + + 21.755371 + RPT160 + + + 23.197388 + RPT161 + + + 9.739014 + RPT162 + + + 11.180908 + RPT163 + + + 12.622925 + RPT164 + + + 22.235962 + RPT165 + + + 38.097656 + RPT166 + + + 24.639282 + RPT167 + + + 16.948853 + RPT168 + + + 19.832764 + RPT169 + + + 3.009766 + RPT170 + + + 18.871460 + RPT171 + + + 15.506958 + RPT172 + + + 23.677978 + RPT173 + + + 36.655762 + RPT174 + + + 39.539551 + RPT175 + + + 40.500977 + RPT176 + + + 46.268921 + RPT177 + + + 55.709473 + RPT178 + + + 70.709473 + RPT179 + + + 75.709473 + RPT180 + + + 90.267456 + RPT181 + + + 95.963867 + RPT182 + + + 100.102295 + RPT183 + + + 93.373047 + RPT184 + + + 90.969727 + RPT185 + + + 88.085815 + RPT186 + + + 87.605103 + RPT187 + + + 102.986084 + RPT188 + + + 126.057617 + RPT189 + + + 144.803223 + RPT190 + + + 180.371704 + RPT191 + + + 191.426758 + RPT192 + + + 197.194580 + RPT193 + + + 210.652954 + RPT194 + + + 231.801758 + RPT195 + + + 208.730347 + RPT196 + + + 195.271973 + RPT197 + + + 187.100830 + RPT198 + + + 155.377564 + RPT199 + + + 148.167847 + RPT200 + + + 183.736206 + RPT201 + + + 200.078613 + RPT202 + + + 208.730347 + RPT203 + + + 221.227539 + RPT204 + + + 235.166382 + RPT205 + + + 226.033936 + RPT206 + + + 201.520508 + RPT207 + + + 188.542969 + RPT208 + + + 144.803223 + RPT209 + + + 141.919311 + RPT210 + + + 136.151367 + RPT211 + + + 110.196045 + RPT212 + + + 86.163208 + RPT213 + + + 75.588745 + RPT214 + + + 71.262940 + RPT215 + + + 66.937012 + RPT216 + + + 63.091797 + RPT217 + + + 61.649902 + RPT218 + + + 59.727173 + RPT219 + + + 55.881958 + RPT220 + + + 53.478638 + RPT221 + + + 55.401245 + RPT222 + + + 52.036743 + RPT223 + + + 49.152710 + RPT224 + + + 46.749512 + RPT225 + + + 48.672119 + RPT226 + + + 44.826904 + RPT227 + + + 44.826904 + RPT228 + + + 44.346314 + RPT229 + + + 45.307495 + RPT230 + + + 42.904175 + RPT231 + + + 33.771729 + RPT232 + + + diff --git a/gpsbabel/reference/route/psitrtes.txt b/gpsbabel/reference/route/psitrtes.txt old mode 100755 new mode 100644 diff --git a/gpsbabel/reference/track/bounds-test-track.gpx b/gpsbabel/reference/track/bounds-test-track.gpx new file mode 100644 index 000000000..996f36d3a --- /dev/null +++ b/gpsbabel/reference/track/bounds-test-track.gpx @@ -0,0 +1,505 @@ + + + + + 479.300000 + Head east on CA-190 E/Nadeau Trail Continue to follow CA-190 E + go 52.3&#160;mi + go 52.3&#160;mi + + + -55.600000 + Turn right at Airport Rd + go 0.8&#160;mi + go 0.8&#160;mi + + + -67.300000 + Arrive at: Furnace Creek Airport-L06, Death Valley National Park, Death Valley, CA 92328 + Arrive at: Furnace Creek Airport-L06, Death Valley National Park, Death Valley, CA 92328 + Arrive at: Furnace Creek Airport-L06, Death Valley National Park, Death Valley, CA 92328 + + + 2272.300000 + Head northwest + go 3.0&#160;mi + go 3.0&#160;mi + + + 1734.200000 + Continue straight onto Charcoal Kiln Rd + go 4.2&#160;mi + go 4.2&#160;mi + + + 1304.100000 + Continue onto Wood Canyon Rd + go 0.7&#160;mi + go 0.7&#160;mi + + + 1226.400000 + Continue onto Wildrose Rd + go 7.9&#160;mi + go 7.9&#160;mi + + + 1595.800000 + Slight left to stay on Wildrose Rd + go 13.2&#160;mi + go 13.2&#160;mi + + + 669.800000 + Arrive at: Wildrose Rd + Arrive at: Wildrose Rd + Arrive at: Wildrose Rd + + + Head east on Airport Rd + go 0.8&#160;mi + go 0.8&#160;mi + + + Arrive at: Airport Rd + Arrive at: Airport Rd + Arrive at: Airport Rd + + + Low Road + Generated from route Route + + + 479.300000 + RPT001 + + + 624.300000 + RPT005 + + + 663.700000 + RPT011 + + + 762.100000 + RPT019 + + + 927.400000 + RPT027 + + + 940.400000 + RPT032 + + + 969.300000 + RPT038 + + + 1028.200000 + RPT046 + + + 1094.500000 + RPT054 + + + 1132.700000 + RPT060 + + + 1184.900000 + RPT065 + + + 1201.800000 + RPT068 + + + 1281.700000 + RPT076 + + + 1311.300000 + RPT081 + + + 1493.900000 + RPT096 + + + 1439.500000 + RPT104 + + + 1395.500000 + RPT107 + + + 1377.700000 + RPT112 + + + 1291.500000 + RPT125 + + + 1226.000000 + RPT130 + + + 1089.000000 + RPT138 + + + 926.000000 + RPT147 + + + 669.900000 + RPT152 + + + 514.400000 + RPT160 + + + 449.500000 + RPT163 + + + 216.300000 + RPT169 + + + 3.400000 + RPT176 + + + -4.400000 + RPT182 + + + -5.400000 + RPT185 + + + -0.200000 + RPT190 + + + -2.600000 + RPT194 + + + -1.300000 + RPT200 + + + -4.900000 + RPT205 + + + -8.900000 + RPT209 + + + -13.000000 + RPT212 + + + -21.200000 + RPT223 + + + 36.800000 + RPT224 + + + 39.900000 + RPT229 + + + 45.000000 + RPT232 + + + 45.900000 + RPT236 + + + 45.200000 + RPT241 + + + 42.500000 + RPT246 + + + -49.100000 + RPT259 + + + -55.900000 + RPT265 + + + -60.400000 + RPT279 + + + -67.900000 + RPT287 + + + -69.800000 + RPT298 + + + -68.700000 + RPT307 + + + -69.100000 + RPT312 + + + -67.600000 + RPT320 + + + -69.300000 + RPT326 + + + -69.900000 + RPT331 + + + -63.600000 + RPT344 + + + -61.000000 + RPT352 + + + -57.900000 + RPT356 + + + -39.800000 + RPT362 + + + -57.700000 + RPT371 + + + -64.400000 + RPT377 + + + -55.600000 + RPT386 + + + -67.300000 + RPT399 + + + + + High Road + Generated from route Route + + + 2272.300000 + RPT001 + + + 2128.600000 + RPT014 + + + 2025.200000 + RPT025 + + + 1721.800000 + RPT056 + + + 1661.600000 + RPT063 + + + 1593.300000 + RPT067 + + + 1510.700000 + RPT075 + + + 1315.700000 + RPT089 + + + 1224.500000 + RPT112 + + + 1265.600000 + RPT119 + + + 1333.500000 + RPT140 + + + 1390.900000 + RPT147 + + + 1422.700000 + RPT152 + + + 1480.300000 + RPT162 + + + 1495.400000 + RPT167 + + + 1590.200000 + RPT189 + + + 1655.700000 + RPT218 + + + 1626.500000 + RPT263 + + + 1594.100000 + RPT279 + + + 1515.200000 + RPT286 + + + 1495.800000 + RPT294 + + + 1467.700000 + RPT309 + + + 1447.900000 + RPT317 + + + 1352.700000 + RPT340 + + + 1322.000000 + RPT350 + + + 1264.800000 + RPT356 + + + 1220.000000 + RPT362 + + + 1178.100000 + RPT370 + + + 1034.900000 + RPT389 + + + 1012.300000 + RPT393 + + + 836.700000 + RPT409 + + + 815.300000 + RPT414 + + + 739.100000 + RPT419 + + + 685.000000 + RPT426 + + + 669.800000 + RPT430 + + + + + No Elevation Route + Generated from route No Elevation Route + + + RPT001 + + + RPT002 + + + RPT003 + + + RPT004 + + + RPT005 + + + RPT006 + + + RPT007 + + + RPT008 + + + RPT009 + + + RPT010 + + + RPT011 + + + RPT012 + + + RPT013 + + + + diff --git a/gpsbabel/reference/track/bounds-test-track.kml b/gpsbabel/reference/track/bounds-test-track.kml new file mode 100644 index 000000000..ecb585e86 --- /dev/null +++ b/gpsbabel/reference/track/bounds-test-track.kml @@ -0,0 +1,2600 @@ + + + + GPS device + + -117.144015 + 36.438270 + 87257.203848 + + + + + + + + normal + #track_n + + + highlight + #track_h + + + + + + + + + normal + #waypoint_n + + + highlight + #waypoint_h + + + + + Waypoints + + Head east on CA-190 E/Nadeau Trail Continue to follow CA-190 E + go 52.3&#160;mi + #waypoint + + -117.422570,36.339560,479.30 + + + + Turn right at Airport Rd + go 0.8&#160;mi + #waypoint + + -116.865460,36.460850,-55.60 + + + + Arrive at: Furnace Creek Airport-L06, Death Valley National Park, Death Valley, CA 92328 + #waypoint + + -116.879200,36.463640,-67.30 + + + + Head northwest + go 3.0&#160;mi + #waypoint + + -117.072030,36.236600,2272.30 + + + + Continue straight onto Charcoal Kiln Rd + go 4.2&#160;mi + #waypoint + + -117.113260,36.253260,1734.20 + + + + Continue onto Wood Canyon Rd + go 0.7&#160;mi + #waypoint + + -117.179860,36.264610,1304.10 + + + + Continue onto Wildrose Rd + go 7.9&#160;mi + #waypoint + + -117.192050,36.265430,1226.40 + + + + Slight left to stay on Wildrose Rd + go 13.2&#160;mi + #waypoint + + -117.135520,36.335600,1595.80 + + + + Arrive at: Wildrose Rd + #waypoint + + -117.226936,36.494947,669.80 + + + + Head east on Airport Rd + go 0.8&#160;mi + #waypoint + + -116.879080,36.463670 + + + + Arrive at: Airport Rd + #waypoint + + -116.865720,36.460860 + + + + + Tracks + + Low Road + + + + Description Generated from route Route + Distance 52.8 mi + Min Alt -229.331 ft + Max Alt 4901.247 ft + ]]> + + + Points + + RPT001 + + + Longitude: -117.422570 + Latitude: 36.339560 + Altitude: 1572.507 ft + Heading: 309.7 + + ]]> + + -117.422570 + 36.339560 + 66 + + #track + + -117.422570,36.339560,479.30 + + + + RPT005 + + + Longitude: -117.354270 + Latitude: 36.345010 + Altitude: 2048.228 ft + Heading: 84.3 + + ]]> + + -117.354270 + 36.345010 + 66 + + #track + + -117.354270,36.345010,624.30 + + + + RPT011 + + + Longitude: -117.349030 + Latitude: 36.344640 + Altitude: 2177.493 ft + Heading: 95.0 + + ]]> + + -117.349030 + 36.344640 + 66 + + #track + + -117.349030,36.344640,663.70 + + + + RPT019 + + + Longitude: -117.335270 + Latitude: 36.348710 + Altitude: 2500.328 ft + Heading: 69.8 + + ]]> + + -117.335270 + 36.348710 + 66 + + #track + + -117.335270,36.348710,762.10 + + + + RPT027 + + + Longitude: -117.316960 + Latitude: 36.346040 + Altitude: 3042.651 ft + Heading: 100.3 + + ]]> + + -117.316960 + 36.346040 + 66 + + #track + + -117.316960,36.346040,927.40 + + + + RPT032 + + + Longitude: -117.314020 + Latitude: 36.343080 + Altitude: 3085.302 ft + Heading: 141.3 + + ]]> + + -117.314020 + 36.343080 + 66 + + #track + + -117.314020,36.343080,940.40 + + + + RPT038 + + + Longitude: -117.311530 + Latitude: 36.342480 + Altitude: 3180.118 ft + Heading: 106.7 + + ]]> + + -117.311530 + 36.342480 + 66 + + #track + + -117.311530,36.342480,969.30 + + + + RPT046 + + + Longitude: -117.307620 + Latitude: 36.346880 + Altitude: 3373.360 ft + Heading: 35.6 + + ]]> + + -117.307620 + 36.346880 + 66 + + #track + + -117.307620,36.346880,1028.20 + + + + RPT054 + + + Longitude: -117.301180 + Latitude: 36.347060 + Altitude: 3590.879 ft + Heading: 88.0 + + ]]> + + -117.301180 + 36.347060 + 66 + + #track + + -117.301180,36.347060,1094.50 + + + + RPT060 + + + Longitude: -117.295650 + Latitude: 36.351920 + Altitude: 3716.207 ft + Heading: 42.5 + + ]]> + + -117.295650 + 36.351920 + 66 + + #track + + -117.295650,36.351920,1132.70 + + + + RPT065 + + + Longitude: -117.292270 + Latitude: 36.357050 + Altitude: 3887.467 ft + Heading: 28.0 + + ]]> + + -117.292270 + 36.357050 + 66 + + #track + + -117.292270,36.357050,1184.90 + + + + RPT068 + + + Longitude: -117.289430 + Latitude: 36.358440 + Altitude: 3942.913 ft + Heading: 58.7 + + ]]> + + -117.289430 + 36.358440 + 66 + + #track + + -117.289430,36.358440,1201.80 + + + + RPT076 + + + Longitude: -117.286380 + Latitude: 36.364320 + Altitude: 4205.052 ft + Heading: 22.7 + + ]]> + + -117.286380 + 36.364320 + 66 + + #track + + -117.286380,36.364320,1281.70 + + + + RPT081 + + + Longitude: -117.287070 + Latitude: 36.367970 + Altitude: 4302.165 ft + Heading: 351.3 + + ]]> + + -117.287070 + 36.367970 + 66 + + #track + + -117.287070,36.367970,1311.30 + + + + RPT096 + + + Longitude: -117.278460 + Latitude: 36.406150 + Altitude: 4901.247 ft + Heading: 10.3 + + ]]> + + -117.278460 + 36.406150 + 66 + + #track + + -117.278460,36.406150,1493.90 + + + + RPT104 + + + Longitude: -117.274150 + Latitude: 36.414650 + Altitude: 4722.769 ft + Heading: 22.2 + + ]]> + + -117.274150 + 36.414650 + 66 + + #track + + -117.274150,36.414650,1439.50 + + + + RPT107 + + + Longitude: -117.270260 + Latitude: 36.419620 + Altitude: 4578.412 ft + Heading: 32.2 + + ]]> + + -117.270260 + 36.419620 + 66 + + #track + + -117.270260,36.419620,1395.50 + + + + RPT112 + + + Longitude: -117.267430 + Latitude: 36.419700 + Altitude: 4520.013 ft + Heading: 88.0 + + ]]> + + -117.267430 + 36.419700 + 66 + + #track + + -117.267430,36.419700,1377.70 + + + + RPT125 + + + Longitude: -117.260620 + Latitude: 36.428730 + Altitude: 4237.205 ft + Heading: 31.2 + + ]]> + + -117.260620 + 36.428730 + 66 + + #track + + -117.260620,36.428730,1291.50 + + + + RPT130 + + + Longitude: -117.251140 + Latitude: 36.434140 + Altitude: 4022.310 ft + Heading: 54.6 + + ]]> + + -117.251140 + 36.434140 + 66 + + #track + + -117.251140,36.434140,1226.00 + + + + RPT138 + + + Longitude: -117.243900 + Latitude: 36.446250 + Altitude: 3572.835 ft + Heading: 25.7 + + ]]> + + -117.243900 + 36.446250 + 66 + + #track + + -117.243900,36.446250,1089.00 + + + + RPT147 + + + Longitude: -117.236110 + Latitude: 36.463810 + Altitude: 3038.058 ft + Heading: 19.6 + + ]]> + + -117.236110 + 36.463810 + 66 + + #track + + -117.236110,36.463810,926.00 + + + + RPT152 + + + Longitude: -117.226980 + Latitude: 36.494960 + Altitude: 2197.835 ft + Heading: 13.3 + + ]]> + + -117.226980 + 36.494960 + 66 + + #track + + -117.226980,36.494960,669.90 + + + + RPT160 + + + Longitude: -117.222650 + Latitude: 36.519980 + Altitude: 1687.664 ft + Heading: 7.9 + + ]]> + + -117.222650 + 36.519980 + 66 + + #track + + -117.222650,36.519980,514.40 + + + + RPT163 + + + Longitude: -117.218940 + Latitude: 36.529870 + Altitude: 1474.738 ft + Heading: 16.8 + + ]]> + + -117.218940 + 36.529870 + 66 + + #track + + -117.218940,36.529870,449.50 + + + + RPT169 + + + Longitude: -117.199580 + Latitude: 36.563200 + Altitude: 709.646 ft + Heading: 25.0 + + ]]> + + -117.199580 + 36.563200 + 66 + + #track + + -117.199580,36.563200,216.30 + + + + RPT176 + + + Longitude: -117.147410 + Latitude: 36.605940 + Altitude: 11.155 ft + Heading: 44.4 + + ]]> + + -117.147410 + 36.605940 + 66 + + #track + + -117.147410,36.605940,3.40 + + + + RPT182 + + + Longitude: -117.143600 + Latitude: 36.607880 + Altitude: -14.436 ft + Heading: 57.6 + + ]]> + + -117.143600 + 36.607880 + 66 + + #track + + -117.143600,36.607880,-4.40 + + + + RPT185 + + + Longitude: -117.137140 + Latitude: 36.607210 + Altitude: -17.717 ft + Heading: 97.4 + + ]]> + + -117.137140 + 36.607210 + 66 + + #track + + -117.137140,36.607210,-5.40 + + + + RPT190 + + + Longitude: -117.127830 + Latitude: 36.603590 + Altitude: -0.656 ft + Heading: 115.8 + + ]]> + + -117.127830 + 36.603590 + 66 + + #track + + -117.127830,36.603590,-0.20 + + + + RPT194 + + + Longitude: -117.117700 + Latitude: 36.605420 + Altitude: -8.530 ft + Heading: 77.3 + + ]]> + + -117.117700 + 36.605420 + 66 + + #track + + -117.117700,36.605420,-2.60 + + + + RPT200 + + + Longitude: -117.106740 + Latitude: 36.604640 + Altitude: -4.265 ft + Heading: 95.1 + + ]]> + + -117.106740 + 36.604640 + 66 + + #track + + -117.106740,36.604640,-1.30 + + + + RPT205 + + + Longitude: -117.097480 + Latitude: 36.601210 + Altitude: -16.076 ft + Heading: 114.8 + + ]]> + + -117.097480 + 36.601210 + 66 + + #track + + -117.097480,36.601210,-4.90 + + + + RPT209 + + + Longitude: -117.094200 + Latitude: 36.601720 + Altitude: -29.199 ft + Heading: 79.0 + + ]]> + + -117.094200 + 36.601720 + 66 + + #track + + -117.094200,36.601720,-8.90 + + + + RPT212 + + + Longitude: -117.082040 + Latitude: 36.611300 + Altitude: -42.651 ft + Heading: 45.5 + + ]]> + + -117.082040 + 36.611300 + 66 + + #track + + -117.082040,36.611300,-13.00 + + + + RPT223 + + + Longitude: -117.067710 + Latitude: 36.617900 + Altitude: -69.554 ft + Heading: 60.1 + + ]]> + + -117.067710 + 36.617900 + 66 + + #track + + -117.067710,36.617900,-21.20 + + + + RPT224 + + + Longitude: -117.035740 + Latitude: 36.639210 + Altitude: 120.735 ft + Heading: 50.3 + + ]]> + + -117.035740 + 36.639210 + 66 + + #track + + -117.035740,36.639210,36.80 + + + + RPT229 + + + Longitude: -117.031520 + Latitude: 36.639940 + Altitude: 130.906 ft + Heading: 77.8 + + ]]> + + -117.031520 + 36.639940 + 66 + + #track + + -117.031520,36.639940,39.90 + + + + RPT232 + + + Longitude: -117.029010 + Latitude: 36.638970 + Altitude: 147.638 ft + Heading: 115.7 + + ]]> + + -117.029010 + 36.638970 + 66 + + #track + + -117.029010,36.638970,45.00 + + + + RPT236 + + + Longitude: -117.024030 + Latitude: 36.633800 + Altitude: 150.591 ft + Heading: 142.3 + + ]]> + + -117.024030 + 36.633800 + 66 + + #track + + -117.024030,36.633800,45.90 + + + + RPT241 + + + Longitude: -117.016190 + Latitude: 36.628480 + Altitude: 148.294 ft + Heading: 130.2 + + ]]> + + -117.016190 + 36.628480 + 66 + + #track + + -117.016190,36.628480,45.20 + + + + RPT246 + + + Longitude: -117.006890 + Latitude: 36.625430 + Altitude: 139.436 ft + Heading: 112.2 + + ]]> + + -117.006890 + 36.625430 + 66 + + #track + + -117.006890,36.625430,42.50 + + + + RPT259 + + + Longitude: -116.969890 + Latitude: 36.596550 + Altitude: -161.089 ft + Heading: 134.2 + + ]]> + + -116.969890 + 36.596550 + 66 + + #track + + -116.969890,36.596550,-49.10 + + + + RPT265 + + + Longitude: -116.954760 + Latitude: 36.592470 + Altitude: -183.399 ft + Heading: 108.6 + + ]]> + + -116.954760 + 36.592470 + 66 + + #track + + -116.954760,36.592470,-55.90 + + + + RPT279 + + + Longitude: -116.936270 + Latitude: 36.584200 + Altitude: -198.163 ft + Heading: 119.1 + + ]]> + + -116.936270 + 36.584200 + 66 + + #track + + -116.936270,36.584200,-60.40 + + + + RPT287 + + + Longitude: -116.927060 + Latitude: 36.575990 + Altitude: -222.769 ft + Heading: 138.0 + + ]]> + + -116.927060 + 36.575990 + 66 + + #track + + -116.927060,36.575990,-67.90 + + + + RPT298 + + + Longitude: -116.909750 + Latitude: 36.568520 + Altitude: -229.003 ft + Heading: 118.2 + + ]]> + + -116.909750 + 36.568520 + 66 + + #track + + -116.909750,36.568520,-69.80 + + + + RPT307 + + + Longitude: -116.904380 + Latitude: 36.561450 + Altitude: -225.394 ft + Heading: 148.6 + + ]]> + + -116.904380 + 36.561450 + 66 + + #track + + -116.904380,36.561450,-68.70 + + + + RPT312 + + + Longitude: -116.894840 + Latitude: 36.557140 + Altitude: -226.706 ft + Heading: 119.4 + + ]]> + + -116.894840 + 36.557140 + 66 + + #track + + -116.894840,36.557140,-69.10 + + + + RPT320 + + + Longitude: -116.891610 + Latitude: 36.549690 + Altitude: -221.785 ft + Heading: 160.8 + + ]]> + + -116.891610 + 36.549690 + 66 + + #track + + -116.891610,36.549690,-67.60 + + + + RPT326 + + + Longitude: -116.886030 + Latitude: 36.543000 + Altitude: -227.362 ft + Heading: 146.2 + + ]]> + + -116.886030 + 36.543000 + 66 + + #track + + -116.886030,36.543000,-69.30 + + + + RPT331 + + + Longitude: -116.882770 + Latitude: 36.532760 + Altitude: -229.331 ft + Heading: 165.7 + + ]]> + + -116.882770 + 36.532760 + 66 + + #track + + -116.882770,36.532760,-69.90 + + + + RPT344 + + + Longitude: -116.881860 + Latitude: 36.513990 + Altitude: -208.661 ft + Heading: 177.8 + + ]]> + + -116.881860 + 36.513990 + 66 + + #track + + -116.881860,36.513990,-63.60 + + + + RPT352 + + + Longitude: -116.875450 + Latitude: 36.502030 + Altitude: -200.131 ft + Heading: 156.7 + + ]]> + + -116.875450 + 36.502030 + 66 + + #track + + -116.875450,36.502030,-61.00 + + + + RPT356 + + + Longitude: -116.875070 + Latitude: 36.498060 + Altitude: -189.961 ft + Heading: 175.6 + + ]]> + + -116.875070 + 36.498060 + 66 + + #track + + -116.875070,36.498060,-57.90 + + + + RPT362 + + + Longitude: -116.868420 + Latitude: 36.487220 + Altitude: -130.577 ft + Heading: 153.7 + + ]]> + + -116.868420 + 36.487220 + 66 + + #track + + -116.868420,36.487220,-39.80 + + + + RPT371 + + + Longitude: -116.871370 + Latitude: 36.482910 + Altitude: -189.304 ft + Heading: 208.8 + + ]]> + + -116.871370 + 36.482910 + 66 + + #track + + -116.871370,36.482910,-57.70 + + + + RPT377 + + + Longitude: -116.868950 + Latitude: 36.479500 + Altitude: -211.286 ft + Heading: 150.3 + + ]]> + + -116.868950 + 36.479500 + 66 + + #track + + -116.868950,36.479500,-64.40 + + + + RPT386 + + + Longitude: -116.865460 + Latitude: 36.460850 + Altitude: -182.415 ft + Heading: 171.4 + + ]]> + + -116.865460 + 36.460850 + 66 + + #track + + -116.865460,36.460850,-55.60 + + + + RPT399 + + + Longitude: -116.879200 + Latitude: 36.463640 + Altitude: -220.801 ft + Heading: 284.2 + + ]]> + + -116.879200 + 36.463640 + 66 + + #track + + -116.879200,36.463640,-67.30 + + + + + Path + #lineStyle + + 1 + + -117.422570,36.339560,479.30 + -117.354270,36.345010,624.30 + -117.349030,36.344640,663.70 + -117.335270,36.348710,762.10 + -117.316960,36.346040,927.40 + -117.314020,36.343080,940.40 + -117.311530,36.342480,969.30 + -117.307620,36.346880,1028.20 + -117.301180,36.347060,1094.50 + -117.295650,36.351920,1132.70 + -117.292270,36.357050,1184.90 + -117.289430,36.358440,1201.80 + -117.286380,36.364320,1281.70 + -117.287070,36.367970,1311.30 + -117.278460,36.406150,1493.90 + -117.274150,36.414650,1439.50 + -117.270260,36.419620,1395.50 + -117.267430,36.419700,1377.70 + -117.260620,36.428730,1291.50 + -117.251140,36.434140,1226.00 + -117.243900,36.446250,1089.00 + -117.236110,36.463810,926.00 + -117.226980,36.494960,669.90 + -117.222650,36.519980,514.40 + -117.218940,36.529870,449.50 + -117.199580,36.563200,216.30 + -117.147410,36.605940,3.40 + -117.143600,36.607880,-4.40 + -117.137140,36.607210,-5.40 + -117.127830,36.603590,-0.20 + -117.117700,36.605420,-2.60 + -117.106740,36.604640,-1.30 + -117.097480,36.601210,-4.90 + -117.094200,36.601720,-8.90 + -117.082040,36.611300,-13.00 + -117.067710,36.617900,-21.20 + -117.035740,36.639210,36.80 + -117.031520,36.639940,39.90 + -117.029010,36.638970,45.00 + -117.024030,36.633800,45.90 + -117.016190,36.628480,45.20 + -117.006890,36.625430,42.50 + -116.969890,36.596550,-49.10 + -116.954760,36.592470,-55.90 + -116.936270,36.584200,-60.40 + -116.927060,36.575990,-67.90 + -116.909750,36.568520,-69.80 + -116.904380,36.561450,-68.70 + -116.894840,36.557140,-69.10 + -116.891610,36.549690,-67.60 + -116.886030,36.543000,-69.30 + -116.882770,36.532760,-69.90 + -116.881860,36.513990,-63.60 + -116.875450,36.502030,-61.00 + -116.875070,36.498060,-57.90 + -116.868420,36.487220,-39.80 + -116.871370,36.482910,-57.70 + -116.868950,36.479500,-64.40 + -116.865460,36.460850,-55.60 + -116.879200,36.463640,-67.30 + + + + + + High Road + + + + Description Generated from route Route + Distance 28.0 mi + Min Alt 2197.507 ft + Max Alt 7455.053 ft + ]]> + + + Points + + RPT001 + + + Longitude: -117.072030 + Latitude: 36.236600 + Altitude: 7455.053 ft + Heading: 309.5 + + ]]> + + -117.072030 + 36.236600 + 66 + + #track + + -117.072030,36.236600,2272.30 + + + + RPT014 + + + Longitude: -117.074910 + Latitude: 36.245280 + Altitude: 6983.596 ft + Heading: 345.0 + + ]]> + + -117.074910 + 36.245280 + 66 + + #track + + -117.074910,36.245280,2128.60 + + + + RPT025 + + + Longitude: -117.082060 + Latitude: 36.250720 + Altitude: 6644.357 ft + Heading: 313.3 + + ]]> + + -117.082060 + 36.250720 + 66 + + #track + + -117.082060,36.250720,2025.20 + + + + RPT056 + + + Longitude: -117.114930 + Latitude: 36.253250 + Altitude: 5648.950 ft + Heading: 275.5 + + ]]> + + -117.114930 + 36.253250 + 66 + + #track + + -117.114930,36.253250,1721.80 + + + + RPT063 + + + Longitude: -117.124070 + Latitude: 36.249180 + Altitude: 5451.444 ft + Heading: 241.1 + + ]]> + + -117.124070 + 36.249180 + 66 + + #track + + -117.124070,36.249180,1661.60 + + + + RPT067 + + + Longitude: -117.140500 + Latitude: 36.248030 + Altitude: 5227.362 ft + Heading: 265.0 + + ]]> + + -117.140500 + 36.248030 + 66 + + #track + + -117.140500,36.248030,1593.30 + + + + RPT075 + + + Longitude: -117.154180 + Latitude: 36.250220 + Altitude: 4956.365 ft + Heading: 281.2 + + ]]> + + -117.154180 + 36.250220 + 66 + + #track + + -117.154180,36.250220,1510.70 + + + + RPT089 + + + Longitude: -117.178010 + Latitude: 36.264660 + Altitude: 4316.601 ft + Heading: 306.9 + + ]]> + + -117.178010 + 36.264660 + 66 + + #track + + -117.178010,36.264660,1315.70 + + + + RPT112 + + + Longitude: -117.195180 + Latitude: 36.265950 + Altitude: 4017.388 ft + Heading: 275.3 + + ]]> + + -117.195180 + 36.265950 + 66 + + #track + + -117.195180,36.265950,1224.50 + + + + RPT119 + + + Longitude: -117.195290 + Latitude: 36.268100 + Altitude: 4152.231 ft + Heading: 357.6 + + ]]> + + -117.195290 + 36.268100 + 66 + + #track + + -117.195290,36.268100,1265.60 + + + + RPT140 + + + Longitude: -117.186690 + Latitude: 36.271540 + Altitude: 4375.000 ft + Heading: 63.6 + + ]]> + + -117.186690 + 36.271540 + 66 + + #track + + -117.186690,36.271540,1333.50 + + + + RPT147 + + + Longitude: -117.187690 + Latitude: 36.283430 + Altitude: 4563.320 ft + Heading: 356.1 + + ]]> + + -117.187690 + 36.283430 + 66 + + #track + + -117.187690,36.283430,1390.90 + + + + RPT152 + + + Longitude: -117.184800 + Latitude: 36.288060 + Altitude: 4667.651 ft + Heading: 26.7 + + ]]> + + -117.184800 + 36.288060 + 66 + + #track + + -117.184800,36.288060,1422.70 + + + + RPT162 + + + Longitude: -117.175450 + Latitude: 36.292430 + Altitude: 4856.627 ft + Heading: 59.9 + + ]]> + + -117.175450 + 36.292430 + 66 + + #track + + -117.175450,36.292430,1480.30 + + + + RPT167 + + + Longitude: -117.174710 + Latitude: 36.299830 + Altitude: 4906.168 ft + Heading: 4.6 + + ]]> + + -117.174710 + 36.299830 + 66 + + #track + + -117.174710,36.299830,1495.40 + + + + RPT189 + + + Longitude: -117.147920 + Latitude: 36.307650 + Altitude: 5217.192 ft + Heading: 70.1 + + ]]> + + -117.147920 + 36.307650 + 66 + + #track + + -117.147920,36.307650,1590.20 + + + + RPT218 + + + Longitude: -117.155360 + Latitude: 36.315930 + Altitude: 5432.087 ft + Heading: 324.1 + + ]]> + + -117.155360 + 36.315930 + 66 + + #track + + -117.155360,36.315930,1655.70 + + + + RPT263 + + + Longitude: -117.147000 + Latitude: 36.332460 + Altitude: 5336.286 ft + Heading: 22.2 + + ]]> + + -117.147000 + 36.332460 + 66 + + #track + + -117.147000,36.332460,1626.50 + + + + RPT279 + + + Longitude: -117.135460 + Latitude: 36.335790 + Altitude: 5229.987 ft + Heading: 70.3 + + ]]> + + -117.135460 + 36.335790 + 66 + + #track + + -117.135460,36.335790,1594.10 + + + + RPT286 + + + Longitude: -117.133870 + Latitude: 36.359960 + Altitude: 4971.129 ft + Heading: 3.0 + + ]]> + + -117.133870 + 36.359960 + 66 + + #track + + -117.133870,36.359960,1515.20 + + + + RPT294 + + + Longitude: -117.142570 + Latitude: 36.376850 + Altitude: 4907.480 ft + Heading: 337.5 + + ]]> + + -117.142570 + 36.376850 + 66 + + #track + + -117.142570,36.376850,1495.80 + + + + RPT309 + + + Longitude: -117.156910 + Latitude: 36.394590 + Altitude: 4815.289 ft + Heading: 327.0 + + ]]> + + -117.156910 + 36.394590 + 66 + + #track + + -117.156910,36.394590,1467.70 + + + + RPT317 + + + Longitude: -117.166230 + Latitude: 36.398990 + Altitude: 4750.328 ft + Heading: 300.4 + + ]]> + + -117.166230 + 36.398990 + 66 + + #track + + -117.166230,36.398990,1447.90 + + + + RPT340 + + + Longitude: -117.177600 + Latitude: 36.413520 + Altitude: 4437.992 ft + Heading: 327.8 + + ]]> + + -117.177600 + 36.413520 + 66 + + #track + + -117.177600,36.413520,1352.70 + + + + RPT350 + + + Longitude: -117.185560 + Latitude: 36.415730 + Altitude: 4337.270 ft + Heading: 289.0 + + ]]> + + -117.185560 + 36.415730 + 66 + + #track + + -117.185560,36.415730,1322.00 + + + + RPT356 + + + Longitude: -117.187740 + Latitude: 36.421720 + Altitude: 4149.606 ft + Heading: 343.7 + + ]]> + + -117.187740 + 36.421720 + 66 + + #track + + -117.187740,36.421720,1264.80 + + + + RPT362 + + + Longitude: -117.192970 + Latitude: 36.426060 + Altitude: 4002.625 ft + Heading: 315.9 + + ]]> + + -117.192970 + 36.426060 + 66 + + #track + + -117.192970,36.426060,1220.00 + + + + RPT370 + + + Longitude: -117.191580 + Latitude: 36.431930 + Altitude: 3865.157 ft + Heading: 10.8 + + ]]> + + -117.191580 + 36.431930 + 66 + + #track + + -117.191580,36.431930,1178.10 + + + + RPT389 + + + Longitude: -117.200850 + Latitude: 36.450210 + Altitude: 3395.341 ft + Heading: 337.8 + + ]]> + + -117.200850 + 36.450210 + 66 + + #track + + -117.200850,36.450210,1034.90 + + + + RPT393 + + + Longitude: -117.204490 + Latitude: 36.451910 + Altitude: 3321.194 ft + Heading: 300.1 + + ]]> + + -117.204490 + 36.451910 + 66 + + #track + + -117.204490,36.451910,1012.30 + + + + RPT409 + + + Longitude: -117.211120 + Latitude: 36.475590 + Altitude: 2745.079 ft + Heading: 347.3 + + ]]> + + -117.211120 + 36.475590 + 66 + + #track + + -117.211120,36.475590,836.70 + + + + RPT414 + + + Longitude: -117.214550 + Latitude: 36.476240 + Altitude: 2674.869 ft + Heading: 283.3 + + ]]> + + -117.214550 + 36.476240 + 66 + + #track + + -117.214550,36.476240,815.30 + + + + RPT419 + + + Longitude: -117.222200 + Latitude: 36.485010 + Altitude: 2424.869 ft + Heading: 325.0 + + ]]> + + -117.222200 + 36.485010 + 66 + + #track + + -117.222200,36.485010,739.10 + + + + RPT426 + + + Longitude: -117.224040 + Latitude: 36.492950 + Altitude: 2247.375 ft + Heading: 349.4 + + ]]> + + -117.224040 + 36.492950 + 66 + + #track + + -117.224040,36.492950,685.00 + + + + RPT430 + + + Longitude: -117.226940 + Latitude: 36.494950 + Altitude: 2197.507 ft + Heading: 310.6 + + ]]> + + -117.226940 + 36.494950 + 66 + + #track + + -117.226940,36.494950,669.80 + + + + + Path + #lineStyle + + 1 + + -117.072030,36.236600,2272.30 + -117.074910,36.245280,2128.60 + -117.082060,36.250720,2025.20 + -117.114930,36.253250,1721.80 + -117.124070,36.249180,1661.60 + -117.140500,36.248030,1593.30 + -117.154180,36.250220,1510.70 + -117.178010,36.264660,1315.70 + -117.195180,36.265950,1224.50 + -117.195290,36.268100,1265.60 + -117.186690,36.271540,1333.50 + -117.187690,36.283430,1390.90 + -117.184800,36.288060,1422.70 + -117.175450,36.292430,1480.30 + -117.174710,36.299830,1495.40 + -117.147920,36.307650,1590.20 + -117.155360,36.315930,1655.70 + -117.147000,36.332460,1626.50 + -117.135460,36.335790,1594.10 + -117.133870,36.359960,1515.20 + -117.142570,36.376850,1495.80 + -117.156910,36.394590,1467.70 + -117.166230,36.398990,1447.90 + -117.177600,36.413520,1352.70 + -117.185560,36.415730,1322.00 + -117.187740,36.421720,1264.80 + -117.192970,36.426060,1220.00 + -117.191580,36.431930,1178.10 + -117.200850,36.450210,1034.90 + -117.204490,36.451910,1012.30 + -117.211120,36.475590,836.70 + -117.214550,36.476240,815.30 + -117.222200,36.485010,739.10 + -117.224040,36.492950,685.00 + -117.226940,36.494950,669.80 + + + + + + No Elevation Route + + + + Description Generated from route No Elevation Route + Distance 4170.5 ft + ]]> + + + Points + + RPT001 + + + Longitude: -116.879080 + Latitude: 36.463670 + Heading: 309.6 + + ]]> + + -116.879080 + 36.463670 + 66 + + #track + + -116.879080,36.463670 + + + + RPT002 + + + Longitude: -116.878300 + Latitude: 36.463860 + Heading: 73.1 + + ]]> + + -116.878300 + 36.463860 + 66 + + #track + + -116.878300,36.463860 + + + + RPT003 + + + Longitude: -116.878140 + Latitude: 36.463880 + Heading: 81.2 + + ]]> + + -116.878140 + 36.463880 + 66 + + #track + + -116.878140,36.463880 + + + + RPT004 + + + Longitude: -116.877910 + Latitude: 36.463840 + Heading: 102.2 + + ]]> + + -116.877910 + 36.463840 + 66 + + #track + + -116.877910,36.463840 + + + + RPT005 + + + Longitude: -116.876800 + Latitude: 36.463450 + Heading: 113.6 + + ]]> + + -116.876800 + 36.463450 + 66 + + #track + + -116.876800,36.463450 + + + + RPT006 + + + Longitude: -116.872870 + Latitude: 36.462240 + Heading: 110.9 + + ]]> + + -116.872870 + 36.462240 + 66 + + #track + + -116.872870,36.462240 + + + + RPT007 + + + Longitude: -116.868650 + Latitude: 36.460990 + Heading: 110.2 + + ]]> + + -116.868650 + 36.460990 + 66 + + #track + + -116.868650,36.460990 + + + + RPT008 + + + Longitude: -116.868250 + Latitude: 36.461010 + Heading: 86.4 + + ]]> + + -116.868250 + 36.461010 + 66 + + #track + + -116.868250,36.461010 + + + + RPT009 + + + Longitude: -116.867660 + Latitude: 36.461210 + Heading: 67.1 + + ]]> + + -116.867660 + 36.461210 + 66 + + #track + + -116.867660,36.461210 + + + + RPT010 + + + Longitude: -116.867020 + Latitude: 36.460950 + Heading: 116.8 + + ]]> + + -116.867020 + 36.460950 + 66 + + #track + + -116.867020,36.460950 + + + + RPT011 + + + Longitude: -116.866830 + Latitude: 36.460910 + Heading: 104.7 + + ]]> + + -116.866830 + 36.460910 + 66 + + #track + + -116.866830,36.460910 + + + + RPT012 + + + Longitude: -116.866460 + Latitude: 36.460860 + Heading: 99.5 + + ]]> + + -116.866460 + 36.460860 + 66 + + #track + + -116.866460,36.460860 + + + + RPT013 + + + Longitude: -116.865720 + Latitude: 36.460860 + Heading: 90.0 + + ]]> + + -116.865720 + 36.460860 + 66 + + #track + + -116.865720,36.460860 + + + + + Path + #lineStyle + + 1 + + -116.879080,36.463670 + -116.878300,36.463860 + -116.878140,36.463880 + -116.877910,36.463840 + -116.876800,36.463450 + -116.872870,36.462240 + -116.868650,36.460990 + -116.868250,36.461010 + -116.867660,36.461210 + -116.867020,36.460950 + -116.866830,36.460910 + -116.866460,36.460860 + -116.865720,36.460860 + + + + + + + diff --git a/gpsbabel/reference/track/course~tcx.gpx b/gpsbabel/reference/track/course~tcx.gpx index 5fcf3435e..49de3f3a9 100644 --- a/gpsbabel/reference/track/course~tcx.gpx +++ b/gpsbabel/reference/track/course~tcx.gpx @@ -8,9 +8,9 @@ - WPT001 - WPT001 - WPT001 + LAP001 + LAP001 + LAP001 ThursRide diff --git a/gpsbabel/reference/track/fit-sample.fit b/gpsbabel/reference/track/fit-sample.fit new file mode 100644 index 0000000000000000000000000000000000000000..5f797e93ae5c642ed42e5b06ae29904b2d4f77ee GIT binary patch literal 16678 zcmZYH1$Y!!*9Y*~&2D6u1PPQtu^^WKX|bIhT#Gveid%7~1PY}TcnJ>0TBKN!pv5hC zi&NY!5S-!;Sv&duhi1>F&&T`lyz}(8_s-0nd+(gNLWWFLw5Y0@_GQgF&8lel6C7lj zVzG=fnd8moc&j;HGih4ht*h?s%NreI(z;kuQ!V&;NzJU8<4q>B>AaR&P1CYzR-a{D zkYyZxZZc^WliAD(I79sTbo?fxrrCqE>YA2a%kb&PQ$j4`LM`KP9?Pdw+4yW`WEyNT z+fC*m&Vf&zn)b(}y|UnRshTM@^%HX50W4$rx?yUnDMM=NSDN;j7K(HHo1GbXnasE* zt4TxFmQS~0O6C96(6p?YoquT=YqE^Be!7}qb9{(7KFmDk-&8gvjX2>p>X3HdIa{g@S|GI)?b|DC`YPua-g;GO*>c`|Skm(n~|#Ymh?bNVXXf zemetmy)e}8EmJ5Y2iuX1X=b?$LkZwkQ>}cQ_TNW7&8ul~wjh5VmMi?be{a)z9mmC< z8EQ>j3LV5_8EBj3&(E3+TlmCKBSxo?sf4EWx1ANc2kZ6NP`^%2p&dHg_x}8?k72tW z8Ol6Ag}PSKw0^c4VlQER9vUikO$yzqscC&}t;F8JKHfLf?d>UKZ^-tIm>X91o}mgI zNud=j*bFgKzUY`Q?%)|*N}tb@+^_*x3^gN%i>i!c+lG4gZ+$2L z3%P8lDurG2Vk+A$v7)dc7Y%jL>7u2x*=CECfNeW(sFh#2X!IhsJz_fS)>%V6YwV&i z32eROTFSvzoH5k7wk|652is!5St`TQ>WZZbAE(s^K3;LkP#t@_Xz*4}vqbK@ChW@- zhWhLW7roiTR#56geOQHKxc-SQvL9hfkaSI9n+_Z5+FTdyJk7RTtR?L9K|^(0h3mh< zwpgq^EcAe(3Maa#^KDJ*V_PlO6;@-vp`wqvDEDJc>u#Ga))Q7_pP`a2xTw-AP3xM@ z`oZ?^F;wF_F1qkh)4JH!NxC@L`Q3)f_u54Z&|iIPJ1zDDtQstb$xYvfv276h3ASbz z+JfCpO){Fa4z}%L@vu&?m!G?-O_WJ%YkMI!3AS;kp{5seQ)skFYi&CxHXT+LHlVzl z&KEIht!zJw{Q}F9XsFXQ+_bGY+dQ#(u!B1cmE~(Ug&S;##TLV|!di58)7Z*vqs0llwajYXu9w?56i4*(!-$gstCbs1x_yRCEHHMeI7PB&_B;H|?Iz_Fm3+ z3zoFOP(#U0r{}QQCEZ=vhjoTp9pa%}3)!UqwLXFsfaT2Qp+?Ktwn(1OVSCmZDq8^$ z6<*7BP3$c!WR0P+m-5hpEo{+pJ{PRaDnlKr>Y;&q*!qj5!fY$h&o%bYnnP?A#H`WL zF*TPNYF&E|#hhXbJR=({>k>mX@8zNA7ub%-wPb=lS!5{NFb_3MVml}H8Eo7_Lk%16 zp)U8?PKbRDTRGoQU1xcy>{B-BlW-}~F~jE>YW@-rwS3DqOVSmFotbT@!5ci(+ru_e zEEd+}7elq)4Ktfzi^NL7j?OTY_qc~{*x175-VNB~X@+Wf)kB#h**;3Tim+-^4VC$k zhkp8;?Soi#SpG?d+VIXpGYYT;%B&8o+;~GZ3-VH)ShlN@t|6@8SVP$}dg*>Cwo78o zV68`^{eAAGedXAyinWH7|H)8)#dv9IHMU@}4zN+f4VB5^r6zUQT8VuNt2N9}11oyz zeM7c+Vm)C4h8SvmJuj8`hHaNvf7tJX4E0S5FYRf^HcV^~ti?d|k)6EsSr@jfVuNAN z2H?He)l0S>Y@37NKG4z|Nj_% zncsEz6Rd@OdU0xIlXX1ui0NUdvXi}(`XgU?xc|znQ()`5BAS`)rR!tZ@{7%cHTl+1 zW0!kr@8tj7v2`wNeg{L%+T^9@>~wf*2+*t8fwrZFGX!-J0rFoR-uuhdcOBk zi#=woh3&HcT-M#NnEHm=804b^hs;`2+bgj@VZ-VeDo-XKMV>TkjcxTM&m%Bb4MR=J zb%S`Ax_L`N@Sl}Z?D>rXz~9L{!MuJJwWeXOD4rugV#wjk{*+cf{V ztZvw#qIeU|_0h>(Y-_}{{LwMr6vo>;!AENgvUL*+h7~SosL`8!G&PnjP*3czdeMg3 zw%11;O0%_B@#Z_l(A(jiKq6}5+zK?p>W!oec z4eOH4P~Bhps9+PerGB%-z|zXn%ExG4Bl+*uZ}@lX5oF?8rY(m9HUD zpV>jEm(8T7Yz6Cl|aCCa-XNNZqQD%K9x_?A=cXhl?NX^_^$wqNq>3_EzmsVa9O znzuSgYnCnw?GD?2&Z*Y+Aez202<>%@lv!U`&l677@;jn2i9y;owzFabV0Vr<)#x9H z688n64`?jqIRtj|FQ>XVo~Zp%wqjz#VWvG!)nW$G$J0TGGy{?CXjterr%GBt6n>RW zlXT-@S=KvM)m20}?yyx8n*wXS%Bf0hBI@)HTdG{=3|P!kr|PkbDCesnt+|cF=D>cO z?^Fj5;oeh%&>#IFwh-3g7pMB}G*NbwMXP5kC$XsT01T_G}sSwkuRY=zt?}M%D?Nr}rsg$FHMJt~!syGDO+r_DV2}z}$hD9r9YcAJv99FWuQ!NWi zB~^*-wbZ3ku#v5u>aZ!5o>XU(_l5Nw>|+b3s**xfpe~zL%H=X__Sa7J{yEXg#%ycF zl3?Q-IaQrIM2lOp9TU3)J5tZ7Ze1X{+L7%Gu}82xwQ()Sh?2YWz2B01cnVAY3hiMp z(V~79t#Y~u{533Z6{otsktphWi&o8cSJHii{a)UwE-fW`GSZ?|x3!b=d0|Tpr$+l0d6l|>Bsgm;&&Ai06N6dh|32~~T=yz`?v8@oR0Gk)&R1`{7`~H8e zD(oB0sm5z~?vL4I#3z`IV>EwUrtrJBsXo#!2WwmL*B_smw4sR4f+OO%)KWt=Te|p+ z^Qe=mtI9~1?J4J9T&}AI?5I~)`#$>U#!I$91Y8$peAJcp%ts|t*j`B4HiG^9MpyT4 z`zSG$?WE+{9CqTFu9{r*(b!NcEbuJb!t_VFT6@e#XEU*tlyse8L3ebOf_L&~IoP(# z`Fg;HUei_B7QC3p5z7*S^lI{oC-b1 zpH(Yq8zJfLz(&^BmBs3#q{CLNgl(hPLssvg+#1K`*V&%yv!gI~Qz?rmNsRUivdT zTclVtEZ*Z#KW_8V(cHmWAzOcWw-$m$eQ>DE8@;r$0NY-%BCs>B9O}01ABeTp$g9NQjdykb>;rb!~VMNP}^pD zDWY01%6YbwOBI;uqC?%7i0{cd!FWEcGI9Kkzt)~p9meZ2JU+hEk`p>i$Xz@icz>O&VV)#x3p88(ktJJ`NW z4pqOkmzE9+*2>y?i*<$_UgJ>tn|SHLaJJoIJz(pXIaIA$UK$o3jP_MhuCpJk@Ir@L zj1iDoQ`iFU!9lPla~-NSMo!{pv2B)n_#RgKSClnITt@tc@qoa{kYyOmUpI&Iaa!FR zf#b=u9Lki_OE;GWBkn6I*D(f`3@d2IxAfXz#2dHd`X|B${Nhk|Jsz6AB^WWqeYuWl zutcOg`ocrEcCjf*_bbc+>zeGLZU@;~i~R;mndwk-E_mquakjrC&&9B9uzN>6^uyU; z^wagkmccs0I_&e%p-XJ3QpZ-pGQzrS^-z-=Z1pAGI@o|24%H{YLrd&4-F(6ph+z_8C8y!}Oz_aww`?8d9`?dY{fst*5yp02wvA$kV4bHr)U%!*`r8r$ zbBg^9s|8!v#zPx3u+5R{JPYeR#i24a@X-0JZ2iS9!&*;vsH>H5@447Iirs*DCpuJ8 z35>iJWGf+d7nXm5Llwb@ZRc3F3}TO955_yx{OlfjQ;ID}>>12~YgrPGdng-%?~8_F zuVMXBp4)>wRIq9YVnP{zu)c@2pY2d<-EQ*K3PIeLL+;(f>E=6>=Y^XrjYIHW4~#yV z3Sks+3G%#$k@J>pE9873utN#xBd)vYWcv_|uMG5CFdN5F{`f0&g+n#M?*=>%)+Rj* z#9`)7aoF|nKHP&K4hu~ehjAXGkS^~vH~rIr^ACJqhr_O{b*MY1+?3RvEtmh?)=1df z4GuN#PdAks!1kS34%me)4pnNKo8rC?L2P_eEDtPUheMTL`4}$uK>5YMD*x$Fd1kw*=9Cb`@PW9f80_XjhdMjcO<^5TGXnWp%BD-h$D__W)N{;? zL@nbqyQIIa2s?hoq3UjN(^qTQqW$?U0PFS8p?*1u=e9Ql@!k>X51PP=;awGb5q05U2;#&SV&A~#zHq4b$!>C<;Aayp zdA5aBct)}hr)78p8tc{VeUd63bTY_{L>~j9@Z?2uIgZR zr;I%m<2SKllVNSM>gr`V4|UBHit(F2|6`9};T1iUEt2h!*bJmAlpXPGZ4dQ`3dPt? zJF(fYoH_A5(%eG@@`YmjCh(2_8!TfkU3Ko@p|^!XG1f9s?tKAl7VJb94OhE5eM?or-LSB;5wsBBiShm@zu> z6pQl~lIJ7AV-@s-?;JYXvVzXtT7@sLD_x%y(4$;+*h@%Fr4aK+JYq>WctUqFF zM@cWymQZ}#$+y2XNJYmSa5+?HIWIlg%@*i~Lt(qnf3&EId6fg9h}#0+A`!4Zo;%dr zx?W27n=KIAM8ZZra;WI$UP?UA7MQKg2HX37k7lKv0>`*=8ytMgADB{6DdoBVa#NACtcu9L5igByD zQZB_|uB#4JW&-AvK5$u&kY`>Rb{YNn=hM8@o7fhKm4PMRbEr!A1}JI?L(CVL!LJD0 z@Q*{SUgV{YHn!_>zN)bD=&Qd=@Y3N-Y!=I#KSBmy*6<`%%)hfqjd*R1V*119Y}5VjWl`HCp$;I$^A)0>)~3>|k3Zb^uloV?47P`Do^TwgqCxV2+u(ion>A z_bA&Du~V@8b9LqI=%a`;Y-V`|=U}!4x+>ot^OG0ZBpwK63qhadkAG|6cM14iCLg}9 zJb^ek=u;fLH~hQID8>KA!ItyL!(ZkX_&BZ1`S{Qxj5qf2(cUY3-Z;6Y>#({Bx{4a? zqb12~PyP2|NlKUBt#tYEfA>Gbh7UMRb9qkpVWT&pZN~fP)N{5XVvk|fFuu2YvX3Uc zV|(I1m-RWU0>%Ze&Gb=64_jco^c^e-%Rn zg7b(aFn$>l$+k_-XDN&^o2$CovJqokIoJ+}* zmMt)z8x8CK4r8|WP(P}$1=@09SPK`%USIg=PObl1EbKe4t`adOeYFAGc4_A&VOKGh zUDkv-r?1)Ch?RmlOimRZMD)A`TVJsSV)4qb z9X6->BRA25Zfv#uWo)ep`y-x*0E%5yM!s^C4RilwaNeOITIo}|dUJ~;zm>(Ljo-L2R z9$AOMp6O0?YA)tTw%hQ|2oW0zt6vWDm&=K=?z17*DkOQ1ft9G_RH^GQXL!hl@2t*Z z6JeLDIaP7YZLU6P!}nxa$#W8Hc6F!9yoadX8Mb<2(_nRKI@PqJL}xGB@LgvUn*pm> z3v-kwiC$i13#>$%3mcAkx|vBtJ@44?o_!rlXF0IcwiQ{~uF~9r}>k*3B@qB`%|2PM`KF+Cv zlZoCIx1&BpiCuy%pNwa46``?i$N0|~xwq@E(lgL5&l1H~up?&KB9;tmI>)IZjuS1b zZb$vQCw3new9u()A0Yaot{wGuz1S1jz2#2T9ChqKQ?|fd;&a#p%)5KG5xH8}@jZJ? z(!GJL!+ia`^=QxS?b_Gr+E5DY)>fx#oIrG>s~z8$Qze}nR%-|Pon`1-dfKt_wTzf4 z2CKRE;vUe3Rt&If?QOa|^AOn815Ra~iuDLX?O55nMl2jw`Iu8(!`$qKQFg7Tt)%1` z32Su9se&*!dw0AYD~SW+7*VihSR2t5bF(2o+qD6<#*$}lSllJFOY|SBXW6wuw*3-U z=7Fuc>{M5~pRIn{r!{NZ3?!e#K8i*BxO}Ot= zbD9zDPOxi3Y;(n8Vap$&EqqNBw(`GL0#@#cQinYO~1>j9@m7 zkNq+61N<%@e#fzK6|9)_&(&K##m3vhGkh8&wqdVOU@heWq%&p%U;dc48>oLdo+W z?6(GnI+p4s-zc`3V#i?Zu%2?{J1>nI&o)Ht6s#=PVV-#6rNL9#9!cB20NeGoq2?ud zsnaiPlf*8=?>nZ0;h9zPh>2a(vJ)gifO6(r2 zDb}A_6R}cvE!($Z|G;v$$67^<72Mp&Hp6e0r!ap%^PG><`k5Cv-r31elQAx_a3`nH zrJlZpebxoL4rX8_^ZN0m;n?Lxavh~$!?0rgIOZRd zbB1FlS1BoHCyXYbA9>@U2KmCZ-s!Hf0_@o&Lp6Hfp<{)^u>+@qTz@rKr>TZ&aK%Hn zi-+Sq{Z8s-ZP@ndSOfew#x0F-?7#_(S2Tcy%tW2tCkS(yzr#-CeJoMSWc<9#_Y#HRoodCQ>DY|^%@V_?av3{?j6md_@z1?CYa z!h*1yQVR7Q-&V)_UBuXg%9=vE{I`n+#Zc{UV-9dHTVM=w zBWxG!v-55`ayT6EU~|cH8|)r-A1yxYrb8#gwKld8u|2T8+pq>2^MgAtg(Jp1Aoq6w zHXD{@g_~;J3dflHd`Wi?Yvra5p==-h!xg(BM`5@mp1zxb`!R~oSQD@V0+-t&-xB#-;K5MMcmZ30NZl8Zx2kz z&bXUV*vS>kHb~4=6fq=hUYMKm>k*i1SSl6*d$AYqJhzMDDn?-Ktx3)o4*Po_`nabq zT2&(g^G_EfT^3mT{f7D~*+mKUBT&v4#iBUfpNKWiy68-^2t4z^w`3mJDeMaDaKJ^c z+D2#{(>=R_u#<HiqHg2Z0%PD+VJ}bP-PY4Z4W>n4 zXX6t|R|^(<4sEZMi(1TO`ykc;cJw@UOV)MKvftSziG2<0e92IwD!Az7Dz?CSkXEo^ zR}57=)l@fp5bmO*2mh15wKpv1P4p$c6#DZd z+j;-Ftpi~dlhHRn$1dVaY{$ihz}DV2)JN><&6dO#n9KPQmiexsx?I3+;QMSchHD)K zGu=b~bUcOrc+3{qDHadQb|1T}_NP#}mu!LY%}KCU5AY7zm_my_vOSi1H4Wy1IhUnS z{#3Tva-F}zRy@M4u9+#+BQzt-Ded$(SQvIt?~2EDW@2k1_B*W4Q$wX-S9Zl5Y#qc_ zusz2+q-zRU^0Qr%^Zfy9`VxIm^A!5KC|iQqW?1Xjc(>NT&g;?{@t#i>ON2dsgLjXf zLOCmDMC?$qYU)IlNQAPc!3tmzu`RbyPT#+!~PE=7Bo-* literal 0 HcmV?d00001 diff --git a/gpsbabel/reference/track/fit-sample.gpx b/gpsbabel/reference/track/fit-sample.gpx new file mode 100644 index 000000000..2b0a01984 --- /dev/null +++ b/gpsbabel/reference/track/fit-sample.gpx @@ -0,0 +1,2679 @@ + + + + + + + + 35.800000 + + 1.240000 + + + 35.800000 + + 1.888000 + + + 35.800000 + + 2.844000 + + + 35.800000 + + 3.729000 + + + 35.800000 + + 4.038000 + + + 34.600000 + + 3.987000 + + + 34.200000 + + 4.048000 + + + 34.200000 + + 3.703000 + + + 34.000000 + + 3.653000 + + + 33.800000 + + 3.673000 + + + 33.800000 + + 3.671000 + + + 33.800000 + + 3.639000 + + + 33.800000 + + 3.634000 + + + 33.800000 + + 3.671000 + + + 33.800000 + + 3.651000 + + + 33.800000 + + 3.601000 + + + 33.800000 + + 3.364000 + + + 33.800000 + + 3.253000 + + + 33.800000 + + 3.294000 + + + 33.800000 + + 3.222000 + + + 33.800000 + + 3.260000 + + + 33.800000 + + 3.434000 + + + 33.800000 + + 3.487000 + + + 33.800000 + + 3.745000 + + + 33.800000 + + 3.876000 + + + 33.800000 + + 3.749000 + + + 33.800000 + + 3.748000 + + + 33.800000 + + 3.743000 + + + 33.600000 + + 3.753000 + + + 32.600000 + + 3.728000 + + + 32.200000 + + 3.728000 + + + 32.000000 + + 3.757000 + + + 31.800000 + + 3.790000 + + + 31.800000 + + 3.759000 + + + 31.000000 + + 3.766000 + + + 30.400000 + + 3.822000 + + + 30.000000 + + 3.793000 + + + 29.800000 + + 3.726000 + + + 29.800000 + + 3.737000 + + + 29.800000 + + 3.781000 + + + 29.800000 + + 3.713000 + + + 29.600000 + + 3.559000 + + + 29.600000 + + 3.547000 + + + 29.600000 + + 3.525000 + + + 29.600000 + + 3.540000 + + + 29.600000 + + 3.536000 + + + 29.600000 + + 3.533000 + + + 29.600000 + + 3.557000 + + + 29.600000 + + 3.627000 + + + 29.600000 + + 3.646000 + + + 29.600000 + + 3.588000 + + + 29.600000 + + 3.573000 + + + 29.600000 + + 3.595000 + + + 29.600000 + + 3.587000 + + + 29.600000 + + 3.507000 + + + 29.600000 + + 3.545000 + + + 29.600000 + + 3.617000 + + + 29.600000 + + 3.695000 + + + 29.600000 + + 3.644000 + + + 29.600000 + + 3.540000 + + + 29.600000 + + 3.526000 + + + 29.600000 + + 3.537000 + + + 29.600000 + + 3.531000 + + + 29.600000 + + 3.487000 + + + 29.600000 + + 3.475000 + + + 29.600000 + + 3.455000 + + + 29.600000 + + 3.486000 + + + 29.600000 + + 3.597000 + + + 29.600000 + + 3.575000 + + + 29.600000 + + 3.574000 + + + 29.600000 + + 3.540000 + + + 29.600000 + + 3.544000 + + + 29.600000 + + 3.541000 + + + 29.600000 + + 3.393000 + + + 29.600000 + + 3.334000 + + + 29.600000 + + 3.417000 + + + 29.600000 + + 3.481000 + + + 29.600000 + + 3.514000 + + + 29.600000 + + 3.449000 + + + 29.600000 + + 3.348000 + + + 29.600000 + + 3.298000 + + + 29.600000 + + 3.333000 + + + 29.600000 + + 3.387000 + + + 29.600000 + + 3.341000 + + + 29.600000 + + 3.362000 + + + 29.600000 + + 3.387000 + + + 29.600000 + + 3.387000 + + + 29.600000 + + 3.380000 + + + 29.600000 + + 3.375000 + + + 29.600000 + + 3.724000 + + + 29.600000 + + 3.791000 + + + 29.200000 + + 3.542000 + + + 28.400000 + + 3.568000 + + + 28.000000 + + 3.660000 + + + 27.800000 + + 3.705000 + + + 27.800000 + + 3.687000 + + + 27.600000 + + 3.630000 + + + 27.200000 + + 3.561000 + + + 26.400000 + + 3.551000 + + + 26.000000 + + 3.562000 + + + 25.800000 + + 3.880000 + + + 25.800000 + + 3.812000 + + + 25.600000 + + 3.471000 + + + 25.600000 + + 3.498000 + + + 25.600000 + + 3.430000 + + + 25.600000 + + 3.380000 + + + 25.600000 + + 3.420000 + + + 25.600000 + + 3.378000 + + + 25.600000 + + 3.414000 + + + 25.600000 + + 3.505000 + + + 25.600000 + + 3.490000 + + + 25.600000 + + 3.783000 + + + 25.600000 + + 3.856000 + + + 25.600000 + + 3.534000 + + + 25.600000 + + 3.431000 + + + 25.600000 + + 3.438000 + + + 26.000000 + + 3.499000 + + + 26.800000 + + 3.416000 + + + 27.200000 + + 3.156000 + + + 27.400000 + + 3.234000 + + + 28.200000 + + 3.519000 + + + 28.800000 + + 3.766000 + + + 29.200000 + + 3.715000 + + + 29.400000 + + 3.792000 + + + 29.600000 + + 3.920000 + + + 29.600000 + + 3.883000 + + + 29.800000 + + 3.793000 + + + 29.800000 + + 3.840000 + + + 29.800000 + + 3.906000 + + + 29.800000 + + 3.839000 + + + 29.000000 + + 3.838000 + + + 28.400000 + + 3.756000 + + + 27.000000 + + 3.642000 + + + 26.400000 + + 3.542000 + + + 25.800000 + + 3.577000 + + + 25.000000 + + 3.793000 + + + 24.400000 + + 3.839000 + + + 24.000000 + + 3.724000 + + + 23.800000 + + 3.544000 + + + 23.600000 + + 3.413000 + + + 23.600000 + + 3.313000 + + + 23.600000 + + 3.375000 + + + 23.600000 + + 3.589000 + + + 23.600000 + + 3.755000 + + + 23.600000 + + 3.784000 + + + 23.600000 + + 3.629000 + + + 24.000000 + + 3.550000 + + + 24.600000 + + 3.573000 + + + 25.200000 + + 3.554000 + + + 25.400000 + + 3.677000 + + + 25.400000 + + 3.742000 + + + 25.600000 + + 3.722000 + + + 25.600000 + + 3.687000 + + + 26.000000 + + 3.773000 + + + 26.600000 + + 3.903000 + + + 27.000000 + + 3.871000 + + + 27.200000 + + 3.608000 + + + 27.400000 + + 3.515000 + + + 27.600000 + + 3.604000 + + + 27.600000 + + 3.698000 + + + 27.600000 + + 3.774000 + + + 27.600000 + + 3.772000 + + + 27.600000 + + 3.750000 + + + 27.600000 + + 3.750000 + + + 27.600000 + + 3.671000 + + + 27.600000 + + 3.631000 + + + 27.600000 + + 3.514000 + + + 27.600000 + + 3.566000 + + + 27.600000 + + 3.788000 + + + 27.600000 + + 3.871000 + + + 27.600000 + + 3.633000 + + + 27.600000 + + 3.510000 + + + 27.600000 + + 3.452000 + + + 27.600000 + + 3.455000 + + + 27.600000 + + 3.520000 + + + 27.600000 + + 3.537000 + + + 26.800000 + + 3.455000 + + + 26.200000 + + 3.337000 + + + 25.800000 + + 3.398000 + + + 24.800000 + + 3.517000 + + + 24.200000 + + 3.511000 + + + 23.800000 + + 3.460000 + + + 23.600000 + + 3.488000 + + + 23.600000 + + 3.601000 + + + 23.600000 + + 3.612000 + + + 23.600000 + + 3.456000 + + + 23.600000 + + 3.387000 + + + 23.600000 + + 3.471000 + + + 23.600000 + + 3.501000 + + + 22.600000 + + 3.508000 + + + 22.200000 + + 3.499000 + + + 21.800000 + + 3.453000 + + + 21.600000 + + 3.504000 + + + 21.600000 + + 3.539000 + + + 21.600000 + + 3.440000 + + + 21.600000 + + 3.498000 + + + 21.400000 + + 3.684000 + + + 20.600000 + + 3.799000 + + + 20.000000 + + 3.654000 + + + 19.800000 + + 3.915000 + + + 19.600000 + + 3.912000 + + + 19.600000 + + 3.600000 + + + 19.600000 + + 3.545000 + + + 19.600000 + + 3.347000 + + + 19.400000 + + 3.183000 + + + 19.400000 + + 3.261000 + + + 19.400000 + + 3.203000 + + + 19.400000 + + 3.174000 + + + 19.400000 + + 3.285000 + + + 19.400000 + + 3.658000 + + + 20.000000 + + 3.990000 + + + 20.600000 + + 4.185000 + + + 21.000000 + + 3.891000 + + + 21.800000 + + 3.582000 + + + 22.600000 + + 3.704000 + + + 23.000000 + + 3.835000 + + + 23.400000 + + 3.691000 + + + 23.400000 + + 3.771000 + + + 23.600000 + + 3.889000 + + + 23.600000 + + 3.604000 + + + 23.600000 + + 3.506000 + + + 24.400000 + + 3.575000 + + + 25.000000 + + 3.882000 + + + 25.400000 + + 3.806000 + + + 25.600000 + + 3.556000 + + + 25.600000 + + 3.622000 + + + 25.600000 + + 3.674000 + + + 25.600000 + + 3.521000 + + + 25.800000 + + 3.403000 + + + 25.800000 + + 3.327000 + + + 25.800000 + + 3.404000 + + + 25.800000 + + 3.488000 + + + 25.800000 + + 3.608000 + + + 25.800000 + + 3.680000 + + + 25.800000 + + 3.760000 + + + 25.800000 + + 3.638000 + + + 25.800000 + + 3.479000 + + + 25.800000 + + 3.439000 + + + 25.800000 + + 3.424000 + + + 25.800000 + + 3.376000 + + + 25.800000 + + 3.340000 + + + 25.800000 + + 3.331000 + + + 26.400000 + + 3.406000 + + + 27.000000 + + 3.562000 + + + 27.400000 + + 3.609000 + + + 27.600000 + + 3.544000 + + + 27.600000 + + 3.494000 + + + 27.800000 + + 3.441000 + + + 27.800000 + + 3.431000 + + + 27.800000 + + 3.356000 + + + 27.800000 + + 3.442000 + + + 27.200000 + + 3.549000 + + + 26.600000 + + 3.603000 + + + 26.400000 + + 3.609000 + + + 26.000000 + + 3.537000 + + + 26.000000 + + 3.468000 + + + 25.800000 + + 4.013000 + + + 25.800000 + + 4.282000 + + + 25.800000 + + 3.873000 + + + 25.800000 + + 3.844000 + + + 25.800000 + + 3.527000 + + + 26.200000 + + 3.270000 + + + 26.800000 + + 3.310000 + + + 27.200000 + + 3.361000 + + + 27.600000 + + 3.329000 + + + 27.600000 + + 3.234000 + + + 27.800000 + + 3.233000 + + + 27.800000 + + 3.292000 + + + 27.800000 + + 3.376000 + + + 27.800000 + + 3.467000 + + + 27.800000 + + 3.650000 + + + 27.800000 + + 3.651000 + + + 27.800000 + + 3.357000 + + + 28.000000 + + 3.338000 + + + 28.800000 + + 3.372000 + + + 29.200000 + + 3.520000 + + + 29.200000 + + 3.524000 + + + 29.400000 + + 3.421000 + + + 29.600000 + + 3.589000 + + + 29.800000 + + 3.721000 + + + 29.800000 + + 3.778000 + + + 29.800000 + + 3.824000 + + + 29.800000 + + 3.766000 + + + 29.800000 + + 3.780000 + + + 29.800000 + + 3.713000 + + + 29.800000 + + 3.566000 + + + 29.800000 + + 3.571000 + + + 29.800000 + + 3.521000 + + + 29.800000 + + 3.678000 + + + 29.800000 + + 3.975000 + + + 29.800000 + + 3.866000 + + + 29.800000 + + 3.798000 + + + 29.800000 + + 3.448000 + + + 29.200000 + + 3.278000 + + + 28.400000 + + 3.636000 + + + 27.200000 + + 3.802000 + + + 25.400000 + + 4.054000 + + + 24.600000 + + 3.879000 + + + 24.200000 + + 3.569000 + + + 23.800000 + + 3.671000 + + + 23.800000 + + 3.537000 + + + 23.600000 + + 3.498000 + + + 23.600000 + + 3.403000 + + + 23.600000 + + 3.595000 + + + 23.600000 + + 3.606000 + + + 23.800000 + + 3.755000 + + + 24.600000 + + 3.430000 + + + 25.000000 + + 3.372000 + + + 25.200000 + + 3.402000 + + + 25.400000 + + 3.197000 + + + 25.400000 + + 3.230000 + + + 25.600000 + + 3.559000 + + + 25.600000 + + 3.546000 + + + 25.600000 + + 3.588000 + + + 25.600000 + + 3.705000 + + + 25.600000 + + 3.744000 + + + 25.600000 + + 3.575000 + + + 25.600000 + + 3.708000 + + + 25.600000 + + 3.602000 + + + 25.600000 + + 3.209000 + + + 26.400000 + + 3.042000 + + + 26.800000 + + 3.082000 + + + 27.200000 + + 3.259000 + + + 27.400000 + + 3.538000 + + + 27.600000 + + 3.660000 + + + 27.600000 + + 3.681000 + + + 27.600000 + + 3.670000 + + + 27.600000 + + 3.343000 + + + 27.600000 + + 3.247000 + + + 27.600000 + + 3.370000 + + + 27.600000 + + 3.394000 + + + 27.600000 + + 3.900000 + + + 27.600000 + + 3.577000 + + + 27.600000 + + 3.479000 + + + 27.600000 + + 3.425000 + + + 27.600000 + + 3.496000 + + + 27.600000 + + 3.484000 + + + 27.600000 + + 3.526000 + + + 27.600000 + + 3.586000 + + + 27.600000 + + 3.467000 + + + 27.600000 + + 3.700000 + + + 27.600000 + + 3.563000 + + + 27.600000 + + 3.881000 + + + 27.600000 + + 3.562000 + + + 27.600000 + + 3.514000 + + + 27.600000 + + 3.549000 + + + 27.600000 + + 3.527000 + + + 27.600000 + + 3.509000 + + + 27.600000 + + 3.522000 + + + 27.600000 + + 3.497000 + + + 27.600000 + + 3.709000 + + + 27.600000 + + 3.907000 + + + 27.600000 + + 3.633000 + + + 27.600000 + + 3.343000 + + + 27.600000 + + 3.343000 + + + 27.600000 + + 3.254000 + + + 27.600000 + + 3.163000 + + + 27.600000 + + 3.181000 + + + 27.600000 + + 3.283000 + + + 27.600000 + + 3.329000 + + + 27.600000 + + 3.399000 + + + 27.600000 + + 3.334000 + + + 27.600000 + + 3.371000 + + + 27.600000 + + 3.351000 + + + 27.600000 + + 3.437000 + + + 27.600000 + + 3.398000 + + + 27.600000 + + 3.508000 + + + 27.600000 + + 3.629000 + + + 27.600000 + + 3.633000 + + + 27.600000 + + 3.580000 + + + 27.600000 + + 3.614000 + + + 27.400000 + + 3.591000 + + + 26.600000 + + 3.365000 + + + 26.200000 + + 3.426000 + + + 26.000000 + + 3.641000 + + + 26.000000 + + 3.659000 + + + 25.800000 + + 3.594000 + + + 25.800000 + + 3.541000 + + + 25.600000 + + 3.570000 + + + 25.600000 + + 3.604000 + + + 25.600000 + + 3.536000 + + + 25.600000 + + 3.385000 + + + 25.600000 + + 3.279000 + + + 25.600000 + + 3.291000 + + + 25.600000 + + 3.381000 + + + 25.600000 + + 3.591000 + + + 25.600000 + + 3.715000 + + + 25.600000 + + 3.556000 + + + 26.000000 + + 3.846000 + + + 26.600000 + + 3.864000 + + + 27.000000 + + 3.535000 + + + 27.200000 + + 3.507000 + + + 27.400000 + + 3.555000 + + + 27.600000 + + 3.502000 + + + 27.600000 + + 3.515000 + + + 27.800000 + + 3.528000 + + + 28.600000 + + 3.633000 + + + 29.600000 + + 3.469000 + + + 30.000000 + + 3.384000 + + + 30.800000 + + 3.125000 + + + 32.200000 + + 3.242000 + + + 33.000000 + + 3.377000 + + + 33.600000 + + 3.270000 + + + 34.400000 + + 3.152000 + + + 35.000000 + + 3.007000 + + + 35.000000 + + 3.000000 + + + 35.400000 + + 3.220000 + + + 35.400000 + + 3.149000 + + + 35.600000 + + 3.224000 + + + 35.600000 + + 3.224000 + + + 35.600000 + + 3.226000 + + + 35.800000 + + 3.578000 + + + 35.800000 + + 3.910000 + + + 35.800000 + + 4.022000 + + + 35.800000 + + 3.886000 + + + 35.800000 + + 3.934000 + + + 35.800000 + + 3.840000 + + + 35.800000 + + 3.756000 + + + 35.800000 + + 3.761000 + + + 35.800000 + + 3.664000 + + + 35.800000 + + 3.621000 + + + 35.800000 + + 3.621000 + + + 35.800000 + + 3.658000 + + + 35.800000 + + 3.692000 + + + 35.800000 + + 3.636000 + + + 35.800000 + + 3.632000 + + + 35.800000 + + 3.706000 + + + 35.800000 + + 3.833000 + + + 35.800000 + + 3.851000 + + + 35.800000 + + 3.803000 + + + 35.800000 + + 3.699000 + + + 35.800000 + + 3.639000 + + + 35.800000 + + 3.646000 + + + 35.800000 + + 3.668000 + + + 35.800000 + + 3.669000 + + + 35.800000 + + 3.591000 + + + 35.800000 + + 3.529000 + + + 35.800000 + + 3.509000 + + + 35.800000 + + 3.522000 + + + 35.800000 + + 3.485000 + + + 35.800000 + + 3.474000 + + + 35.800000 + + 3.446000 + + + 35.800000 + + 3.303000 + + + 35.800000 + + 3.210000 + + + 35.800000 + + 3.292000 + + + 35.800000 + + 3.433000 + + + 35.800000 + + 3.456000 + + + 35.800000 + + 3.427000 + + + 35.800000 + + 3.473000 + + + 35.800000 + + 3.893000 + + + 35.800000 + + 4.009000 + + + 35.800000 + + 3.698000 + + + 35.800000 + + 3.723000 + + + 35.800000 + + 3.748000 + + + 35.800000 + + 3.764000 + + + 35.800000 + + 3.707000 + + + 35.800000 + + 3.780000 + + + 35.800000 + + 3.637000 + + + 35.800000 + + 3.552000 + + + 35.800000 + + 3.538000 + + + 35.000000 + + 3.866000 + + + 34.600000 + + 3.838000 + + + 34.200000 + + 3.890000 + + + 33.400000 + + 3.552000 + + + 32.600000 + + 3.388000 + + + 32.200000 + + 3.316000 + + + 32.000000 + + 3.370000 + + + 31.800000 + + 3.449000 + + + 31.800000 + + 3.572000 + + + 31.800000 + + 3.631000 + + + 31.800000 + + 3.596000 + + + 31.600000 + + 3.514000 + + + 31.600000 + + 3.508000 + + + 31.600000 + + 3.504000 + + + 31.600000 + + 3.512000 + + + 31.600000 + + 3.506000 + + + 31.600000 + + 3.481000 + + + 31.600000 + + 3.473000 + + + 31.600000 + + 3.406000 + + + 31.600000 + + 3.294000 + + + 31.600000 + + 3.322000 + + + 31.600000 + + 3.435000 + + + 31.600000 + + 3.472000 + + + 31.600000 + + 3.565000 + + + 31.600000 + + 3.665000 + + + 31.600000 + + 3.588000 + + + 30.800000 + + 3.413000 + + + 30.200000 + + 3.335000 + + + 30.000000 + + 3.266000 + + + 29.800000 + + 3.483000 + + + 29.800000 + + 3.565000 + + + 28.600000 + + 3.535000 + + + 28.200000 + + 3.632000 + + + 27.800000 + + 3.621000 + + + 27.800000 + + 3.831000 + + + 27.600000 + + 4.085000 + + + 27.600000 + + 3.813000 + + + 27.600000 + + 3.492000 + + + 27.600000 + + 3.443000 + + + 28.400000 + + 3.490000 + + + 29.000000 + + 3.585000 + + + 29.400000 + + 3.539000 + + + 29.800000 + + 3.540000 + + + 30.800000 + + 3.536000 + + + 31.200000 + + 3.483000 + + + 31.800000 + + 3.460000 + + + 32.800000 + + 3.570000 + + + 33.200000 + + 3.704000 + + + 33.600000 + + 3.767000 + + + 33.600000 + + 3.744000 + + + 33.800000 + + 3.818000 + + + 33.800000 + + 3.830000 + + + 33.800000 + + 3.722000 + + + 33.800000 + + 3.622000 + + + 33.800000 + + 3.660000 + + + 33.800000 + + 3.777000 + + + 33.800000 + + 3.739000 + + + 33.800000 + + 3.739000 + + + 33.800000 + + 3.794000 + + + 33.800000 + + 3.785000 + + + 33.800000 + + 3.595000 + + + 33.800000 + + 3.467000 + + + 33.800000 + + 3.486000 + + + 33.800000 + + 3.514000 + + + 33.800000 + + 3.561000 + + + 33.800000 + + 3.734000 + + + 33.800000 + + 3.894000 + + + 33.800000 + + 3.921000 + + + 33.800000 + + 3.935000 + + + 33.800000 + + 3.797000 + + + 33.800000 + + 3.749000 + + + 34.200000 + + 3.807000 + + + 35.000000 + + 3.913000 + + + + diff --git a/gpsbabel/reference/track/gpx_garmin_extensions-kml_track.kml b/gpsbabel/reference/track/gpx_garmin_extensions-kml_track.kml index 4d94bd15f..459c3eeaa 100644 --- a/gpsbabel/reference/track/gpx_garmin_extensions-kml_track.kml +++ b/gpsbabel/reference/track/gpx_garmin_extensions-kml_track.kml @@ -3,25 +3,26 @@ xmlns:gx="http://www.google.com/kml/ext/2.2"> GPS device - - - Heart Rate - - - Cadence - - + + + 2008-08-20T07:04:48Z + 2008-08-20T07:04:55Z + + -0.035329 + 51.506248 + 1300.000000 + - - + + @@ -110,6 +111,14 @@ 6 + + + Heart Rate + + + Cadence + + Waypoints @@ -171,11 +180,11 @@ 2008-08-20T07:04:47Z - + Distance 85.9 ft - Min Alt 0.449 ft + Min Alt -51.588 ft Max Alt 0.449 ft Max Speed 11.3 mph Avg Speed 8.4 mph @@ -196,7 +205,7 @@ Points 2008-08-20T07:04:47Z-0 - + Longitude: -0.035187 @@ -222,7 +231,7 @@ 2008-08-20T07:04:47Z-1 - + Longitude: -0.035242 @@ -248,7 +257,7 @@ 2008-08-20T07:04:47Z-2 - + Longitude: -0.035303 @@ -274,7 +283,7 @@ 2008-08-20T07:04:47Z-3 - + Longitude: -0.035354 @@ -300,7 +309,7 @@ 2008-08-20T07:04:47Z-4 - + Longitude: -0.035400 @@ -325,7 +334,7 @@ 2008-08-20T07:04:47Z-5 - + Longitude: -0.035438 @@ -350,7 +359,7 @@ 2008-08-20T07:04:47Z-6 - + Longitude: -0.035462 @@ -376,7 +385,7 @@ 2008-08-20T07:04:47Z-7 - + Longitude: -0.035472 @@ -408,34 +417,17 @@ 1 -0.035187,51.506172,0.14 - -0.035187,51.506172,0.137000 -0.035242,51.506196,-0.82 - -0.035242,51.506196,-0.824000 -0.035303,51.506221,-15.72 - -0.035303,51.506221,-15.724000 -0.035354,51.506246,-15.72 - -0.035354,51.506246,-15.724000 -0.035400,51.506271,-15.24 - -0.035400,51.506271,-15.244000 -0.035438,51.506297,-15.24 - -0.035438,51.506297,-15.244000 -0.035462,51.506315,-15.24 - -0.035462,51.506315,-15.244000 -0.035472,51.506324,-15.24 - -0.035472,51.506324,-15.244000 - - - 2008-08-20T07:04:48Z - 2008-08-20T07:04:55Z - - -0.035329 - 51.506248 - 1300.000000 - diff --git a/gpsbabel/reference/track/gpx_subsecond-sample.gpx b/gpsbabel/reference/track/gpx_subsecond-sample.gpx new file mode 100644 index 000000000..e61fc7309 --- /dev/null +++ b/gpsbabel/reference/track/gpx_subsecond-sample.gpx @@ -0,0 +1,96 @@ + + + + + + + + 289.200000 + + 13.818100 + trkpt-2011-07-02T17:47:25.000Z + 3d +T + + + 289.300000 + + 14.049800 + trkpt-2011-07-02T17:47:25.000Z + 3d +T + + + 289.300000 + + 14.161100 + trkpt-2011-07-02T17:47:25.000Z + 3d +T + + + 289.400000 + + 14.090400 + trkpt-2011-07-02T17:47:25.000Z + 3d +T + + + 289.500000 + + 14.183800 + trkpt-2011-07-02T17:47:25.000Z + 3d +T + + + + + diff --git a/gpsbabel/reference/track/gpx_subsecond-sample~subrip.srt b/gpsbabel/reference/track/gpx_subsecond-sample~subrip.srt new file mode 100644 index 000000000..e44b07ed3 --- /dev/null +++ b/gpsbabel/reference/track/gpx_subsecond-sample~subrip.srt @@ -0,0 +1,24 @@ +1 +00:00:00,000 --> 00:00:00,200 +0 km/h, 289 m +17:47:25 Lat=49.79469 Lon=9.83402 + +2 +00:00:00,200 --> 00:00:00,400 +289 m +17:47:25 Lat=49.79472 Lon=9.83400 + +3 +00:00:00,400 --> 00:00:00,600 +289 m +17:47:25 Lat=49.79474 Lon=9.83398 + +4 +00:00:00,600 --> 00:00:00,800 +289 m +17:47:25 Lat=49.79476 Lon=9.83396 + +5 +00:00:00,800 --> 00:00:01,000 +290 m +17:47:25 Lat=49.79479 Lon=9.83394 diff --git a/gpsbabel/reference/track/gtrnctr-readcp.gpx b/gpsbabel/reference/track/gtrnctr-readcp.gpx new file mode 100644 index 000000000..fe6d93fbc --- /dev/null +++ b/gpsbabel/reference/track/gtrnctr-readcp.gpx @@ -0,0 +1,220 @@ + + + + + + LAP001 + LAP001 + LAP001 + + + 231.000000 + + Tp Gen + Not Gen + Tp Gen + Generic + + + 232.000000 + + Tp Sum + Not Sum + Tp Sum + Summit + + + 232.000000 + + Tp Val + Not Val + Tp Val + Valley + + + 232.000000 + + Tp Wat + Not Wat + Tp Wat + Water + + + 232.000000 + + Tp Foo + Not Foo + Tp Foo + Food + + + 232.000000 + + Tp Dan + Not Dan + Tp Dan + Danger + + + 234.000000 + + Tp Lef + Not Lef + Tp Lef + Left + + + 233.000000 + + Tp Rig + Not Rig + Tp Rig + Right + + + 233.000000 + + Tp Str + Not Str + Tp Str + Straight + + + 233.000000 + + Tp Fir + Not Fir + Tp Fir + First Aid + + + 230.000000 + + Tp 4th + Not 4th + Tp 4th + 4th Category + + + 228.000000 + + Tp 3th + Not 3rd + Tp 3th + 3rd Category + + + 224.000000 + + Tp 2nd + Not 2nd + Tp 2nd + 2nd Category + + + 224.000000 + + Tp 1st + Not 1st + Tp 1st + 1st Category + + + 226.000000 + + Tp Hor + Not Hor + Tp Hor + Hors Category + + + 225.000000 + + Tp Spr + Not Spr + Tp Spr + Sprint + + + Test CP Reading + + + 231.000000 + + + + 231.000000 + + + + 231.000000 + + + + 232.000000 + + + + 232.000000 + + + + 232.000000 + + + + 232.000000 + + + + 232.000000 + + + + 234.000000 + + + + 233.000000 + + + + 233.000000 + + + + 233.000000 + + + + 230.000000 + + + + 228.000000 + + + + 224.000000 + + + + 224.000000 + + + + 226.000000 + + + + 225.000000 + + + + + diff --git a/gpsbabel/reference/track/gtrnctr-readcp.tcx b/gpsbabel/reference/track/gtrnctr-readcp.tcx new file mode 100644 index 000000000..f09771c1d --- /dev/null +++ b/gpsbabel/reference/track/gtrnctr-readcp.tcx @@ -0,0 +1,388 @@ + + + + + + + Test CP Reading + + + + + + + Test CP Reading + + 309.9 + 207.872342345229 + + 28.3899562951997 + -16.5815234184265 + + + 28.3897769635538 + -16.5820491313934 + + Active + + + + + + 28.389956 + -16.581523 + + 231 + 0 + Absent + + + + + 28.389950 + -16.581551 + + 231 + 2.78552429082476 + Absent + + + + + 28.389900 + -16.581539 + + 231 + 8.46401259709588 + Absent + + + + + 28.389919 + -16.581369 + + 232 + 25.2160839556801 + Absent + + + + + 28.390003 + -16.581287 + + 232 + 37.536598150474 + Absent + + + + + 28.389985 + -16.581202 + + 232 + 46.1852716217043 + Absent + + + + + 28.390003 + -16.581105 + + 232 + 55.8547825200545 + Absent + + + + + 28.389994 + -16.581019 + + 232 + 64.3105241299902 + Absent + + + + + 28.389900 + -16.581051 + + 234 + 75.26038211514 + Absent + + + + + 28.389909 + -16.581191 + + 233 + 88.9351471352528 + Absent + + + + + 28.389890 + -16.581309 + + 233 + 100.661161922849 + Absent + + + + + 28.389871 + -16.581438 + + 233 + 113.420447740461 + Absent + + + + + 28.389881 + -16.581663 + + 230 + 135.470349678032 + Absent + + + + + 28.389852 + -16.581813 + + 228 + 150.486980256282 + Absent + + + + + 28.389815 + -16.581985 + + 224 + 167.78435337889 + Absent + + + + + 28.389834 + -16.582156 + + 224 + 184.695864453439 + Absent + + + + + 28.389768 + -16.582199 + + 226 + 193.151621872271 + Absent + + + + + 28.389777 + -16.582049 + + 225 + 207.872342345229 + Absent + + + + Tp Gen + + + 28.389956 + -16.581523 + + 231 + Generic + Not Gen + + + Tp Sum + + + 28.389919 + -16.581369 + + 232 + Summit + Not Sum + + + Tp Val + + + 28.390003 + -16.581287 + + 232 + Valley + Not Val + + + Tp Wat + + + 28.389985 + -16.581202 + + 232 + Water + Not Wat + + + Tp Foo + + + 28.390003 + -16.581105 + + 232 + Food + Not Foo + + + Tp Dan + + + 28.389994 + -16.581019 + + 232 + Danger + Not Dan + + + Tp Lef + + + 28.389900 + -16.581051 + + 234 + Left + Not Lef + + + Tp Rig + + + 28.389909 + -16.581191 + + 233 + Right + Not Rig + + + Tp Str + + + 28.389890 + -16.581309 + + 233 + Straight + Not Str + + + Tp Fir + + + 28.389871 + -16.581438 + + 233 + First Aid + Not Fir + + + Tp 4th + + + 28.389881 + -16.581663 + + 230 + 4th Category + Not 4th + + + Tp 3th + + + 28.389852 + -16.581813 + + 228 + 3rd Category + Not 3rd + + + Tp 2nd + + + 28.389815 + -16.581985 + + 224 + 2nd Category + Not 2nd + + + Tp 1st + + + 28.389834 + -16.582156 + + 224 + 1st Category + Not 1st + + + Tp Hor + + + 28.389768 + -16.582199 + + 226 + Hors Category + Not Hor + + + Tp Spr + + + 28.389777 + -16.582049 + + 225 + Sprint + Not Spr + + + + diff --git a/gpsbabel/reference/track/gtrnctr_power-kml.kml b/gpsbabel/reference/track/gtrnctr_power-kml.kml index 2b893313b..00bd762ae 100644 --- a/gpsbabel/reference/track/gtrnctr_power-kml.kml +++ b/gpsbabel/reference/track/gtrnctr_power-kml.kml @@ -3,28 +3,26 @@ xmlns:gx="http://www.google.com/kml/ext/2.2"> GPS device - - - Heart Rate - - - Cadence - - - Power - - + + + 2010-05-28T01:16:36Z + 2010-05-28T02:41:44Z + + -122.139608 + 37.382794 + 19819.321245 + - - + + @@ -113,6 +111,17 @@ 6 + + + Heart Rate + + + Cadence + + + Power + + Waypoints @@ -25688,14 +25697,5 @@ - - - 2010-05-28T01:16:36Z - 2010-05-28T02:41:44Z - - -122.139608 - 37.382794 - 19819.321245 - diff --git a/gpsbabel/reference/track/psittrks.txt b/gpsbabel/reference/track/psittrks.txt old mode 100755 new mode 100644 diff --git a/gpsbabel/reference/track/segmented_tracks-track.kml b/gpsbabel/reference/track/segmented_tracks-track.kml index 90b0f0288..2b1147b72 100644 --- a/gpsbabel/reference/track/segmented_tracks-track.kml +++ b/gpsbabel/reference/track/segmented_tracks-track.kml @@ -3,17 +3,26 @@ xmlns:gx="http://www.google.com/kml/ext/2.2"> GPS device + + + 2007-07-27T05:24:05Z + 2007-07-27T05:35:00Z + + -86.841461 + 35.831217 + 1944.793167 + - - + + @@ -106,11 +115,11 @@ Tracks No Times - + Distance 1.1 mi - Min Alt 621371.192 mi + Min Alt 0.000 ft Max Alt 0.000 ft ]]> @@ -118,7 +127,7 @@ Points No Times-0 - + Longitude: -86.844140 @@ -138,7 +147,7 @@ No Times-1 - + Longitude: -86.843587 @@ -158,7 +167,7 @@ No Times-2 - + Longitude: -86.843869 @@ -178,7 +187,7 @@ No Times-3 - + Longitude: -86.843399 @@ -198,7 +207,7 @@ No Times-4 - + Longitude: -86.843647 @@ -218,7 +227,7 @@ No Times-5 - + Longitude: -86.843137 @@ -238,7 +247,7 @@ No Times-6 - + Longitude: -86.842846 @@ -258,7 +267,7 @@ No Times-7 - + Longitude: -86.842592 @@ -278,7 +287,7 @@ No Times-8 - + Longitude: -86.842084 @@ -298,7 +307,7 @@ No Times-9 - + Longitude: -86.842528 @@ -318,7 +327,7 @@ No Times-10 - + Longitude: -86.841917 @@ -338,7 +347,7 @@ No Times-11 - + Longitude: -86.841882 @@ -358,7 +367,7 @@ No Times-12 - + Longitude: -86.841275 @@ -378,7 +387,7 @@ No Times-13 - + Longitude: -86.840954 @@ -398,7 +407,7 @@ No Times-14 - + Longitude: -86.840765 @@ -418,7 +427,7 @@ No Times-15 - + Longitude: -86.840254 @@ -438,7 +447,7 @@ No Times-16 - + Longitude: -86.840499 @@ -458,7 +467,7 @@ No Times-17 - + Longitude: -86.840954 @@ -478,7 +487,7 @@ No Times-18 - + Longitude: -86.839683 @@ -498,7 +507,7 @@ No Times-19 - + Longitude: -86.840327 @@ -518,7 +527,7 @@ No Times-20 - + Longitude: -86.839510 @@ -538,7 +547,7 @@ No Times-21 - + Longitude: -86.839451 @@ -558,7 +567,7 @@ No Times-22 - + Longitude: -86.838782 @@ -584,17 +593,11 @@ 1 - -86.844140,35.826146 -86.844140,35.826146 -86.843587,35.824859 - -86.843587,35.824859 - -86.843869,35.825508 -86.843869,35.825508 -86.843399,35.825659 - -86.843399,35.825659 -86.843647,35.826201 - -86.843647,35.826201 - -86.843137,35.825023 -86.843137,35.825023 @@ -602,8 +605,6 @@ 1 -86.842846,35.825765 - -86.842846,35.825765 - -86.842592,35.825213 -86.842592,35.825213 @@ -611,14 +612,9 @@ 1 -86.842084,35.825410 - -86.842084,35.825410 - -86.842528,35.826530 -86.842528,35.826530 -86.841917,35.826228 - -86.841917,35.826228 -86.841882,35.826753 - -86.841882,35.826753 - -86.841275,35.825879 -86.841275,35.825879 @@ -626,29 +622,19 @@ 1 -86.840954,35.826506 - -86.840954,35.826506 - -86.840765,35.826053 -86.840765,35.826053 -86.840254,35.826187 - -86.840254,35.826187 - -86.840499,35.826665 -86.840499,35.826665 -86.840954,35.826506 - -86.840954,35.826506 1 -86.839683,35.826441 - -86.839683,35.826441 - -86.840327,35.827349 -86.840327,35.827349 -86.839510,35.827134 - -86.839510,35.827134 -86.839451,35.827576 - -86.839451,35.827576 - -86.838782,35.826744 -86.838782,35.826744 @@ -709,11 +695,11 @@ No Times - + Distance 1.1 mi - Min Alt 621371.192 mi + Min Alt 0.000 ft Max Alt 0.000 ft ]]> @@ -721,7 +707,7 @@ Points No Times-0 - + Longitude: -86.844140 @@ -741,7 +727,7 @@ No Times-1 - + Longitude: -86.843587 @@ -761,7 +747,7 @@ No Times-2 - + Longitude: -86.843869 @@ -781,7 +767,7 @@ No Times-3 - + Longitude: -86.843399 @@ -801,7 +787,7 @@ No Times-4 - + Longitude: -86.843647 @@ -821,7 +807,7 @@ No Times-5 - + Longitude: -86.843137 @@ -841,7 +827,7 @@ No Times-6 - + Longitude: -86.842846 @@ -861,7 +847,7 @@ No Times-7 - + Longitude: -86.842592 @@ -881,7 +867,7 @@ No Times-8 - + Longitude: -86.842084 @@ -901,7 +887,7 @@ No Times-9 - + Longitude: -86.842528 @@ -921,7 +907,7 @@ No Times-10 - + Longitude: -86.841917 @@ -941,7 +927,7 @@ No Times-11 - + Longitude: -86.841882 @@ -961,7 +947,7 @@ No Times-12 - + Longitude: -86.841275 @@ -981,7 +967,7 @@ No Times-13 - + Longitude: -86.840954 @@ -1001,7 +987,7 @@ No Times-14 - + Longitude: -86.840765 @@ -1021,7 +1007,7 @@ No Times-15 - + Longitude: -86.840254 @@ -1041,7 +1027,7 @@ No Times-16 - + Longitude: -86.840499 @@ -1061,7 +1047,7 @@ No Times-17 - + Longitude: -86.840954 @@ -1081,7 +1067,7 @@ No Times-18 - + Longitude: -86.839683 @@ -1101,7 +1087,7 @@ No Times-19 - + Longitude: -86.840327 @@ -1121,7 +1107,7 @@ No Times-20 - + Longitude: -86.839510 @@ -1141,7 +1127,7 @@ No Times-21 - + Longitude: -86.839451 @@ -1161,7 +1147,7 @@ No Times-22 - + Longitude: -86.838782 @@ -1187,26 +1173,18 @@ 1 - -86.844140,35.826146 -86.844140,35.826146 -86.843587,35.824859 - -86.843587,35.824859 - -86.843869,35.825508 -86.843869,35.825508 -86.843399,35.825659 - -86.843399,35.825659 - -86.843647,35.826201 -86.843647,35.826201 -86.843137,35.825023 - -86.843137,35.825023 1 -86.842846,35.825765 - -86.842846,35.825765 - -86.842592,35.825213 -86.842592,35.825213 @@ -1214,44 +1192,29 @@ 1 -86.842084,35.825410 - -86.842084,35.825410 - -86.842528,35.826530 -86.842528,35.826530 -86.841917,35.826228 - -86.841917,35.826228 - -86.841882,35.826753 -86.841882,35.826753 -86.841275,35.825879 - -86.841275,35.825879 1 -86.840954,35.826506 - -86.840954,35.826506 - -86.840765,35.826053 -86.840765,35.826053 -86.840254,35.826187 - -86.840254,35.826187 - -86.840499,35.826665 -86.840499,35.826665 -86.840954,35.826506 - -86.840954,35.826506 1 - -86.839683,35.826441 -86.839683,35.826441 -86.840327,35.827349 - -86.840327,35.827349 - -86.839510,35.827134 -86.839510,35.827134 -86.839451,35.827576 - -86.839451,35.827576 - -86.838782,35.826744 -86.838782,35.826744 @@ -1260,11 +1223,11 @@ With Times - + Distance 1.1 mi - Min Alt 621371.192 mi + Min Alt 0.000 ft Max Alt 0.000 ft Max Speed 0.0 mph Avg Speed 6.1 mph @@ -1280,7 +1243,7 @@ Points With Times-0 - + Longitude: -86.844140 @@ -1303,7 +1266,7 @@ With Times-1 - + Longitude: -86.843587 @@ -1324,7 +1287,7 @@ With Times-2 - + Longitude: -86.843869 @@ -1344,7 +1307,7 @@ With Times-3 - + Longitude: -86.843399 @@ -1364,7 +1327,7 @@ With Times-4 - + Longitude: -86.843647 @@ -1384,7 +1347,7 @@ With Times-5 - + Longitude: -86.843137 @@ -1407,7 +1370,7 @@ With Times-6 - + Longitude: -86.842846 @@ -1428,7 +1391,7 @@ With Times-7 - + Longitude: -86.842592 @@ -1448,7 +1411,7 @@ With Times-8 - + Longitude: -86.842084 @@ -1471,7 +1434,7 @@ With Times-9 - + Longitude: -86.842528 @@ -1492,7 +1455,7 @@ With Times-10 - + Longitude: -86.841917 @@ -1512,7 +1475,7 @@ With Times-11 - + Longitude: -86.841882 @@ -1532,7 +1495,7 @@ With Times-12 - + Longitude: -86.841275 @@ -1552,7 +1515,7 @@ With Times-13 - + Longitude: -86.840954 @@ -1572,7 +1535,7 @@ With Times-14 - + Longitude: -86.840765 @@ -1592,7 +1555,7 @@ With Times-15 - + Longitude: -86.840254 @@ -1612,7 +1575,7 @@ With Times-16 - + Longitude: -86.840499 @@ -1632,7 +1595,7 @@ With Times-17 - + Longitude: -86.840954 @@ -1652,7 +1615,7 @@ With Times-18 - + Longitude: -86.839683 @@ -1672,7 +1635,7 @@ With Times-19 - + Longitude: -86.840327 @@ -1692,7 +1655,7 @@ With Times-20 - + Longitude: -86.839510 @@ -1712,7 +1675,7 @@ With Times-21 - + Longitude: -86.839451 @@ -1732,7 +1695,7 @@ With Times-22 - + Longitude: -86.838782 @@ -1762,70 +1725,47 @@ 1 -86.844140,35.836146 - -86.844140,35.836146 - -86.843587,35.834859 -86.843587,35.834859 -86.843869,35.835508 - -86.843869,35.835508 - -86.843399,35.835659 -86.843399,35.835659 -86.843647,35.836201 - -86.843647,35.836201 - -86.843137,35.835023 -86.843137,35.835023 1 - -86.842846,35.835765 -86.842846,35.835765 -86.842592,35.835213 - -86.842592,35.835213 1 - -86.842084,35.835410 -86.842084,35.835410 -86.842528,35.836530 - -86.842528,35.836530 - -86.841917,35.836228 -86.841917,35.836228 -86.841882,35.836753 - -86.841882,35.836753 - -86.841275,35.835879 -86.841275,35.835879 1 - -86.840954,35.836506 -86.840954,35.836506 -86.840765,35.836053 - -86.840765,35.836053 - -86.840254,35.836187 -86.840254,35.836187 -86.840499,35.836665 - -86.840499,35.836665 - -86.840954,35.836506 -86.840954,35.836506 1 - -86.839683,35.836441 -86.839683,35.836441 -86.840327,35.837349 - -86.840327,35.837349 - -86.839510,35.837134 -86.839510,35.837134 -86.839451,35.837576 - -86.839451,35.837576 - -86.838782,35.836744 -86.838782,35.836744 @@ -1833,14 +1773,5 @@ - - - 2007-07-27T05:24:05Z - 2007-07-27T05:35:00Z - - -86.841461 - 35.831217 - 1944.793167 - diff --git a/gpsbabel/reference/track/segmented_tracks.kml b/gpsbabel/reference/track/segmented_tracks.kml index 9066532b8..3e9d01eb7 100644 --- a/gpsbabel/reference/track/segmented_tracks.kml +++ b/gpsbabel/reference/track/segmented_tracks.kml @@ -3,17 +3,26 @@ xmlns:gx="http://www.google.com/kml/ext/2.2"> GPS device + + + 2007-07-27T05:24:05Z + 2007-07-27T05:35:00Z + + -86.841461 + 35.831217 + 1944.793167 + "), NULL != lcp) { - sp = returnstr + (lcp - lcstr) ; /* becomes --> */ - *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = '-'; *sp++ = '-'; - *lcp = '*'; /* so we wont find it again */ - } - while (lcp = strstr(lcstr, ""), NULL != lcp) { + sp = returnstr + (lcp - lcstr) ; /* becomes */ + sp++; + *sp++ = '!'; + *sp++ = ' '; + *sp++ = ' '; + *sp++ = ' '; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, " */ + sp = returnstr + (lcp - lcstr) ; + sp++; + *sp++ = '!'; + *sp++ = '-'; + *sp++ = '-'; + while ((*sp) && (*sp != '>')) { + sp++; + } + *--sp = '-'; + *--sp = '-'; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, ""), NULL != lcp) { + sp = returnstr + (lcp - lcstr) ; /* becomes */ + *sp++ = ' '; + *sp++ = ' '; + *sp++ = ' '; + *sp++ = ' '; + *sp++ = ' '; + *sp++ = '-'; + *sp++ = '-'; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, "utfstring; - char tag[8]; - unsigned short int taglen = 0; - - if (!in->is_html) - return xstrdup(in->utfstring); - /* - * We only shorten, so just dupe the input buf for space. - */ - - outstring = out = xstrdup(in->utfstring); - - tag[0] = 0; - while (*instr) { - if ((*instr == '<') || (*instr == '&')) { - tag[0] = *instr; - taglen = 0; - } - - if (! tag[0]) { - if (*instr == '\n') { - *out++ = ' '; - do { - instr++; - } while (isspace(*instr)); - continue; - } else { - *out++ = *instr; - } - } - else { - if (taglen < (sizeof(tag)-1)) { - tag[taglen++] = tolower(*instr); - tag[taglen] = 0; - } - } - - if ( ((tag[0] == '<') && (*instr == '>')) || - ((tag[0] == '&') && (*instr == ';')) ) { - if (! strcmp(tag,"&")) - *out++ = '&'; - else if (! strcmp (tag, "<")) - *out++ = '<'; - else if (! strcmp (tag, ">")) - *out++ = '>'; - else if (! strcmp (tag, """)) - *out++ = '"'; - else if (! strcmp (tag, " ")) - *out++ = ' '; - else if (! strcmp (tag, "°")) { - *out++ = 'd'; *out++ = 'e'; *out++ = 'g'; - } - else if ((tag[0]=='<') && (tag[1]=='p')) - *out++ = '\n'; - else if ((tag[0]=='<') && (tag[1]=='b') && (tag[2]=='r')) - *out++ = '\n'; - else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='r')) - *out++ = '\n'; - else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='d')) - *out++ = ' '; - else if ((tag[0]=='<') && (tag[1]=='i') && (tag[2]=='m') && (tag[3]=='g')) { - *out++ = '['; *out++ = 'I'; *out++ = 'M'; *out++ = 'G'; *out++ = ']'; - } - - tag[0] = 0; - } - instr++; - } - *out++ = 0; - return (outstring); + char *outstring, *out; + char *instr = in->utfstring; + char tag[8]; + unsigned short int taglen = 0; + + if (!in->is_html) { + return xstrdup(in->utfstring); + } + /* + * We only shorten, so just dupe the input buf for space. + */ + + outstring = out = xstrdup(in->utfstring); + + tag[0] = 0; + while (*instr) { + if ((*instr == '<') || (*instr == '&')) { + tag[0] = *instr; + taglen = 0; + } + + if (! tag[0]) { + if (*instr == '\n') { + *out++ = ' '; + do { + instr++; + } while (isspace(*instr)); + continue; + } else { + *out++ = *instr; + } + } else { + if (taglen < (sizeof(tag)-1)) { + tag[taglen++] = tolower(*instr); + tag[taglen] = 0; + } + } + + if (((tag[0] == '<') && (*instr == '>')) || + ((tag[0] == '&') && (*instr == ';'))) { + if (! strcmp(tag,"&")) { + *out++ = '&'; + } else if (! strcmp(tag, "<")) { + *out++ = '<'; + } else if (! strcmp(tag, ">")) { + *out++ = '>'; + } else if (! strcmp(tag, """)) { + *out++ = '"'; + } else if (! strcmp(tag, " ")) { + *out++ = ' '; + } else if (! strcmp(tag, "°")) { + *out++ = 'd'; + *out++ = 'e'; + *out++ = 'g'; + } else if ((tag[0]=='<') && (tag[1]=='p')) { + *out++ = '\n'; + } else if ((tag[0]=='<') && (tag[1]=='b') && (tag[2]=='r')) { + *out++ = '\n'; + } else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='r')) { + *out++ = '\n'; + } else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='d')) { + *out++ = ' '; + } else if ((tag[0]=='<') && (tag[1]=='i') && (tag[2]=='m') && (tag[3]=='g')) { + *out++ = '['; + *out++ = 'I'; + *out++ = 'M'; + *out++ = 'G'; + *out++ = ']'; + } + + tag[0] = 0; + } + instr++; + } + *out++ = 0; + return (outstring); } typedef struct { - const char * text; - const char * entity; - int not_html; + const char * text; + const char * entity; + int not_html; } entity_types; -static +static entity_types stdentities[] = { - { "&", "&", 0 }, - { "'", "'", 1 }, - { "<", "<", 0 }, - { ">", ">", 0 }, - { "\"", """, 0 }, - { NULL, NULL, 0 } + { "&", "&", 0 }, + { "'", "'", 1 }, + { "<", "<", 0 }, + { ">", ">", 0 }, + { "\"", """, 0 }, + { NULL, NULL, 0 } }; -static -char * -entitize(const char * str, int is_html) -{ - int elen, ecount, nsecount; - entity_types *ep; - const char * cp; - char * p, * tmp, * xstr; - - int bytes = 0; - int value = 0; - ep = stdentities; - elen = ecount = nsecount = 0; - - /* figure # of entity replacements and additional size. */ - while (ep->text) { - cp = str; - while ((cp = strstr(cp, ep->text)) != NULL) { - elen += strlen(ep->entity) - strlen(ep->text); - ecount++; - cp += strlen(ep->text); - } - ep++; - } - - /* figure the same for other than standard entities (i.e. anything - * that isn't in the range U+0000 to U+007F */ - +static +char * +entitize(const char * str, int is_html) +{ + int elen, ecount, nsecount; + entity_types *ep; + const char * cp; + char * p, * tmp, * xstr; + + int bytes = 0; + int value = 0; + ep = stdentities; + elen = ecount = nsecount = 0; + + /* figure # of entity replacements and additional size. */ + while (ep->text) { + cp = str; + while ((cp = strstr(cp, ep->text)) != NULL) { + elen += strlen(ep->entity) - strlen(ep->text); + ecount++; + cp += strlen(ep->text); + } + ep++; + } + + /* figure the same for other than standard entities (i.e. anything + * that isn't in the range U+0000 to U+007F */ + #if 0 - for ( cp = str; *cp; cp++ ) { - if ( *cp & 0x80 ) { - cet_utf8_to_ucs4( cp, &bytes, &value ); - cp += bytes-1; - elen += sprintf( tmpsub, "&#x%x;", value ) - bytes; - nsecount++; - } - } + for (cp = str; *cp; cp++) { + if (*cp & 0x80) { + cet_utf8_to_ucs4(cp, &bytes, &value); + cp += bytes-1; + elen += sprintf(tmpsub, "&#x%x;", value) - bytes; + nsecount++; + } + } #endif - /* enough space for the whole string plus entity replacements, if any */ - tmp = (char *) xcalloc((strlen(str) + elen + 1), 1); - strcpy(tmp, str); - - /* no entity replacements */ - if (ecount == 0 && nsecount == 0) - return (tmp); - - if ( ecount != 0 ) { - for (ep = stdentities; ep->text; ep++) { - p = tmp; - if (is_html && ep->not_html) { - continue; - } - while ((p = strstr(p, ep->text)) != NULL) { - elen = strlen(ep->entity); - - xstr = xstrdup(p + strlen(ep->text)); - - strcpy(p, ep->entity); - strcpy(p + elen, xstr); - - xfree(xstr); - - p += elen; - } - } - } - - if ( nsecount != 0 ) { - p = tmp; - while (*p) { - if ( *p & 0x80 ) { - cet_utf8_to_ucs4( p, &bytes, &value ); - if ( p[bytes] ) { - xstr = xstrdup( p + bytes ); - } - else { - xstr = NULL; - } - sprintf( p, "&#x%x;", value ); - p = p+strlen(p); - if ( xstr ) { - strcpy( p, xstr ); - xfree(xstr); - } - } - else { - p++; - } - } - } - return (tmp); + /* enough space for the whole string plus entity replacements, if any */ + tmp = (char *) xcalloc((strlen(str) + elen + 1), 1); + strcpy(tmp, str); + + /* no entity replacements */ + if (ecount == 0 && nsecount == 0) { + return (tmp); + } + + if (ecount != 0) { + for (ep = stdentities; ep->text; ep++) { + p = tmp; + if (is_html && ep->not_html) { + continue; + } + while ((p = strstr(p, ep->text)) != NULL) { + elen = strlen(ep->entity); + + xstr = xstrdup(p + strlen(ep->text)); + + strcpy(p, ep->entity); + strcpy(p + elen, xstr); + + xfree(xstr); + + p += elen; + } + } + } + + if (nsecount != 0) { + p = tmp; + while (*p) { + if (*p & 0x80) { + cet_utf8_to_ucs4(p, &bytes, &value); + if (p[bytes]) { + xstr = xstrdup(p + bytes); + } else { + xstr = NULL; + } + sprintf(p, "&#x%x;", value); + p = p+strlen(p); + if (xstr) { + strcpy(p, xstr); + xfree(xstr); + } + } else { + p++; + } + } + } + return (tmp); } /* * Public callers for the above to hide the absence of &apos from HTML */ -char * xml_entitize(const char * str) +char * xml_entitize(const char * str) { - return entitize(str, 0); + return entitize(str, 0); } -char * html_entitize(const char * str) +char * html_entitize(const char * str) { - return entitize(str, 1); + return entitize(str, 1); } /* * xml_tag utilities */ -xml_tag *xml_next( xml_tag *root, xml_tag *cur ) -{ - if ( cur->child ) { - cur = cur->child; - } - else if ( cur->sibling ) { - cur = cur->sibling; - } - else { - cur = cur->parent; - if ( cur == root ) { - cur = NULL; - } - if ( cur ) { - cur = cur->sibling; - } - } - return cur; +xml_tag *xml_next(xml_tag *root, xml_tag *cur) +{ + if (cur->child) { + cur = cur->child; + } else if (cur->sibling) { + cur = cur->sibling; + } else { + cur = cur->parent; + if (cur == root) { + cur = NULL; + } + if (cur) { + cur = cur->sibling; + } + } + return cur; } -xml_tag *xml_findnext( xml_tag *root, xml_tag *cur, const char *tagname ) +xml_tag *xml_findnext(xml_tag *root, xml_tag *cur, const char *tagname) { - xml_tag *result = cur; - do { - result = xml_next( root, result ); - } while ( result && case_ignore_strcmp( result->tagname, tagname )); - return result; + xml_tag *result = cur; + do { + result = xml_next(root, result); + } while (result && case_ignore_strcmp(result->tagname, tagname)); + return result; } -xml_tag *xml_findfirst( xml_tag *root, const char *tagname ) +xml_tag *xml_findfirst(xml_tag *root, const char *tagname) { - return xml_findnext( root, root, tagname ); + return xml_findnext(root, root, tagname); } -char *xml_attribute( xml_tag *tag, const char *attrname ) +char *xml_attribute(xml_tag *tag, const char *attrname) { - char *result = NULL; - if ( tag->attributes ) { - char **attr = tag->attributes; - while ( attr && *attr ) { - if ( 0 == case_ignore_strcmp( *attr, attrname )) { - result = attr[1]; - break; - } - attr+=2; - } - } - return result; + char *result = NULL; + if (tag->attributes) { + char **attr = tag->attributes; + while (attr && *attr) { + if (0 == case_ignore_strcmp(*attr, attrname)) { + result = attr[1]; + break; + } + attr+=2; + } + } + return result; } char *get_filename(const char *fname) { - char *res, *cb, *cs; - - cb = strrchr(fname, '\\'); - cs = strrchr(fname, '/'); - - if (cb == NULL) res = cs; - else if (cs == NULL) res = cb; - else res = (cs > cb) ? cs : cb; - - return (res == NULL) ? (char *) fname : ++res; + char *res, *cb, *cs; + + cb = strrchr(fname, '\\'); + cs = strrchr(fname, '/'); + + if (cb == NULL) { + res = cs; + } else if (cs == NULL) { + res = cb; + } else { + res = (cs > cb) ? cs : cb; + } + + return (res == NULL) ? (char *) fname : ++res; } /* bit manipulation functions */ @@ -1788,8 +1886,8 @@ char *get_filename(const char *fname) */ void gb_setbit(void *buf, const gbuint32 nr) { - unsigned char *bytes = (unsigned char *) buf; - bytes[nr / 8] |= (1 << (nr % 8)); + unsigned char *bytes = (unsigned char *) buf; + bytes[nr / 8] |= (1 << (nr % 8)); } /* @@ -1797,9 +1895,9 @@ void gb_setbit(void *buf, const gbuint32 nr) */ char gb_getbit(const void *buf, const gbuint32 nr) { - const unsigned char *bytes = (const unsigned char *) buf; - return (bytes[nr / 8] & (1 << (nr % 8))); - + const unsigned char *bytes = (const unsigned char *) buf; + return (bytes[nr / 8] & (1 << (nr % 8))); + } /* @@ -1807,13 +1905,13 @@ char gb_getbit(const void *buf, const gbuint32 nr) */ void *gb_int2ptr(const int i) { - union { - void *p; - int i; - } x = { NULL }; + union { + void *p; + int i; + } x = { NULL }; - x.i = i; - return x.p; + x.i = i; + return x.p; } /* @@ -1821,10 +1919,10 @@ void *gb_int2ptr(const int i) */ int gb_ptr2int(const void *p) { - union { - const void *p; - int i; - } x = { p }; + union { + const void *p; + int i; + } x = { p }; - return x.i; + return x.i; } diff --git a/gpsbabel/util_crc.c b/gpsbabel/util_crc.c index cba43adcb..4e91871d2 100644 --- a/gpsbabel/util_crc.c +++ b/gpsbabel/util_crc.c @@ -19,65 +19,64 @@ */ -static unsigned long crc32_table[256] = -{ - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, - 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, - 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, - 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, - 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, - 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, - 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, - 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, - 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, - 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, - 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, - 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, - 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +static unsigned long crc32_table[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; unsigned long get_crc32(const void * data, int datalen) { - unsigned long crc = 0xFFFFFFFF; - const unsigned char * cp = (unsigned char *)data; + unsigned long crc = 0xFFFFFFFF; + const unsigned char * cp = (unsigned char *)data; - while (cp < ((unsigned char *)data + datalen)) { - crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; - cp++; - } + while (cp < ((unsigned char *)data + datalen)) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; + cp++; + } - return (crc ^ 0xFFFFFFFF); + return (crc ^ 0xFFFFFFFF); } /* @@ -86,11 +85,11 @@ get_crc32(const void * data, int datalen) unsigned long get_crc32_s(const void *data) { - unsigned long crc = 0xFFFFFFFF; - const unsigned char* cp = (unsigned char *)data; + unsigned long crc = 0xFFFFFFFF; + const unsigned char* cp = (unsigned char *)data; - for (;*cp;cp++) { - crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; - } - return (crc ^ 0xFFFFFFFF); + for (; *cp; cp++) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; + } + return (crc ^ 0xFFFFFFFF); } diff --git a/gpsbabel/uuid.c b/gpsbabel/uuid.c index cba1d65ff..9ad956fb4 100755 --- a/gpsbabel/uuid.c +++ b/gpsbabel/uuid.c @@ -23,15 +23,15 @@ void gb_uuid_generate(uuid_t uu) { - unsigned char *cp; - int i; - for (cp = uu, i = 0; i < 16; i++) { - if (getenv("GPSBABEL_FREEZE_TIME")) { - static unsigned char blech = 0; - *cp++ = blech++; - } else { - *cp++ ^= (rand() >> 7) & 0xFF; - } - } + unsigned char *cp; + int i; + for (cp = uu, i = 0; i < 16; i++) { + if (getenv("GPSBABEL_FREEZE_TIME")) { + static unsigned char blech = 0; + *cp++ = blech++; + } else { + *cp++ ^= (rand() >> 7) & 0xFF; + } + } } diff --git a/gpsbabel/uuid.h b/gpsbabel/uuid.h old mode 100755 new mode 100644 diff --git a/gpsbabel/v900.c b/gpsbabel/v900.c index 6eae4643f..7c894fcb7 100644 --- a/gpsbabel/v900.c +++ b/gpsbabel/v900.c @@ -1,4 +1,4 @@ -/* +/* Support for Columbus/Visiontac V900 csv format This format pads fields with NULL up to a fixed per field length. Because of that, and because xcsv does not allows a regex as a field delimiter, @@ -40,17 +40,17 @@ Two modes are available: basic and advanced. The following two examples show "*" where null appears. -------basic mode - start------------------------- +------basic mode - start------------------------- INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,VOX 1*****,T,090404,063401,31.765931N,035.206969E,821**,0***,0**,********* 2*****,T,090404,063402,31.765931N,035.206969E,821**,0***,0**,********* 3*****,T,090404,063403,31.765933N,035.206971E,821**,0***,0**,********* 4*****,T,090404,063404,31.765933N,035.206971E,822**,0***,0**,********* 5*****,T,090404,063407,31.765934N,035.206971E,824**,0***,0**,********* -------basic mode - end--------------------------- +------basic mode - end--------------------------- -------advanced mode - start------------------------- +------advanced mode - start------------------------- INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,FIX MODE,VALID,PDOP,HDOP,VDOP,VOX 1*****,T,090204,055722,31.768380N,035.209656E,149**,0***,0**,3D,SPS ,2.6**,2.4**,1.0**,********* 2*****,T,090204,055723,31.768380N,035.209656E,149**,0***,0**,3D,SPS ,2.5**,2.3**,0.9**,********* @@ -65,9 +65,9 @@ INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,FIX MODE,VAL 11****,T,090204,055739,31.768338N,035.209991E,155**,0***,0**,3D,SPS ,2.5**,2.3**,0.9**,********* 42****,C,090724,162320,31.763841N,035.205461E,788**,9***,344,3D,SPS ,1.2**,0.9**,0.8**,********* 121***,V,090724,162502,31.769619N,035.208964E,786**,16**,306,3D,SPS ,1.1**,0.8**,0.8**,VOX00003* -------advanced mode - end--------------------------- +------advanced mode - end--------------------------- -for a little more info, see structures: +for a little more info, see structures: one_line_advanced_mode, one_line_basic_mode, one_line_common_start. ******************************************************************************/ @@ -76,70 +76,67 @@ for a little more info, see structures: #include #if _MSC_VER - #define __func__ __FUNCTION__ +#define __func__ __FUNCTION__ #endif /* the start of each record (line) is common to both advanced and basic mode. it will be parsed by a single common code. hence, it will be easier and clearer to have a common structure for it. */ -struct one_line_common_start -{ - char index[6]; /* record number */ - char comma1; /* ',' */ - char tag; /* tag type. T=trackpoint. TODO: more options??? */ - char comma2; /* ',' */ - char date[6]; /* YYMMDD. YY=09 is 2009. */ - char comma3; /* ',' */ - char time[6]; /* HHMMSS */ - char comma4; /* ',' */ - char latitude_num[9]; /* example: "31.768380" */ - char latitude_NS; /* 'N' or 'S' */ - char comma5; /* ',' */ - char longitude_num[10]; /* example: "035.209656" */ - char longitude_EW; /* 'E' or 'W' */ - char comma6; /* ',' */ - char height[5]; /* Altitude in meters. +struct one_line_common_start { + char index[6]; /* record number */ + char comma1; /* ',' */ + char tag; /* tag type. T=trackpoint. TODO: more options??? */ + char comma2; /* ',' */ + char date[6]; /* YYMMDD. YY=09 is 2009. */ + char comma3; /* ',' */ + char time[6]; /* HHMMSS */ + char comma4; /* ',' */ + char latitude_num[9]; /* example: "31.768380" */ + char latitude_NS; /* 'N' or 'S' */ + char comma5; /* ',' */ + char longitude_num[10]; /* example: "035.209656" */ + char longitude_EW; /* 'E' or 'W' */ + char comma6; /* ',' */ + char height[5]; /* Altitude in meters. * (not corrected to WGS84 ??) */ - char comma7; /* ',' */ - char speed[4]; /* speed in km/h. no decimal point. */ - char comma8; /* ',' */ - char heading[3]; /* heading in degrees */ - char comma9; /* ',' */ + char comma7; /* ',' */ + char speed[4]; /* speed in km/h. no decimal point. */ + char comma8; /* ',' */ + char heading[3]; /* heading in degrees */ + char comma9; /* ',' */ }; /* this structure holds one record (line) in advanced logging mode. advanced mode lines looks like this ('*' means NULL): 1717**,T,090204,062634,31.765528N,035.207730E,772**,0***,0**,2D,SPS ,2.1**,1.9**,1.0**,********* */ -struct one_line_advanced_mode -{ - struct one_line_common_start common; - char fixmode[2]; /* "2D" or "3D" */ - char comma10; /* ',' */ - char valid[4]; /* "SPS " or "DGPS" */ - char comma11; /* ',' */ - char pdop[5]; - char comma12; /* ',' */ - char hdop[5]; - char comma13; /* ',' */ - char vdop[5]; - char comma14; /* ',' */ - char vox[9]; /* voicetag recorded */ - char cr; /* '\r' */ - char lf; /* '\n' */ +struct one_line_advanced_mode { + struct one_line_common_start common; + char fixmode[2]; /* "2D" or "3D" */ + char comma10; /* ',' */ + char valid[4]; /* "SPS " or "DGPS" */ + char comma11; /* ',' */ + char pdop[5]; + char comma12; /* ',' */ + char hdop[5]; + char comma13; /* ',' */ + char vdop[5]; + char comma14; /* ',' */ + char vox[9]; /* voicetag recorded */ + char cr; /* '\r' */ + char lf; /* '\n' */ }; /* this structure holds one record (line) in basic logging mode. basic mode lines looks like this ('*' means NULL): 1*****,T,090404,063401,31.765931N,035.206969E,821**,0***,0**,********* */ -struct one_line_basic_mode -{ - struct one_line_common_start common; - char vox[9]; /* voicetag recorded */ - char cr; /* '\r' */ - char lf; /* '\n' */ +struct one_line_basic_mode { + struct one_line_common_start common; + char vox[9]; /* voicetag recorded */ + char cr; /* '\r' */ + char lf; /* '\n' */ }; @@ -149,36 +146,38 @@ static FILE* fin = NULL; static void v900_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (global_opts.debug_level < 1) { - return; - } + if (global_opts.debug_level < 1) { + return; + } - va_start (ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); } static void v900_rd_init(const char *fname) { - v900_log("%s(%s)\n",__func__,fname); - /* note: file is opened in binary mode, since lines end with \r\n, and in windows text mode - that will be translated to a single \n, making the line len one character shorter than - on linux machines. - */ - fin = fopen(fname,"rb"); - if (!fin) - fatal("v900: could not open '%s'.\n", fname); + v900_log("%s(%s)\n",__func__,fname); + /* note: file is opened in binary mode, since lines end with \r\n, and in windows text mode + that will be translated to a single \n, making the line len one character shorter than + on linux machines. + */ + fin = fopen(fname,"rb"); + if (!fin) { + fatal("v900: could not open '%s'.\n", fname); + } } static void v900_rd_deinit(void) { - v900_log("%s\n",__func__); - if (fin) - fclose(fin); + v900_log("%s\n",__func__); + if (fin) { + fclose(fin); + } } @@ -186,210 +185,206 @@ v900_rd_deinit(void) static time_t bintime2utc(int date, int time) { - struct tm gpstime; - - gpstime.tm_sec = time % 100; - time /= 100; - gpstime.tm_min = time % 100; - time /= 100; - gpstime.tm_hour = time; - - /* - * GPS year: 2000+; struct tm year: 1900+ - * GPS month: 1-12, struct tm month: 0-11 - */ - gpstime.tm_mday = date % 100; - date /= 100; - gpstime.tm_mon = date % 100 - 1; - date /= 100; - gpstime.tm_year = date + 100; - - return(mkgmtime(&gpstime)); + struct tm gpstime; + + gpstime.tm_sec = time % 100; + time /= 100; + gpstime.tm_min = time % 100; + time /= 100; + gpstime.tm_hour = time; + + /* + * GPS year: 2000+; struct tm year: 1900+ + * GPS month: 1-12, struct tm month: 0-11 + */ + gpstime.tm_mday = date % 100; + date /= 100; + gpstime.tm_mon = date % 100 - 1; + date /= 100; + gpstime.tm_year = date + 100; + + return(mkgmtime(&gpstime)); } static void v900_read(void) { - /* use line buffer large enough to hold either basic or advanced mode lines. */ - union - { - struct one_line_basic_mode bas; - struct one_line_advanced_mode adv; - char text[200]; /* used to read the header line, which is normal text */ - } line; - int is_advanced_mode = 0; - int lc = 0; - route_head *track; - - v900_log("%s\n",__func__); - -/* -Basic mode: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,VOX -Advanced mode: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,FIX MODE,VALID,PDOP,HDOP,VDOP,VOX -*/ - /* first, determine if this is advanced mode by reading the first line. + /* use line buffer large enough to hold either basic or advanced mode lines. */ + union { + struct one_line_basic_mode bas; + struct one_line_advanced_mode adv; + char text[200]; /* used to read the header line, which is normal text */ + } line; + int is_advanced_mode = 0; + int lc = 0; + route_head *track; + + v900_log("%s\n",__func__); + + /* + Basic mode: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,VOX + Advanced mode: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,FIX MODE,VALID,PDOP,HDOP,VDOP,VOX + */ + /* first, determine if this is advanced mode by reading the first line. since the first line does not contain any nulls, it can be safely read by fgets(). */ - if (!fgets(line.text, sizeof(line), fin)) - fatal("v900: error reading header (first) line from input file\n"); - is_advanced_mode = (NULL != strstr(line.text,"PDOP")); /* PDOP field appears only in advanced mode */ - - v900_log("header line: %s",line.text); - v900_log("is_advance_mode=%d\n",is_advanced_mode); - - track = route_head_alloc(); - track->rte_name = xstrdup("V900 tracklog"); - track->rte_desc = xstrdup("V900 GPS tracklog data"); - track_add_head(track); - - while (1) - { - waypoint *wpt; - char c; - int bad = 0; - int record_len = is_advanced_mode ? sizeof(line.adv) : sizeof(line.bas); - if (fread ( &line, record_len, 1, fin ) != 1) - { - break; - } - lc++; - - /* change all "," characters to NULLs. + if (!fgets(line.text, sizeof(line), fin)) { + fatal("v900: error reading header (first) line from input file\n"); + } + is_advanced_mode = (NULL != strstr(line.text,"PDOP")); /* PDOP field appears only in advanced mode */ + + v900_log("header line: %s",line.text); + v900_log("is_advance_mode=%d\n",is_advanced_mode); + + track = route_head_alloc(); + track->rte_name = xstrdup("V900 tracklog"); + track->rte_desc = xstrdup("V900 GPS tracklog data"); + track_add_head(track); + + while (1) { + waypoint *wpt; + char c; + int bad = 0; + int record_len = is_advanced_mode ? sizeof(line.adv) : sizeof(line.bas); + if (fread(&line, record_len, 1, fin) != 1) { + break; + } + lc++; + + /* change all "," characters to NULLs. so every field is null terminated. */ - bad |= (line.bas.common.comma1 != ','); - bad |= (line.bas.common.comma2 != ','); - bad |= (line.bas.common.comma3 != ','); - bad |= (line.bas.common.comma4 != ','); - bad |= (line.bas.common.comma5 != ','); - bad |= (line.bas.common.comma6 != ','); - bad |= (line.bas.common.comma7 != ','); - bad |= (line.bas.common.comma8 != ','); - bad |= (line.bas.common.comma9 != ','); - - if (bad) { - warning("v900: skipping malformed record at line %d\n", lc); - } - - line.bas.common.comma1 = 0; - line.bas.common.comma2 = 0; - line.bas.common.comma3 = 0; - line.bas.common.comma4 = 0; - line.bas.common.comma5 = 0; - line.bas.common.comma6 = 0; - line.bas.common.comma7 = 0; - line.bas.common.comma8 = 0; - line.bas.common.comma9 = 0; - if(is_advanced_mode) - { - /* change all "," characters to NULLs. - so every field is null terminated. - */ - assert(line.adv.comma10==','); // TODO: abort with fatal() - assert(line.adv.comma11==','); - assert(line.adv.comma12==','); - assert(line.adv.comma13==','); - assert(line.adv.comma14==','); - assert(line.adv.cr=='\r'); - assert(line.adv.lf=='\n'); - line.adv.comma10 = 0; - line.adv.comma11 = 0; - line.adv.comma12 = 0; - line.adv.comma13 = 0; - line.adv.comma14 = 0; - line.adv.cr = 0; /* null terminate vox field */ - - } - else - { - assert(line.bas.cr=='\r'); - assert(line.bas.lf=='\n'); - line.bas.cr = 0; /* null terminate vox field */ - } - - wpt = waypt_new(); - - /* lat is a string in the form: 31.768380N */ - c = line.bas.common.latitude_NS; /* N/S */ - assert(c == 'N' || c == 'S'); - wpt->latitude = atof(line.bas.common.latitude_num); - if (c == 'S') - wpt->latitude = -wpt->latitude; - - /* lon is a string in the form: 035.209656E */ - c = line.bas.common.longitude_EW; /* get E/W */ - assert(c == 'E' || c == 'W'); - line.bas.common.longitude_EW = 0; /* the E will confuse atof(), if not removed */ - wpt->longitude = atof(line.bas.common.longitude_num); - if (c == 'W') - wpt->longitude = -wpt->longitude; - - wpt->altitude = atoi(line.bas.common.height); - - /* handle date/time fields */ - { - int date, time; - date = atoi(line.bas.common.date); - time = atoi(line.bas.common.time); - wpt->creation_time = bintime2utc(date, time); - } - - wpt->speed = KPH_TO_MPS(atoi(line.bas.common.speed)); - wpt->wpt_flags.speed = 1; - - wpt->course = atoi(line.bas.common.heading); - wpt->wpt_flags.course = 1; - - if(is_advanced_mode) - { - wpt->hdop = atof(line.adv.hdop); - wpt->vdop = atof(line.adv.vdop); - wpt->pdop = atof(line.adv.pdop); - - /* handle fix mode (2d, 3d, etc.) */ - if (!strcmp(line.adv.valid,"DGPS")) - wpt->fix = fix_dgps; - else if (!strcmp(line.adv.fixmode,"3D")) - wpt->fix = fix_3d; - else if (!strcmp(line.adv.fixmode,"2D")) - wpt->fix = fix_2d; - else - /* possible values: fix_unknown,fix_none,fix_2d,fix_3d,fix_dgps,fix_pps */ - wpt->fix = fix_unknown; - } - - track_add_wpt(track, wpt); - if(line.bas.common.tag != 'T') - { - waypoint *wpt2; - assert(line.bas.common.tag == 'C' || line.bas.common.tag == 'V'); - wpt2 = waypt_dupe(wpt); - if(line.bas.common.tag == 'V') // waypoint with voice recording? - { - char vox_file_name[sizeof(line.adv.vox)+5]; - const char *vox = is_advanced_mode ? line.adv.vox : line.bas.vox; - assert(vox[0] != '\0'); - strcpy(vox_file_name,vox); - strcat(vox_file_name,".WAV"); - wpt2->shortname = xstrdup(vox_file_name); - wpt2->description = xstrdup(vox_file_name); - waypt_add_url(wpt2, xstrdup(vox_file_name), xstrdup(vox_file_name)); - } - waypt_add(wpt2); - } - } + bad |= (line.bas.common.comma1 != ','); + bad |= (line.bas.common.comma2 != ','); + bad |= (line.bas.common.comma3 != ','); + bad |= (line.bas.common.comma4 != ','); + bad |= (line.bas.common.comma5 != ','); + bad |= (line.bas.common.comma6 != ','); + bad |= (line.bas.common.comma7 != ','); + bad |= (line.bas.common.comma8 != ','); + bad |= (line.bas.common.comma9 != ','); + + if (bad) { + warning("v900: skipping malformed record at line %d\n", lc); + } + + line.bas.common.comma1 = 0; + line.bas.common.comma2 = 0; + line.bas.common.comma3 = 0; + line.bas.common.comma4 = 0; + line.bas.common.comma5 = 0; + line.bas.common.comma6 = 0; + line.bas.common.comma7 = 0; + line.bas.common.comma8 = 0; + line.bas.common.comma9 = 0; + if (is_advanced_mode) { + /* change all "," characters to NULLs. + so every field is null terminated. + */ + assert(line.adv.comma10==','); // TODO: abort with fatal() + assert(line.adv.comma11==','); + assert(line.adv.comma12==','); + assert(line.adv.comma13==','); + assert(line.adv.comma14==','); + assert(line.adv.cr=='\r'); + assert(line.adv.lf=='\n'); + line.adv.comma10 = 0; + line.adv.comma11 = 0; + line.adv.comma12 = 0; + line.adv.comma13 = 0; + line.adv.comma14 = 0; + line.adv.cr = 0; /* null terminate vox field */ + + } else { + assert(line.bas.cr=='\r'); + assert(line.bas.lf=='\n'); + line.bas.cr = 0; /* null terminate vox field */ + } + + wpt = waypt_new(); + + /* lat is a string in the form: 31.768380N */ + c = line.bas.common.latitude_NS; /* N/S */ + assert(c == 'N' || c == 'S'); + wpt->latitude = atof(line.bas.common.latitude_num); + if (c == 'S') { + wpt->latitude = -wpt->latitude; + } + + /* lon is a string in the form: 035.209656E */ + c = line.bas.common.longitude_EW; /* get E/W */ + assert(c == 'E' || c == 'W'); + line.bas.common.longitude_EW = 0; /* the E will confuse atof(), if not removed */ + wpt->longitude = atof(line.bas.common.longitude_num); + if (c == 'W') { + wpt->longitude = -wpt->longitude; + } + + wpt->altitude = atoi(line.bas.common.height); + + /* handle date/time fields */ + { + int date, time; + date = atoi(line.bas.common.date); + time = atoi(line.bas.common.time); + wpt->creation_time = bintime2utc(date, time); + } + + wpt->speed = KPH_TO_MPS(atoi(line.bas.common.speed)); + wpt->wpt_flags.speed = 1; + + wpt->course = atoi(line.bas.common.heading); + wpt->wpt_flags.course = 1; + + if (is_advanced_mode) { + wpt->hdop = atof(line.adv.hdop); + wpt->vdop = atof(line.adv.vdop); + wpt->pdop = atof(line.adv.pdop); + + /* handle fix mode (2d, 3d, etc.) */ + if (!strcmp(line.adv.valid,"DGPS")) { + wpt->fix = fix_dgps; + } else if (!strcmp(line.adv.fixmode,"3D")) { + wpt->fix = fix_3d; + } else if (!strcmp(line.adv.fixmode,"2D")) { + wpt->fix = fix_2d; + } else + /* possible values: fix_unknown,fix_none,fix_2d,fix_3d,fix_dgps,fix_pps */ + { + wpt->fix = fix_unknown; + } + } + + track_add_wpt(track, wpt); + if (line.bas.common.tag != 'T') { + waypoint *wpt2; + assert(line.bas.common.tag == 'C' || line.bas.common.tag == 'V'); + wpt2 = waypt_dupe(wpt); + if (line.bas.common.tag == 'V') { // waypoint with voice recording? + char vox_file_name[sizeof(line.adv.vox)+5]; + const char *vox = is_advanced_mode ? line.adv.vox : line.bas.vox; + assert(vox[0] != '\0'); + strcpy(vox_file_name,vox); + strcat(vox_file_name,".WAV"); + wpt2->shortname = xstrdup(vox_file_name); + wpt2->description = xstrdup(vox_file_name); + waypt_add_url(wpt2, xstrdup(vox_file_name), xstrdup(vox_file_name)); + } + waypt_add(wpt2); + } + } } ff_vecs_t v900_vecs = { - ff_type_file, - {ff_cap_read, ff_cap_read, ff_cap_none}, /* Read only format. May only read trackpoints and waypoints. */ - v900_rd_init, - NULL, /* wr_init */ - v900_rd_deinit, - NULL, /* wr_deinit */ - v900_read, - NULL, /* write */ - NULL, - NULL, /* args */ - CET_CHARSET_UTF8, 1, /* Could be US-ASCII, since we only read "0-9,A-Z\n\r" */ - {NULL,NULL,NULL,NULL,NULL,NULL} + ff_type_file, + {ff_cap_read, ff_cap_read, ff_cap_none}, /* Read only format. May only read trackpoints and waypoints. */ + v900_rd_init, + NULL, /* wr_init */ + v900_rd_deinit, + NULL, /* wr_deinit */ + v900_read, + NULL, /* write */ + NULL, + NULL, /* args */ + CET_CHARSET_UTF8, 1, /* Could be US-ASCII, since we only read "0-9,A-Z\n\r" */ + {NULL,NULL,NULL,NULL,NULL,NULL} }; diff --git a/gpsbabel/vcf.c b/gpsbabel/vcf.c index 9067a976b..9fee87eaa 100644 --- a/gpsbabel/vcf.c +++ b/gpsbabel/vcf.c @@ -32,23 +32,25 @@ static char *vcf_encrypt = NULL; static arglist_t vcf_args[] = { - { "encrypt", &vcf_encrypt, - "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "encrypt", &vcf_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void wr_init(const char *fname) { - file_out = gbfopen(fname, "w", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } /* @@ -58,86 +60,88 @@ wr_deinit(void) static void vcf_print_utf(const utf_string *s) { - char *p, *p2, *p3; - char *stripped_html; - - if (!s) - return; - - stripped_html = strip_html(s); - p = gstrsub(stripped_html, "\n", "\\n"); - p2 = gstrsub(p, "

", "\\n"); - p3 = gstrsub(p2, ";", "\\;"); - gbfputs(p3, file_out); - xfree(p); - xfree(p2); - xfree(p3); - xfree(stripped_html); + char *p, *p2, *p3; + char *stripped_html; + + if (!s) { + return; + } + + stripped_html = strip_html(s); + p = gstrsub(stripped_html, "\n", "\\n"); + p2 = gstrsub(p, "

", "\\n"); + p3 = gstrsub(p2, ";", "\\;"); + gbfputs(p3, file_out); + xfree(p); + xfree(p2); + xfree(p3); + xfree(stripped_html); } static void vcf_print(const char *s) { - char *p; + char *p; - if (!s) - return; + if (!s) { + return; + } - p = gstrsub(s, "\n", "\\n"); - gbfputs(p, file_out); - xfree(p); + p = gstrsub(s, "\n", "\\n"); + gbfputs(p, file_out); + xfree(p); } static void vcf_disp(const waypoint *wpt) { - int latint, lonint; - - lonint = abs((int) wpt->longitude); - latint = abs((int) wpt->latitude); - - gbfprintf(file_out, "BEGIN:VCARD\nVERSION:3.0\n"); - gbfprintf(file_out, "N:%s;%s;;;\n", wpt->description,wpt->shortname); - gbfprintf(file_out, "ADR:%c%d %06.3f %c%d %06.3f\n", wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint)); - - if (wpt->url) { - gbfprintf(file_out, "URL:%s\n", wpt->url); - } - - gbfprintf(file_out, "NOTE:"); - vcf_print_utf(&wpt->gc_data->desc_short); - gbfprintf(file_out, "\\n"); - vcf_print_utf(&wpt->gc_data->desc_long); - gbfprintf(file_out, "\\n\\nHINT:\\n"); - if (vcf_encrypt) { - char *s = rot13(wpt->gc_data->hint); - vcf_print(s); - xfree(s); - } else { - vcf_print(wpt->gc_data->hint); - } - - gbfprintf(file_out, "\nEND:VCARD\n"); + int latint, lonint; + + lonint = abs((int) wpt->longitude); + latint = abs((int) wpt->latitude); + + gbfprintf(file_out, "BEGIN:VCARD\nVERSION:3.0\n"); + gbfprintf(file_out, "N:%s;%s;;;\n", wpt->description,wpt->shortname); + gbfprintf(file_out, "ADR:%c%d %06.3f %c%d %06.3f\n", wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint)); + + if (wpt->url) { + gbfprintf(file_out, "URL:%s\n", wpt->url); + } + + gbfprintf(file_out, "NOTE:"); + vcf_print_utf(&wpt->gc_data->desc_short); + gbfprintf(file_out, "\\n"); + vcf_print_utf(&wpt->gc_data->desc_long); + gbfprintf(file_out, "\\n\\nHINT:\\n"); + if (vcf_encrypt) { + char *s = rot13(wpt->gc_data->hint); + vcf_print(s); + xfree(s); + } else { + vcf_print(wpt->gc_data->hint); + } + + gbfprintf(file_out, "\nEND:VCARD\n"); } static void data_write(void) { - setshort_length(mkshort_handle, 6); - waypt_disp_all(vcf_disp); + setshort_length(mkshort_handle, 6); + waypt_disp_all(vcf_disp); } ff_vecs_t vcf_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_none, ff_cap_none}, - NULL, - wr_init, - NULL, - wr_deinit, - NULL, - data_write, - NULL, - vcf_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none}, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + vcf_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/vecs.c b/gpsbabel/vecs.c index dee947e16..d1dbf4afd 100644 --- a/gpsbabel/vecs.c +++ b/gpsbabel/vecs.c @@ -1,6 +1,6 @@ /* Describe vectors containing file operations. - + Copyright (C) 2002, 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -28,11 +28,11 @@ #define MYNAME "vecs.c" typedef struct { - ff_vecs_t *vec; - const char *name; - const char *desc; - const char *extension; - const char *parent; + ff_vecs_t *vec; + const char *name; + const char *desc; + const char *extension; + const char *parent; } vecs_t; extern ff_vecs_t an1_vecs; @@ -47,6 +47,7 @@ extern ff_vecs_t coto_vecs; extern ff_vecs_t cst_vecs; extern ff_vecs_t delbin_vecs; extern ff_vecs_t dg100_vecs; +extern ff_vecs_t dg200_vecs; extern ff_vecs_t easygps_vecs; extern ff_vecs_t garmin_vecs; extern ff_vecs_t garmin_txt_vecs; @@ -101,6 +102,7 @@ extern ff_vecs_t saroute_vecs; extern ff_vecs_t shape_vecs; extern ff_vecs_t skytraq_vecs; extern ff_vecs_t skytraq_fvecs; +extern ff_vecs_t miniHomer_vecs; #if CSVFMTS_ENABLED extern ff_vecs_t stmsdf_vecs; #endif @@ -173,1121 +175,1170 @@ extern ff_vecs_t jogmap_vecs; extern ff_vecs_t wintec_tes_vecs; extern ff_vecs_t subrip_vecs; extern ff_vecs_t format_garmin_xt_vecs; +extern ff_vecs_t format_fit_vecs; static vecs_t vec_list[] = { #if CSVFMTS_ENABLED - /* XCSV must be the first entry in this table. */ - { - &xcsv_vecs, - "xcsv", - "? Character Separated Values", - NULL - }, + /* XCSV must be the first entry in this table. */ + { + &xcsv_vecs, + "xcsv", + "? Character Separated Values", + NULL + }, #endif - { - &geo_vecs, - "geo", - "Geocaching.com .loc", - "loc" - }, - { - &gpx_vecs, - "gpx", - "GPX XML", - "gpx" - }, - { - &mag_svecs, - "magellan", - "Magellan serial protocol", - NULL - }, - { - &mag_fvecs, - "magellan", - "Magellan SD files (as for Meridian)", - NULL - }, - { - &magX_fvecs, - "magellanx", - "Magellan SD files (as for eXplorist)", - "upt" - }, - { - &garmin_vecs, - "garmin", - "Garmin serial/USB protocol", - NULL - }, - { - &gdb_vecs, - "gdb", - "Garmin MapSource - gdb", - "gdb" - }, - { - >c_vecs, - "gtrnctr", - "Garmin Training Center", - "xml" - }, - { - &mapsend_vecs, - "mapsend", - "Magellan Mapsend", - NULL - }, - { - &mps_vecs, - "mapsource", - "Garmin MapSource - mps", - "mps" - }, - { - &nmea_vecs, - "nmea", - "NMEA 0183 sentences", - NULL - }, - { - &ozi_vecs, - "ozi", - "OziExplorer", - NULL - }, - { - &pcx_vecs, - "pcx", - "Garmin PCX5", - "pcx" - }, - { - &kml_vecs, - "kml", - "Google Earth (Keyhole) Markup Language", - "kml" - }, + { + &geo_vecs, + "geo", + "Geocaching.com .loc", + "loc" + }, + { + &gpx_vecs, + "gpx", + "GPX XML", + "gpx" + }, + { + &mag_svecs, + "magellan", + "Magellan serial protocol", + NULL + }, + { + &mag_fvecs, + "magellan", + "Magellan SD files (as for Meridian)", + NULL + }, + { + &magX_fvecs, + "magellanx", + "Magellan SD files (as for eXplorist)", + "upt" + }, + { + &garmin_vecs, + "garmin", + "Garmin serial/USB protocol", + NULL + }, + { + &gdb_vecs, + "gdb", + "Garmin MapSource - gdb", + "gdb" + }, + { + >c_vecs, + "gtrnctr", + "Garmin Training Center", + "xml" + }, + { + &mapsend_vecs, + "mapsend", + "Magellan Mapsend", + NULL + }, + { + &mps_vecs, + "mapsource", + "Garmin MapSource - mps", + "mps" + }, + { + &nmea_vecs, + "nmea", + "NMEA 0183 sentences", + NULL + }, + { + &ozi_vecs, + "ozi", + "OziExplorer", + NULL + }, + { + &pcx_vecs, + "pcx", + "Garmin PCX5", + "pcx" + }, + { + &kml_vecs, + "kml", + "Google Earth (Keyhole) Markup Language", + "kml" + }, #if MAXIMAL_ENABLED - { - &gpsutil_vecs, - "gpsutil", - "gpsutil", - NULL - }, - { - &psp_vecs, - "psp", - "MS PocketStreets 2002 Pushpin", - "psp" - }, - { - &lowranceusr_vecs, - "lowranceusr", - "Lowrance USR", - "usr" - }, + { + &gpsutil_vecs, + "gpsutil", + "gpsutil", + NULL + }, + { + &psp_vecs, + "psp", + "MS PocketStreets 2002 Pushpin", + "psp" + }, + { + &lowranceusr_vecs, + "lowranceusr", + "Lowrance USR", + "usr" + }, #if PDBFMTS_ENABLED - { - &cetus_vecs, - "cetus", - "Cetus for Palm/OS", - "pdb" - }, - { - &copilot_vecs, - "copilot", - "CoPilot Flight Planner for Palm/OS", - "pdb" - }, - { - &gpspilot_vecs, - "gpspilot", - "GPSPilot Tracker for Palm/OS", - "pdb" - }, - { - &magnav_vec, - "magnav", - "Magellan NAV Companion for Palm/OS", - "pdb" - }, + { + &cetus_vecs, + "cetus", + "Cetus for Palm/OS", + "pdb" + }, + { + &copilot_vecs, + "copilot", + "CoPilot Flight Planner for Palm/OS", + "pdb" + }, + { + &gpspilot_vecs, + "gpspilot", + "GPSPilot Tracker for Palm/OS", + "pdb" + }, + { + &magnav_vec, + "magnav", + "Magellan NAV Companion for Palm/OS", + "pdb" + }, #endif /* PDBFMTS_ENABLED */ - { - &holux_vecs, - "holux", - "Holux (gm-100) .wpo Format", - "wpo" - }, - { - &tpg_vecs, - "tpg", - "National Geographic Topo .tpg (waypoints)", - "tpg" - }, - { - &tpo2_vecs, - "tpo2", - "National Geographic Topo 2.x .tpo", - "tpo" - }, - { - &tpo3_vecs, - "tpo3", - "National Geographic Topo 3.x/4.x .tpo", - "tpo" - }, - { - &tmpro_vecs, - "tmpro", - "TopoMapPro Places File", - "tmpro" - }, + { + &holux_vecs, + "holux", + "Holux (gm-100) .wpo Format", + "wpo" + }, + { + &tpg_vecs, + "tpg", + "National Geographic Topo .tpg (waypoints)", + "tpg" + }, + { + &tpo2_vecs, + "tpo2", + "National Geographic Topo 2.x .tpo", + "tpo" + }, + { + &tpo3_vecs, + "tpo3", + "National Geographic Topo 3.x/4.x .tpo", + "tpo" + }, + { + &tmpro_vecs, + "tmpro", + "TopoMapPro Places File", + "tmpro" + }, #if PDBFMTS_ENABLED - { - &gcdb_vecs, - "gcdb", - "GeocachingDB for Palm/OS", - "pdb" - }, + { + &gcdb_vecs, + "gcdb", + "GeocachingDB for Palm/OS", + "pdb" + }, #endif - { - &tiger_vecs, - "tiger", - "U.S. Census Bureau Tiger Mapping Service", - NULL - }, - { - &easygps_vecs, - "easygps", - "EasyGPS binary format", - "loc" - }, + { + &tiger_vecs, + "tiger", + "U.S. Census Bureau Tiger Mapping Service", + NULL + }, + { + &easygps_vecs, + "easygps", + "EasyGPS binary format", + "loc" + }, #if PDBFMTS_ENABLED - { - &quovadis_vecs, - "quovadis", - "Quovadis", - "pdb" - }, - { - &gpilots_vecs, - "gpilots", - "GpilotS", - "pdb" - }, + { + &quovadis_vecs, + "quovadis", + "Quovadis", + "pdb" + }, + { + &gpilots_vecs, + "gpilots", + "GpilotS", + "pdb" + }, #endif - { - &saroute_vecs, - "saroute", - "DeLorme Street Atlas Route", - "anr" - }, - { - &navicache_vecs, - "navicache", - "Navicache.com XML", - NULL - }, - { - &coastexp_vecs, - "coastexp", - "CoastalExplorer XML", - NULL - }, - { /* MRCB */ - &psit_vecs, - "psitrex", - "KuDaTa PsiTrex text", - NULL - }, + { + &saroute_vecs, + "saroute", + "DeLorme Street Atlas Route", + "anr" + }, + { + &navicache_vecs, + "navicache", + "Navicache.com XML", + NULL + }, + { + &coastexp_vecs, + "coastexp", + "CoastalExplorer XML", + NULL + }, + { /* MRCB */ + &psit_vecs, + "psitrex", + "KuDaTa PsiTrex text", + NULL + }, #if SHAPELIB_ENABLED - { - &shape_vecs, - "shape", - "ESRI shapefile", - "shp" - }, + { + &shape_vecs, + "shape", + "ESRI shapefile", + "shp" + }, #endif #if PDBFMTS_ENABLED - { - &geoniche_vecs, - "geoniche", - "GeoNiche .pdb", - "pdb" - }, + { + &geoniche_vecs, + "geoniche", + "GeoNiche .pdb", + "pdb" + }, #endif - { - &gpl_vecs, - "gpl", - "DeLorme GPL", - "gpl" - }, - { - &text_vecs, - "text", - "Textual Output", - "txt" - }, - { - &html_vecs, - "html", - "HTML Output", - "html" - }, + { + &gpl_vecs, + "gpl", + "DeLorme GPL", + "gpl" + }, + { + &text_vecs, + "text", + "Textual Output", + "txt" + }, + { + &html_vecs, + "html", + "HTML Output", + "html" + }, #if PDBFMTS_ENABLED - { - &palmdoc_vecs, - "palmdoc", - "PalmDoc Output", - "pdb" - }, + { + &palmdoc_vecs, + "palmdoc", + "PalmDoc Output", + "pdb" + }, #endif - { - &netstumbler_vecs, - "netstumbler", - "NetStumbler Summary File (text)", - NULL - }, - { - &HsaEndeavourNavigator_vecs, - "hsandv", - "HSA Endeavour Navigator export File", - NULL - }, - { - &igc_vecs, - "igc", - "FAI/IGC Flight Recorder Data Format", - NULL - }, - { - &brauniger_iq_vecs, - "baroiq", - "Brauniger IQ Series Barograph Download", - NULL - }, - { - &mtk_vecs, - "mtk", - "MTK Logger (iBlue 747,Qstarz BT-1000,...) download", - NULL - }, - { - &mtk_fvecs, - "mtk-bin", - "MTK Logger (iBlue 747,...) Binary File Format", - "bin" - }, - { - &mtk_m241_vecs, - "m241", - "Holux M-241 (MTK based) download", - NULL - }, - { - &mtk_m241_fvecs, - "m241-bin", - "Holux M-241 (MTK based) Binary File Format", - "bin" - }, + { + &netstumbler_vecs, + "netstumbler", + "NetStumbler Summary File (text)", + NULL + }, + { + &HsaEndeavourNavigator_vecs, + "hsandv", + "HSA Endeavour Navigator export File", + NULL + }, + { + &igc_vecs, + "igc", + "FAI/IGC Flight Recorder Data Format", + NULL + }, + { + &brauniger_iq_vecs, + "baroiq", + "Brauniger IQ Series Barograph Download", + NULL + }, + { + &mtk_vecs, + "mtk", + "MTK Logger (iBlue 747,Qstarz BT-1000,...) download", + NULL + }, + { + &mtk_fvecs, + "mtk-bin", + "MTK Logger (iBlue 747,...) Binary File Format", + "bin" + }, + { + &mtk_m241_vecs, + "m241", + "Holux M-241 (MTK based) download", + NULL + }, + { + &mtk_m241_fvecs, + "m241-bin", + "Holux M-241 (MTK based) Binary File Format", + "bin" + }, #endif // MAXIMAL_ENABLED - { - &wbt_svecs, - "wbt", - "Wintec WBT-100/200 GPS Download", - NULL - }, + { + &wbt_svecs, + "wbt", + "Wintec WBT-100/200 GPS Download", + NULL + }, #if MAXIMAL_ENABLED - { - &vpl_vecs, - "vpl", - "Honda/Acura Navigation System VP Log File Format", - NULL - }, - { - &wbt_fvecs, - "wbt-bin", - "Wintec WBT-100/200 Binary File Format", - "bin" - }, - { - &wbt_fvecs, - "wbt-tk1", - "Wintec WBT-201/G-Rays 2 Binary File Format", - "tk1" - }, - { - &hiketech_vecs, - "hiketech", - "HikeTech", - "gps" - }, - { - &glogbook_vecs, - "glogbook", - "Garmin Logbook XML", - "xml" - }, - { - &vcf_vecs, - "vcard", - "Vcard Output (for iPod)", - "vcf", - }, + { + &vpl_vecs, + "vpl", + "Honda/Acura Navigation System VP Log File Format", + NULL + }, + { + &wbt_fvecs, + "wbt-bin", + "Wintec WBT-100/200 Binary File Format", + "bin" + }, + { + &wbt_fvecs, + "wbt-tk1", + "Wintec WBT-201/G-Rays 2 Binary File Format", + "tk1" + }, + { + &hiketech_vecs, + "hiketech", + "HikeTech", + "gps" + }, + { + &glogbook_vecs, + "glogbook", + "Garmin Logbook XML", + "xml" + }, + { + &vcf_vecs, + "vcard", + "Vcard Output (for iPod)", + "vcf", + }, #if 0 - { - &overlay_vecs, - "overlay", - "Geogrid-Viewer", - "ovl" - }, + { + &overlay_vecs, + "overlay", + "Geogrid-Viewer", + "ovl" + }, #endif - { - &google_vecs, - "google", - "Google Maps XML", - "xml" - }, - { - &maggeo_vecs, - "maggeo", - "Magellan Explorist Geocaching", - "gs" - }, - { - &an1_vecs, - "an1", - "DeLorme .an1 (drawing) file", - "an1" - }, - { - &tomtom_vecs, - "tomtom", - "TomTom POI file (.ov2)", - "ov2" - }, - { - &tef_xml_vecs, - "tef", - "Map&Guide 'TourExchangeFormat' XML", - "xml" - }, + { + &google_vecs, + "google", + "Google Maps XML", + "xml" + }, + { + &maggeo_vecs, + "maggeo", + "Magellan Explorist Geocaching", + "gs" + }, + { + &an1_vecs, + "an1", + "DeLorme .an1 (drawing) file", + "an1" + }, + { + &tomtom_vecs, + "tomtom", + "TomTom POI file (.ov2)", + "ov2" + }, + { + &tef_xml_vecs, + "tef", + "Map&Guide 'TourExchangeFormat' XML", + "xml" + }, #if PDBFMTS_ENABLED - { - &ppdb_vecs, - "pathaway", - "PathAway Database for Palm/OS", - "pdb" - }, + { + &ppdb_vecs, + "pathaway", + "PathAway Database for Palm/OS", + "pdb" + }, #endif - { - &vitosmt_vecs, - "vitosmt", - "Vito Navigator II tracks", - "smt" - }, - { - &wfff_xml_vecs, - "wfff", - "WiFiFoFum 2.0 for PocketPC XML", - "xml" - }, - { - &bcr_vecs, - "bcr", - "Motorrad Routenplaner (Map&Guide) .bcr files", - "bcr" - }, + { + &vitosmt_vecs, + "vitosmt", + "Vito Navigator II tracks", + "smt" + }, + { + &wfff_xml_vecs, + "wfff", + "WiFiFoFum 2.0 for PocketPC XML", + "xml" + }, + { + &bcr_vecs, + "bcr", + "Motorrad Routenplaner (Map&Guide) .bcr files", + "bcr" + }, #if PDBFMTS_ENABLED - { - &coto_vecs, - "coto", - "cotoGPS for Palm/OS", - "pdb" - }, + { + &coto_vecs, + "coto", + "cotoGPS for Palm/OS", + "pdb" + }, #endif - { - &ignr_vecs, - "ignrando", - "IGN Rando track files", - "rdn" - }, + { + &ignr_vecs, + "ignrando", + "IGN Rando track files", + "rdn" + }, #if CSVFMTS_ENABLED - { - &stmsdf_vecs, - "stmsdf", - "Suunto Trek Manager (STM) .sdf files", - "sdf" - }, + { + &stmsdf_vecs, + "stmsdf", + "Suunto Trek Manager (STM) .sdf files", + "sdf" + }, #endif #if CSVFMTS_ENABLED - { - &stmwpp_vecs, - "stmwpp", - "Suunto Trek Manager (STM) WaypointPlus files", - "txt" - }, + { + &stmwpp_vecs, + "stmwpp", + "Suunto Trek Manager (STM) WaypointPlus files", + "txt" + }, #endif // CSVFMTS_ENABLED - { - &msroute_vecs, - "msroute", - "Microsoft AutoRoute 2002 (pin/route reader)", - "axe" - }, - { - &msroute_vecs, - "msroute", - "Microsoft Streets and Trips (pin/route reader)" , - "est" - }, - { - &cst_vecs, - "cst", - "CarteSurTable data file", - "cst" - }, - { - &nmn4_vecs, - "nmn4", - "Navigon Mobile Navigator .rte files", - "rte" - }, + { + &msroute_vecs, + "msroute", + "Microsoft AutoRoute 2002 (pin/route reader)", + "axe" + }, + { + &msroute_vecs, + "msroute", + "Microsoft Streets and Trips (pin/route reader)" , + "est" + }, + { + &cst_vecs, + "cst", + "CarteSurTable data file", + "cst" + }, + { + &nmn4_vecs, + "nmn4", + "Navigon Mobile Navigator .rte files", + "rte" + }, #if PDBFMTS_ENABLED - { - &magpdb_vecs, - "mag_pdb", - "Map&Guide to Palm/OS exported files (.pdb)", - "pdb" - }, + { + &magpdb_vecs, + "mag_pdb", + "Map&Guide to Palm/OS exported files (.pdb)", + "pdb" + }, #endif #if CSVFMTS_ENABLED - { - &compegps_vecs, - "compegps", - "CompeGPS data files (.wpt/.trk/.rte)", - NULL - }, + { + &compegps_vecs, + "compegps", + "CompeGPS data files (.wpt/.trk/.rte)", + NULL + }, #endif //CSVFMTS_ENABLED - { - &yahoo_vecs, - "yahoo", - "Yahoo Geocode API data", - NULL - }, - { - &unicsv_vecs, - "unicsv", - "Universal csv with field structure in first line", - NULL - }, - { - >m_vecs, - "gtm", - "GPS TrackMaker", - "gtm" - }, - { - &gpssim_vecs, - "gpssim", - "Franson GPSGate Simulation", - "gpssim" - }, + { + &yahoo_vecs, + "yahoo", + "Yahoo Geocode API data", + NULL + }, + { + &unicsv_vecs, + "unicsv", + "Universal csv with field structure in first line", + NULL + }, + { + >m_vecs, + "gtm", + "GPS TrackMaker", + "gtm" + }, + { + &gpssim_vecs, + "gpssim", + "Franson GPSGate Simulation", + "gpssim" + }, #if CSVFMTS_ENABLED - { - &garmin_txt_vecs, - "garmin_txt", - "Garmin MapSource - txt (tab delimited)", - "txt" - }, + { + &garmin_txt_vecs, + "garmin_txt", + "Garmin MapSource - txt (tab delimited)", + "txt" + }, #endif // CSVFMTS_ENABLED - { - &axim_gpb_vecs, - "axim_gpb", - "Dell Axim Navigation System (.gpb) file format", - "gpb" - }, - { - >c_vecs, - "gtrnctr", - "Garmin Training Center (.tcx)", - "xml" - }, - { - &dmtlog_vecs, - "dmtlog", - "TrackLogs digital mapping (.trl)", - "trl" - }, - { - &raymarine_vecs, - "raymarine", - "Raymarine Waypoint File (.rwf)", - "rwf" - }, - { - &alanwpr_vecs, - "alanwpr", - "Alan Map500 waypoints and routes (.wpr)", - "wpr" - }, - { - &alantrl_vecs, - "alantrl", - "Alan Map500 tracklogs (.trl)", - "trl" - }, - { - &vitovtt_vecs, - "vitovtt", - "Vito SmartMap tracks (.vtt)", - "vtt" - }, - { - &ggv_log_vecs, - "ggv_log", - "Geogrid-Viewer tracklogs (.log)", - "log" - }, + { + &axim_gpb_vecs, + "axim_gpb", + "Dell Axim Navigation System (.gpb) file format", + "gpb" + }, + { + >c_vecs, + "gtrnctr", + "Garmin Training Center (.tcx)", + "xml" + }, + { + &dmtlog_vecs, + "dmtlog", + "TrackLogs digital mapping (.trl)", + "trl" + }, + { + &raymarine_vecs, + "raymarine", + "Raymarine Waypoint File (.rwf)", + "rwf" + }, + { + &alanwpr_vecs, + "alanwpr", + "Alan Map500 waypoints and routes (.wpr)", + "wpr" + }, + { + &alantrl_vecs, + "alantrl", + "Alan Map500 tracklogs (.trl)", + "trl" + }, + { + &vitovtt_vecs, + "vitovtt", + "Vito SmartMap tracks (.vtt)", + "vtt" + }, + { + &ggv_log_vecs, + "ggv_log", + "Geogrid-Viewer tracklogs (.log)", + "log" + }, #if CSVFMTS_ENABLED - { - &g7towin_vecs, - "g7towin", - "G7ToWin data files (.g7t)", - "g7t" - }, + { + &g7towin_vecs, + "g7towin", + "G7ToWin data files (.g7t)", + "g7t" + }, #endif - { - &garmin_gpi_vecs, - "garmin_gpi", - "Garmin Points of Interest (.gpi)", - "gpi" - }, - { - &lmx_vecs, - "lmx", - "Nokia Landmark Exchange", - NULL - }, - { - &random_vecs, - "random", - "Internal GPS data generator", - NULL - }, - { - &xol_vecs, - "xol", - "Swiss Map 25/50/100 (.xol)", - "xol" - }, - { - &dg100_vecs, - "dg-100", - "GlobalSat DG-100/BT-335 Download", - NULL - }, - { - &navilink_vecs, - "navilink", - "NaviGPS GT-11/BGT-11 Download", - NULL - }, - { - &ik3d_vecs, - "ik3d", - "MagicMaps IK3D project file (.ikt)", - "ikt" - }, - { - &osm_vecs, - "osm", - "OpenStreetMap data files", - "osm" - }, - { - &destinator_poi_vecs, - "destinator_poi", - "Destinator Points of Interest (.dat)", - "dat" - }, - { - &destinator_itn_vecs, - "destinator_itn", - "Destinator Itineraries (.dat)", - "dat" - }, - { - &destinator_trl_vecs, - "destinator_trl", - "Destinator TrackLogs (.dat)", - "dat" - }, - { - &exif_vecs, - "exif", - "Embedded Exif-GPS data (.jpg)", - "jpg" - }, - { - &vidaone_vecs, - "vidaone", - "VidaOne GPS for Pocket PC (.gpb)", - "gpb" - }, - { - &igo8_vecs, - "igo8", - "IGO8 .trk", - "trk" - }, - { - &gopal_vecs, - "gopal", - "GoPal GPS track log (.trk)", - "trk" - }, - { - &humminbird_vecs, - "humminbird", - "Humminbird waypoints and routes (.hwr)", - "hwr" - }, - { - &humminbird_ht_vecs, - "humminbird_ht", - "Humminbird tracks (.ht)", - "ht" - }, - { - &mapasia_tr7_vecs, - "mapasia_tr7", - "MapAsia track file (.tr7)", - "tr7" - }, - { - &gnav_trl_vecs, - "gnav_trl", - "Google Navigator Tracklines (.trl)", - "trl" - }, - { - &navitel_trk_vecs, - "navitel_trk", - "Navitel binary track (.bin)", - "bin" - }, - { - &ggv_ovl_vecs, - "ggv_ovl", - "Geogrid-Viewer ascii overlay file (.ovl)", - "ovl" - }, + { + &garmin_gpi_vecs, + "garmin_gpi", + "Garmin Points of Interest (.gpi)", + "gpi" + }, + { + &lmx_vecs, + "lmx", + "Nokia Landmark Exchange", + NULL + }, + { + &random_vecs, + "random", + "Internal GPS data generator", + NULL + }, + { + &xol_vecs, + "xol", + "Swiss Map 25/50/100 (.xol)", + "xol" + }, + { + &dg100_vecs, + "dg-100", + "GlobalSat DG-100/BT-335 Download", + NULL + }, + { + &dg200_vecs, + "dg-200", + "GlobalSat DG-200 Download", + NULL + }, + { + &navilink_vecs, + "navilink", + "NaviGPS GT-11/BGT-11 Download", + NULL + }, + { + &ik3d_vecs, + "ik3d", + "MagicMaps IK3D project file (.ikt)", + "ikt" + }, + { + &osm_vecs, + "osm", + "OpenStreetMap data files", + "osm" + }, + { + &destinator_poi_vecs, + "destinator_poi", + "Destinator Points of Interest (.dat)", + "dat" + }, + { + &destinator_itn_vecs, + "destinator_itn", + "Destinator Itineraries (.dat)", + "dat" + }, + { + &destinator_trl_vecs, + "destinator_trl", + "Destinator TrackLogs (.dat)", + "dat" + }, + { + &exif_vecs, + "exif", + "Embedded Exif-GPS data (.jpg)", + "jpg" + }, + { + &vidaone_vecs, + "vidaone", + "VidaOne GPS for Pocket PC (.gpb)", + "gpb" + }, + { + &igo8_vecs, + "igo8", + "IGO8 .trk", + "trk" + }, + { + &gopal_vecs, + "gopal", + "GoPal GPS track log (.trk)", + "trk" + }, + { + &humminbird_vecs, + "humminbird", + "Humminbird waypoints and routes (.hwr)", + "hwr" + }, + { + &humminbird_ht_vecs, + "humminbird_ht", + "Humminbird tracks (.ht)", + "ht" + }, + { + &mapasia_tr7_vecs, + "mapasia_tr7", + "MapAsia track file (.tr7)", + "tr7" + }, + { + &gnav_trl_vecs, + "gnav_trl", + "Google Navigator Tracklines (.trl)", + "trl" + }, + { + &navitel_trk_vecs, + "navitel_trk", + "Navitel binary track (.bin)", + "bin" + }, + { + &ggv_ovl_vecs, + "ggv_ovl", + "Geogrid-Viewer ascii overlay file (.ovl)", + "ovl" + }, #if CSVFMTS_ENABLED - { - &jtr_vecs, - "jtr", - "Jelbert GeoTagger data file", - "jtr" - }, + { + &jtr_vecs, + "jtr", + "Jelbert GeoTagger data file", + "jtr" + }, #endif - { - &itracku_vecs, - "itracku", - "XAiOX iTrackU Logger", - NULL - }, - - { - &itracku_fvecs, - "itracku-bin", - "XAiOX iTrackU Logger Binary File Format", - "bin" - }, - { - &sbp_vecs, - "sbp", - "NaviGPS GT-31/BGT-31 datalogger (.sbp)", - "sbp" - }, - { - &sbn_vecs, - "sbn", - "NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)", - "sbn" - }, - { - &mmo_vecs, - "mmo", - "Memory-Map Navigator overlay files (.mmo)", - "mmo" - }, - { - &bushnell_vecs, - "bushnell", - "Bushnell GPS Waypoint file", - "wpt" - }, - { - &bushnell_trl_vecs, - "bushnell_trl", - "Bushnell GPS Trail file", - "trl" - }, - { - &skyforce_vecs, - "skyforce", - "Skymap / KMD150 ascii files", - NULL - }, - { - &pocketfms_bc_vecs, - "pocketfms_bc", - "PocketFMS breadcrumbs", - NULL - }, - { - &pocketfms_fp_vecs, - "pocketfms_fp", - "PocketFMS flightplan (.xml)", - "xml" - }, - { - &pocketfms_wp_vecs, - "pocketfms_wp", - "PocketFMS waypoints (.txt)", - "txt" - }, - { - &v900_vecs, - "v900", - "Columbus/Visiontac V900 files (.csv)", - NULL - }, - { - &ng_vecs, - "naviguide", - "Naviguide binary route file (.twl)", - "twl" - }, - { - &enigma_vecs, - "enigma", - "Enigma binary waypoint file (.ert)", - "ert" - }, - { - &delbin_vecs, - "delbin", - "DeLorme PN-20/PN-30/PN-40 USB protocol", - NULL - }, - { - &skytraq_vecs, - "skytraq", - "SkyTraq Venus based loggers (download)", - NULL - }, - { - &teletype_vecs, - "teletype", - "Teletype [ Get Jonathon Johnson to describe", - NULL - }, - { - &skytraq_fvecs, - "skytraq-bin", - "SkyTraq Venus based loggers Binary File Format", - "bin" - }, - { - &jogmap_vecs, - "jogmap", - "Jogmap.de XML format", - "xml" - }, - { - &wintec_tes_vecs, - "wintec_tes", - "Wintec TES file", - "tes" - }, - { - &subrip_vecs, - "subrip", - "SubRip subtitles for video mapping (.srt)", - "srt" - }, - { - &format_garmin_xt_vecs, - "garmin_xt", - "Mobile Garmin XT Track files", - NULL - }, + { + &itracku_vecs, + "itracku", + "XAiOX iTrackU Logger", + NULL + }, + + { + &itracku_fvecs, + "itracku-bin", + "XAiOX iTrackU Logger Binary File Format", + "bin" + }, + { + &sbp_vecs, + "sbp", + "NaviGPS GT-31/BGT-31 datalogger (.sbp)", + "sbp" + }, + { + &sbn_vecs, + "sbn", + "NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)", + "sbn" + }, + { + &mmo_vecs, + "mmo", + "Memory-Map Navigator overlay files (.mmo)", + "mmo" + }, + { + &bushnell_vecs, + "bushnell", + "Bushnell GPS Waypoint file", + "wpt" + }, + { + &bushnell_trl_vecs, + "bushnell_trl", + "Bushnell GPS Trail file", + "trl" + }, + { + &skyforce_vecs, + "skyforce", + "Skymap / KMD150 ascii files", + NULL + }, + { + &pocketfms_bc_vecs, + "pocketfms_bc", + "PocketFMS breadcrumbs", + NULL + }, + { + &pocketfms_fp_vecs, + "pocketfms_fp", + "PocketFMS flightplan (.xml)", + "xml" + }, + { + &pocketfms_wp_vecs, + "pocketfms_wp", + "PocketFMS waypoints (.txt)", + "txt" + }, + { + &v900_vecs, + "v900", + "Columbus/Visiontac V900 files (.csv)", + NULL + }, + { + &ng_vecs, + "naviguide", + "Naviguide binary route file (.twl)", + "twl" + }, + { + &enigma_vecs, + "enigma", + "Enigma binary waypoint file (.ert)", + "ert" + }, + { + &delbin_vecs, + "delbin", + "DeLorme PN-20/PN-30/PN-40 USB protocol", + NULL + }, + { + &skytraq_vecs, + "skytraq", + "SkyTraq Venus based loggers (download)", + NULL + }, + { + &teletype_vecs, + "teletype", + "Teletype [ Get Jonathon Johnson to describe", + NULL + }, + { + &skytraq_fvecs, + "skytraq-bin", + "SkyTraq Venus based loggers Binary File Format", + "bin" + }, + { + &miniHomer_vecs, + "miniHomer", + "MiniHomer, a skyTraq Venus 6 based logger (download tracks, waypoints and get/set POI)", + NULL + }, + { + &jogmap_vecs, + "jogmap", + "Jogmap.de XML format", + "xml" + }, + { + &wintec_tes_vecs, + "wintec_tes", + "Wintec TES file", + "tes" + }, + { + &subrip_vecs, + "subrip", + "SubRip subtitles for video mapping (.srt)", + "srt" + }, + { + &format_garmin_xt_vecs, + "garmin_xt", + "Mobile Garmin XT Track files", + NULL + }, + { + &format_fit_vecs, + "garmin_fit", + "Flexible and Interoperable Data Transfer (FIT) Activity file" + "fit" + }, #endif // MAXIMAL_ENABLED - { - NULL, - NULL, - NULL, - NULL - } + { + NULL, + NULL, + NULL, + NULL + } }; void init_vecs(void) { - vecs_t *vec = vec_list; - while ( vec->vec ) { - arglist_t *ap; - if ( vec->vec->args ) { - for ( ap = vec->vec->args; ap->argstring; ap++ ) { - ap->argvalptr = NULL; - if (ap->argval) *ap->argval = NULL; - } - } - vec++; - } + vecs_t *vec = vec_list; + while (vec->vec) { + arglist_t *ap; + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + ap->argvalptr = NULL; + if (ap->argval) { + *ap->argval = NULL; + } + } + } + vec++; + } } int is_integer(const char *c) { - return isdigit(c[0]) || ((c[0] == '+' || c[0] == '-') && isdigit(c[1])); + return isdigit(c[0]) || ((c[0] == '+' || c[0] == '-') && isdigit(c[1])); } -void -exit_vecs( void ) +void +exit_vecs(void) { - vecs_t *vec = vec_list; - while ( vec->vec ) { - arglist_t *ap; - if ( vec->vec->exit ) { - (*vec->vec->exit)(); - } - if ( vec->vec->args ) { - for ( ap = vec->vec->args; ap->argstring; ap++ ) { - if ( ap->defaultvalue && - ( ap->argtype == ARGTYPE_INT ) && - ! is_integer(ap->defaultvalue)) { - warning("%s: not an integer\n", ap->argstring); - } - if ( ap->argvalptr ) { - xfree(ap->argvalptr); - *ap->argval = ap->argvalptr = NULL; - } - } - } - vec++; - } + vecs_t *vec = vec_list; + while (vec->vec) { + arglist_t *ap; + if (vec->vec->exit) { + (*vec->vec->exit)(); + } + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + if (ap->defaultvalue && + (ap->argtype == ARGTYPE_INT) && + ! is_integer(ap->defaultvalue)) { + warning("%s: not an integer\n", ap->argstring); + } + if (ap->argvalptr) { + xfree(ap->argvalptr); + *ap->argval = ap->argvalptr = NULL; + } + } + } + vec++; + } } void assign_option(const char *module, arglist_t *ap, const char *val) { - char *c; - - if (ap->argval == NULL) - fatal("%s: No local variable defined for option \"%s\"!", module, ap->argstring); - - if (ap->argvalptr != NULL) { - xfree(ap->argvalptr); - ap->argvalptr = NULL; - } - if (ap->argval) *ap->argval = NULL; - - if (val == NULL) return; - - if (case_ignore_strcmp(val, ap->argstring) == 0) c = ""; - else c = (char *)val; - - switch(ap->argtype & ARGTYPE_TYPEMASK) { - case ARGTYPE_INT: - if (*c == '\0') c = "0"; - else { - int test; - is_fatal(1 != sscanf(c, "%d", &test), - "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); - } - break; - case ARGTYPE_FLOAT: - if (*c == '\0') c = "0"; - else { - double test; - is_fatal(1 != sscanf(c, "%lf", &test), - "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); - } - break; - case ARGTYPE_BOOL: - if (*c == '\0') c = "1"; - else { - switch(*c) { - case 'Y': - case 'y': c = "1"; break; - case 'N': - case 'n': c = "0"; break; - default: - if (isdigit(*c)) { - if (*c == '0') c = "0"; - else c = "1"; - } - else { - warning(MYNAME ": Invalid logical value '%s' (%s)!\n", c, module); - c = "0"; - } - break; - } - } - break; - } - - /* for bool options without default: don't set argval if "FALSE" */ - - if (((ap->argtype & ARGTYPE_TYPEMASK) == ARGTYPE_BOOL) && - (*c == '0') && (ap->defaultvalue == NULL)) { - return; - } - *ap->argval = ap->argvalptr = xstrdup(c); + char *c; + + if (ap->argval == NULL) { + fatal("%s: No local variable defined for option \"%s\"!", module, ap->argstring); + } + + if (ap->argvalptr != NULL) { + xfree(ap->argvalptr); + ap->argvalptr = NULL; + } + if (ap->argval) { + *ap->argval = NULL; + } + + if (val == NULL) { + return; + } + + if (case_ignore_strcmp(val, ap->argstring) == 0) { + c = ""; + } else { + c = (char *)val; + } + + switch (ap->argtype & ARGTYPE_TYPEMASK) { + case ARGTYPE_INT: + if (*c == '\0') { + c = "0"; + } else { + int test; + is_fatal(1 != sscanf(c, "%d", &test), + "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); + } + break; + case ARGTYPE_FLOAT: + if (*c == '\0') { + c = "0"; + } else { + double test; + is_fatal(1 != sscanf(c, "%lf", &test), + "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); + } + break; + case ARGTYPE_BOOL: + if (*c == '\0') { + c = "1"; + } else { + switch (*c) { + case 'Y': + case 'y': + c = "1"; + break; + case 'N': + case 'n': + c = "0"; + break; + default: + if (isdigit(*c)) { + if (*c == '0') { + c = "0"; + } else { + c = "1"; + } + } else { + warning(MYNAME ": Invalid logical value '%s' (%s)!\n", c, module); + c = "0"; + } + break; + } + } + break; + } + + /* for bool options without default: don't set argval if "FALSE" */ + + if (((ap->argtype & ARGTYPE_TYPEMASK) == ARGTYPE_BOOL) && + (*c == '0') && (ap->defaultvalue == NULL)) { + return; + } + *ap->argval = ap->argvalptr = xstrdup(c); } void disp_vec_options(const char *vecname, arglist_t *ap) { - for (ap = ap; ap && ap->argstring; ap++) { - if (*ap->argval && ap->argval) { - printf("options: module/option=value: %s/%s=\"%s\"", - vecname, ap->argstring, *ap->argval); - if (ap->defaultvalue && (case_ignore_strcmp(ap->defaultvalue, *ap->argval) == 0)) - printf(" (=default)"); - printf("\n"); - } - } + for (ap = ap; ap && ap->argstring; ap++) { + if (*ap->argval && ap->argval) { + printf("options: module/option=value: %s/%s=\"%s\"", + vecname, ap->argstring, *ap->argval); + if (ap->defaultvalue && (case_ignore_strcmp(ap->defaultvalue, *ap->argval) == 0)) { + printf(" (=default)"); + } + printf("\n"); + } + } } ff_vecs_t * find_vec(char *const vecname, char **opts) { - vecs_t *vec = vec_list; - style_vecs_t *svec = style_list; - char *v = xstrdup(vecname); - char *svecname = strtok(v, ","); - int found = 0; - - if (vecname == NULL) { - fatal("A format name is required.\n"); - } - - while (vec->vec) { - arglist_t *ap; - char *res; - - if (case_ignore_strcmp(svecname, vec->name)) { - vec++; - continue; - } - - res = strchr(vecname, ','); - if (res) { - *opts = strchr(vecname, ',')+1; - } else { - *opts = NULL; - } - - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++) { - const char *opt; - - if ( res ) { - opt = get_option(*opts, ap->argstring); - if ( opt ) { - found = 1; - assign_option(svecname, ap, opt); - xfree((char *)opt); - continue; - } - } - opt = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); - if (opt == NULL) opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); - if (opt == NULL) opt = ap->defaultvalue; - assign_option(vec->name, ap, opt); - } - } - if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, vec->name); - } - - if (global_opts.debug_level >= 1) - disp_vec_options(vec->name, vec->vec->args); - -#if CSVFMTS_ENABLED - // xcsv_setup_internal_style( NULL ); + vecs_t *vec = vec_list; + style_vecs_t *svec = style_list; + char *v = xstrdup(vecname); + char *svecname = strtok(v, ","); + int found = 0; + + if (vecname == NULL) { + fatal("A format name is required.\n"); + } + + while (vec->vec) { + arglist_t *ap; + char *res; + + if (case_ignore_strcmp(svecname, vec->name)) { + vec++; + continue; + } + + res = strchr(vecname, ','); + if (res) { + *opts = strchr(vecname, ',')+1; + } else { + *opts = NULL; + } + + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + const char *opt; + + if (res) { + opt = get_option(*opts, ap->argstring); + if (opt) { + found = 1; + assign_option(svecname, ap, opt); + xfree((char *)opt); + continue; + } + } + opt = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + if (opt == NULL) { + opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); + } + if (opt == NULL) { + opt = ap->defaultvalue; + } + assign_option(vec->name, ap, opt); + } + } + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + } + + if (global_opts.debug_level >= 1) { + disp_vec_options(vec->name, vec->vec->args); + } + +#if CSVFMTS_ENABLED + // xcsv_setup_internal_style( NULL ); #endif // CSVFMTS_ENABLED - xfree(v); - vec->vec->name = vec->name; /* needed for session information */ - return vec->vec; - - } - - /* - * Didn't find it in the table of "real" file types, so plan B - * is to search the list of xcsv styles. - */ - while (svec->name) { - arglist_t *ap; - char *res; - - if (case_ignore_strcmp(svecname, svec->name)) { - svec++; - continue; - } - - res = strchr(vecname, ','); - if (res) { - *opts = strchr(vecname, ',') + 1; - } else { - *opts = NULL; - } - - if (vec_list[0].vec->args) { - for (ap = vec_list[0].vec->args; ap->argstring; ap++) { - const char *opt; - - if ( res ) { - opt = get_option(*opts, ap->argstring); - if ( opt ) { - found = 1; - assign_option(svecname, ap, opt); - xfree((char *)opt); - continue; - } - } - opt = inifile_readstr(global_opts.inifile, svec->name, ap->argstring); - if (opt == NULL) opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); - if (opt == NULL) opt = ap->defaultvalue; - assign_option(svec->name, ap, opt); - } - } - - if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, svec->name); - } - - if (global_opts.debug_level >= 1) - disp_vec_options(svec->name, vec_list[0].vec->args); + xfree(v); + vec->vec->name = vec->name; /* needed for session information */ + return vec->vec; + + } + + /* + * Didn't find it in the table of "real" file types, so plan B + * is to search the list of xcsv styles. + */ + while (svec->name) { + arglist_t *ap; + char *res; + + if (case_ignore_strcmp(svecname, svec->name)) { + svec++; + continue; + } + + res = strchr(vecname, ','); + if (res) { + *opts = strchr(vecname, ',') + 1; + } else { + *opts = NULL; + } + + if (vec_list[0].vec->args) { + for (ap = vec_list[0].vec->args; ap->argstring; ap++) { + const char *opt; + + if (res) { + opt = get_option(*opts, ap->argstring); + if (opt) { + found = 1; + assign_option(svecname, ap, opt); + xfree((char *)opt); + continue; + } + } + opt = inifile_readstr(global_opts.inifile, svec->name, ap->argstring); + if (opt == NULL) { + opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); + } + if (opt == NULL) { + opt = ap->defaultvalue; + } + assign_option(svec->name, ap, opt); + } + } + + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, svec->name); + } + + if (global_opts.debug_level >= 1) { + disp_vec_options(svec->name, vec_list[0].vec->args); + } #if CSVFMTS_ENABLED - xcsv_setup_internal_style(svec->style_buf); + xcsv_setup_internal_style(svec->style_buf); #endif // CSVFMTS_ENABLED - xfree(v); - vec_list[0].vec->name = svec->name; /* needed for session information */ - return vec_list[0].vec; - } - - /* - * Not found. - */ - xfree(v); - return NULL; + xfree(v); + vec_list[0].vec->name = svec->name; /* needed for session information */ + return vec_list[0].vec; + } + + /* + * Not found. + */ + xfree(v); + return NULL; } /* @@ -1301,60 +1352,59 @@ GET_OPTION(const char *iarglist, const char *argname, DEBUG_PARAMS) get_option(const char *iarglist, const char *argname) #endif { - size_t arglen = strlen(argname); - char *arglist; - char *rval = NULL; - char *arg; - char *argp; - - if (!iarglist) { - return NULL; - } - - arglen = strlen(argname); - arglist = xstrdup(iarglist); - - for (arg = arglist; argp = strtok(arg, ","), NULL != argp; arg = NULL) { - if (0 == case_ignore_strncmp(argp, argname, arglen)) { - /* - * If we have something of the form "foo=bar" - * return "bar". Otherwise, we assume we have - * simply "foo" so we return that. - */ - if (argp[arglen] == '=') { - rval = argp + arglen + 1; - break; - } - else if (argp[arglen] == '\0') { - rval = argp; - break; - } - } - } - /* - * Return an offset into the allocated copy. - * The caller mustn't free or otherwise get froggy with - * this data. - */ - if ( rval ) { - rval = xxstrdup(rval,file, line); - } - xfree(arglist); - return rval; + size_t arglen = strlen(argname); + char *arglist; + char *rval = NULL; + char *arg; + char *argp; + + if (!iarglist) { + return NULL; + } + + arglen = strlen(argname); + arglist = xstrdup(iarglist); + + for (arg = arglist; argp = strtok(arg, ","), NULL != argp; arg = NULL) { + if (0 == case_ignore_strncmp(argp, argname, arglen)) { + /* + * If we have something of the form "foo=bar" + * return "bar". Otherwise, we assume we have + * simply "foo" so we return that. + */ + if (argp[arglen] == '=') { + rval = argp + arglen + 1; + break; + } else if (argp[arglen] == '\0') { + rval = argp; + break; + } + } + } + /* + * Return an offset into the allocated copy. + * The caller mustn't free or otherwise get froggy with + * this data. + */ + if (rval) { + rval = xxstrdup(rval,file, line); + } + xfree(arglist); + return rval; } /* * Display the available formats in a format that's easy for humans to * parse for help on available command line options. */ -static signed int -alpha (const void *a, const void *b) +static signed int +alpha(const void *a, const void *b) { - const vecs_t *const *ap = (const vecs_t *const*) a; - const vecs_t *const *bp = (const vecs_t *const*) b; - - return case_ignore_strcmp((*ap)->desc , (*bp)->desc); + const vecs_t *const *ap = (const vecs_t *const*) a; + const vecs_t *const *bp = (const vecs_t *const*) b; + + return case_ignore_strcmp((*ap)->desc , (*bp)->desc); } /* @@ -1365,75 +1415,79 @@ alpha (const void *a, const void *b) vecs_t ** sort_and_unify_vecs(int *ctp) { - int vc; - vecs_t **svp; - vecs_t *vec; + int vc; + vecs_t **svp; + vecs_t *vec; #if CSVFMTS_ENABLED - style_vecs_t *svec; + style_vecs_t *svec; #endif - int i = 0; + int i = 0; - /* Get a count from both the vec (normal) and the svec (csv) lists */ + /* Get a count from both the vec (normal) and the svec (csv) lists */ #if CSVFMTS_ENABLED - extern size_t nstyles; - vc = sizeof vec_list / sizeof vec_list[0] - 1 + nstyles; + extern size_t nstyles; + vc = sizeof vec_list / sizeof vec_list[0] - 1 + nstyles; #else - vc = sizeof vec_list / sizeof vec_list[0] - 1; + vc = sizeof vec_list / sizeof vec_list[0] - 1; #endif // CSVFMTS_ENABLED - svp = (vecs_t **)xcalloc(vc, sizeof(style_vecs_t *)); - /* Normal vecs are easy; populate the first part of the array. */ - for (vec = vec_list; vec->vec; vec++, i++) { - svp[i] = vec; - if (svp[i]->parent == NULL) { - svp[i]->parent = svp[i]->name; - } - } + svp = (vecs_t **)xcalloc(vc, sizeof(style_vecs_t *)); + /* Normal vecs are easy; populate the first part of the array. */ + for (vec = vec_list; vec->vec; vec++, i++) { + svp[i] = vec; + if (svp[i]->parent == NULL) { + svp[i]->parent = svp[i]->name; + } + } #if CSVFMTS_ENABLED - /* Walk the style list, parse the entries, dummy up a "normal" vec */ - for (svec = style_list; svec->name; svec++, i++) { - xcsv_read_internal_style(svec->style_buf); - svp[i] = (vecs_t*) xcalloc(1, sizeof **svp); - svp[i]->name = svec->name; - svp[i]->vec = (ff_vecs_t*) xmalloc(sizeof(*svp[i]->vec)); - svp[i]->extension = xcsv_file.extension; - *svp[i]->vec = *vec_list[0].vec; /* Interits xcsv opts */ - /* Reset file type to inherit ff_type from xcsv for everything - * except the xcsv format itself, which we leave as "internal" - */ - if (case_ignore_strcmp(svec->name, "xcsv")) { - svp[i]->vec->type = xcsv_file.type; - /* Skip over the first help entry for all but the - * actual 'xcsv' format - so we don't expose the - * 'full path to xcsv style file' argument to any - * GUIs for an internal format. - */ - svp[i]->vec->args++; - } - memset(&svp[i]->vec->cap, 0, sizeof(svp[i]->vec->cap)); - switch(xcsv_file.datatype) { - case 0: - case wptdata: - svp[i]->vec->cap[ff_cap_rw_wpt] = (ff_cap) (ff_cap_read | ff_cap_write); break; - case trkdata: - svp[i]->vec->cap[ff_cap_rw_trk] = (ff_cap) (ff_cap_read | ff_cap_write); break; - case rtedata: - svp[i]->vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write); break; - default: ; - } - svp[i]->desc = xcsv_file.description; - svp[i]->parent = "xcsv"; - } + /* Walk the style list, parse the entries, dummy up a "normal" vec */ + for (svec = style_list; svec->name; svec++, i++) { + xcsv_read_internal_style(svec->style_buf); + svp[i] = (vecs_t*) xcalloc(1, sizeof **svp); + svp[i]->name = svec->name; + svp[i]->vec = (ff_vecs_t*) xmalloc(sizeof(*svp[i]->vec)); + svp[i]->extension = xcsv_file.extension; + *svp[i]->vec = *vec_list[0].vec; /* Interits xcsv opts */ + /* Reset file type to inherit ff_type from xcsv for everything + * except the xcsv format itself, which we leave as "internal" + */ + if (case_ignore_strcmp(svec->name, "xcsv")) { + svp[i]->vec->type = xcsv_file.type; + /* Skip over the first help entry for all but the + * actual 'xcsv' format - so we don't expose the + * 'full path to xcsv style file' argument to any + * GUIs for an internal format. + */ + svp[i]->vec->args++; + } + memset(&svp[i]->vec->cap, 0, sizeof(svp[i]->vec->cap)); + switch (xcsv_file.datatype) { + case 0: + case wptdata: + svp[i]->vec->cap[ff_cap_rw_wpt] = (ff_cap)(ff_cap_read | ff_cap_write); + break; + case trkdata: + svp[i]->vec->cap[ff_cap_rw_trk] = (ff_cap)(ff_cap_read | ff_cap_write); + break; + case rtedata: + svp[i]->vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write); + break; + default: + ; + } + svp[i]->desc = xcsv_file.description; + svp[i]->parent = "xcsv"; + } #endif // CSVFMTS_ENABLED - /* Now that we have everything in an array, alphabetize them */ - qsort(svp, vc, sizeof(*svp), alpha); + /* Now that we have everything in an array, alphabetize them */ + qsort(svp, vc, sizeof(*svp), alpha); - *ctp = i; - return svp; + *ctp = i; + return svp; } #define VEC_FMT " %-20.20s %-.50s\n" @@ -1441,57 +1495,57 @@ sort_and_unify_vecs(int *ctp) void disp_vecs(void) { - vecs_t **svp; - arglist_t *ap; - int vc; - int i = 0; - - svp = sort_and_unify_vecs(&vc); - for (i=0;ivec->type == ff_type_internal ) { - continue; - } - printf(VEC_FMT, svp[i]->name, svp[i]->desc); - for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN)) - printf(" %-18.18s %s%-.50s %s\n", - ap->argstring, - (ap->argtype & ARGTYPE_TYPEMASK) == - ARGTYPE_BOOL ? "(0/1) " : "", - ap->helpstring, - (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); - } - } - xfree (svp); - return; + vecs_t **svp; + arglist_t *ap; + int vc; + int i = 0; + + svp = sort_and_unify_vecs(&vc); + for (i=0; ivec->type == ff_type_internal) { + continue; + } + printf(VEC_FMT, svp[i]->name, svp[i]->desc); + for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %s%-.50s %s\n", + ap->argstring, + (ap->argtype & ARGTYPE_TYPEMASK) == + ARGTYPE_BOOL ? "(0/1) " : "", + ap->helpstring, + (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); + } + } + xfree(svp); + return; } void -disp_vec( const char *vecname ) +disp_vec(const char *vecname) { - vecs_t **svp; - arglist_t *ap; - int vc; - int i = 0; - - svp = sort_and_unify_vecs(&vc); - for (i=0;iname, vecname )) { - continue; - } - printf(VEC_FMT, svp[i]->name, svp[i]->desc); - for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN)) - printf(" %-18.18s %s%-.50s %s\n", - ap->argstring, - (ap->argtype & ARGTYPE_TYPEMASK) == - ARGTYPE_BOOL ? "(0/1) " : "", - ap->helpstring, - (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); - } - } - xfree (svp); - return; + vecs_t **svp; + arglist_t *ap; + int vc; + int i = 0; + + svp = sort_and_unify_vecs(&vc); + for (i=0; iname, vecname)) { + continue; + } + printf(VEC_FMT, svp[i]->name, svp[i]->desc); + for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %s%-.50s %s\n", + ap->argstring, + (ap->argtype & ARGTYPE_TYPEMASK) == + ARGTYPE_BOOL ? "(0/1) " : "", + ap->helpstring, + (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); + } + } + xfree(svp); + return; } /* @@ -1501,78 +1555,86 @@ disp_vec( const char *vecname ) static void disp_v1(ff_type t) { - char *tstring; - - switch (t) { - case ff_type_file: tstring = "file"; break; - case ff_type_serial: tstring = "serial"; break; - case ff_type_internal: tstring = "internal"; break; - default: tstring = "unknown"; break; - } - printf("%s\t", tstring); + char *tstring; + + switch (t) { + case ff_type_file: + tstring = "file"; + break; + case ff_type_serial: + tstring = "serial"; + break; + case ff_type_internal: + tstring = "internal"; + break; + default: + tstring = "unknown"; + break; + } + printf("%s\t", tstring); } static void disp_v2(ff_vecs_t *v) { - int i; - for (i = 0; i < 3; i++) { - putchar(v->cap[i] & ff_cap_read ? 'r' : '-'); - putchar(v->cap[i] & ff_cap_write ? 'w' : '-'); - } - putchar('\t'); + int i; + for (i = 0; i < 3; i++) { + putchar(v->cap[i] & ff_cap_read ? 'r' : '-'); + putchar(v->cap[i] & ff_cap_write ? 'w' : '-'); + } + putchar('\t'); } const char * name_option(long type) { - const char *at[] = { - "unknown", - "integer", - "float", - "string", - "boolean", - "file", - "outfile" - }; - - if ((type & ARGTYPE_TYPEMASK) <= 6) { - return at[type & ARGTYPE_TYPEMASK]; - } - return at[0]; + const char *at[] = { + "unknown", + "integer", + "float", + "string", + "boolean", + "file", + "outfile" + }; + + if ((type & ARGTYPE_TYPEMASK) <= 6) { + return at[type & ARGTYPE_TYPEMASK]; + } + return at[0]; } -static +static void disp_help_url(const vecs_t *vec, arglist_t *arg) { - printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); - if (arg) { - printf("#fmt_%s_o_%s",vec->name, arg->argstring); - } - printf("\n"); + printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); + if (arg) { + printf("#fmt_%s_o_%s",vec->name, arg->argstring); + } + printf("\n"); } -static void +static void disp_v3(const vecs_t *vec) { - arglist_t *ap; - - disp_help_url(vec, NULL); - for (ap = vec->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN)) { - printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", - vec->name, - ap->argstring, - ap->helpstring, - name_option(ap->argtype), - ap->defaultvalue? ap->defaultvalue : "", - ap->minvalue? ap->minvalue : "", - ap->maxvalue? ap->maxvalue : ""); - } - disp_help_url(vec, ap); - printf("\n"); - } + arglist_t *ap; + + disp_help_url(vec, NULL); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) { + printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", + vec->name, + ap->argstring, + ap->helpstring, + name_option(ap->argtype), + ap->defaultvalue? ap->defaultvalue : "", + ap->minvalue? ap->minvalue : "", + ap->maxvalue? ap->maxvalue : ""); + } + disp_help_url(vec, ap); + printf("\n"); + } } /* @@ -1583,43 +1645,44 @@ disp_v3(const vecs_t *vec) void disp_formats(int version) { - vecs_t **svp; - vecs_t *vec; - int i, vc = 0; - - switch(version) { - case 0: - case 1: - case 2: - case 3: - svp = sort_and_unify_vecs(&vc); - for (i=0;i 0) { - disp_v1(vec->vec->type); - } else { - if (vec->vec->type == ff_type_internal) - continue; - } - if (version >= 2) { - disp_v2(vec->vec); - } - printf("%s\t%s\t%s%s%s\n", vec->name, - vec->extension? vec->extension : "", - vec->desc, - version >= 3 ? "\t" : "", - version >= 3 ? vec->parent : ""); - if (version >= 3) { - disp_v3(vec); - } - } - xfree (svp); - break; - default: - ; - } + vecs_t **svp; + vecs_t *vec; + int i, vc = 0; + + switch (version) { + case 0: + case 1: + case 2: + case 3: + svp = sort_and_unify_vecs(&vc); + for (i=0; i 0) { + disp_v1(vec->vec->type); + } else { + if (vec->vec->type == ff_type_internal) { + continue; + } + } + if (version >= 2) { + disp_v2(vec->vec); + } + printf("%s\t%s\t%s%s%s\n", vec->name, + vec->extension? vec->extension : "", + vec->desc, + version >= 3 ? "\t" : "", + version >= 3 ? vec->parent : ""); + if (version >= 3) { + disp_v3(vec); + } + } + xfree(svp); + break; + default: + ; + } } diff --git a/gpsbabel/vidaone.c b/gpsbabel/vidaone.c index 630e2128b..1d1c0a713 100644 --- a/gpsbabel/vidaone.c +++ b/gpsbabel/vidaone.c @@ -20,17 +20,17 @@ */ - /* - Simple layout: - - struct - { - double dLatitude - double dLongitude - float fReserved - }; - */ - +/* + Simple layout: + +struct +{ + double dLatitude + double dLongitude + float fReserved +}; +*/ + #include "defs.h" #include #include @@ -44,10 +44,12 @@ static int vidaone_ver; static arglist_t vidaone_args[] = { - {VIDAONE_VER, &vidaone_opt_ver, - "Version of VidaOne file to read or write (1 or 2)", - "1", ARGTYPE_INT, "1", "2"}, - ARG_TERMINATOR + { + VIDAONE_VER, &vidaone_opt_ver, + "Version of VidaOne file to read or write (1 or 2)", + "1", ARGTYPE_INT, "1", "2" + }, + ARG_TERMINATOR }; static gbfile *fin, *fout; @@ -59,90 +61,93 @@ static gbfile *fin, *fout; static void vidaone_rd_init(const char *fname) { - vidaone_ver = atoi(vidaone_opt_ver); - fin = gbfopen(fname, "rb", MYNAME); + vidaone_ver = atoi(vidaone_opt_ver); + fin = gbfopen(fname, "rb", MYNAME); } -static void +static void vidaone_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void vidaone_read(void) { - route_head *trk = NULL; - - while (! gbfeof(fin)) { - waypoint *wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - if (vidaone_ver >= 2) - wpt->altitude = gbfgetflt(fin); - (void) gbfgetflt(fin); - - /* Only one basic check of data integrity */ - if ((fabs(wpt->latitude) > 90) || (fabs(wpt->longitude) > 180)) - fatal(MYNAME ": Latitude and/or longitude out of range.\n"); - - if (!trk) { - trk = route_head_alloc(); - track_add_head(trk); - } - - track_add_wpt(trk, wpt); - } + route_head *trk = NULL; + + while (! gbfeof(fin)) { + waypoint *wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + if (vidaone_ver >= 2) { + wpt->altitude = gbfgetflt(fin); + } + (void) gbfgetflt(fin); + + /* Only one basic check of data integrity */ + if ((fabs(wpt->latitude) > 90) || (fabs(wpt->longitude) > 180)) { + fatal(MYNAME ": Latitude and/or longitude out of range.\n"); + } + + if (!trk) { + trk = route_head_alloc(); + track_add_head(trk); + } + + track_add_wpt(trk, wpt); + } } static void vidaone_wr_init(const char *fname) { - vidaone_ver = atoi(vidaone_opt_ver); - fout = gbfopen(fname, "wb", MYNAME); + vidaone_ver = atoi(vidaone_opt_ver); + fout = gbfopen(fname, "wb", MYNAME); } static void vidaone_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void vidaone_trkpt(const waypoint *wpt) { - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - if (vidaone_ver >= 2) - gbfputflt(wpt->altitude, fout); - gbfputflt(0, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + if (vidaone_ver >= 2) { + gbfputflt(wpt->altitude, fout); + } + gbfputflt(0, fout); } static void vidaone_write(void) { - track_disp_all(NULL, NULL, vidaone_trkpt); + track_disp_all(NULL, NULL, vidaone_trkpt); } /**************************************************************************/ ff_vecs_t vidaone_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - vidaone_rd_init, - vidaone_wr_init, - vidaone_rd_deinit, - vidaone_wr_deinit, - vidaone_read, - vidaone_write, - NULL, - vidaone_args, - CET_CHARSET_UTF8, 1 + ff_type_file, + { + ff_cap_none /* waypoints */, + (ff_cap)(ff_cap_read | ff_cap_write) /* tracks */, + ff_cap_none /* routes */ + }, + vidaone_rd_init, + vidaone_wr_init, + vidaone_rd_deinit, + vidaone_wr_deinit, + vidaone_read, + vidaone_write, + NULL, + vidaone_args, + CET_CHARSET_UTF8, 1 }; /**************************************************************************/ diff --git a/gpsbabel/vitosmt.c b/gpsbabel/vitosmt.c index 1297eb7b4..045cd9190 100644 --- a/gpsbabel/vitosmt.c +++ b/gpsbabel/vitosmt.c @@ -1,6 +1,6 @@ /* Read Vito Navigator .SMT tracks - + Copyright (C) 2005 Etienne TASSE This program is free software; you can redistribute it and/or modify @@ -40,16 +40,16 @@ const size_t vitosmt_datasize =64; static unsigned char * ReadRecord(gbfile *f, gbsize_t size) { - unsigned char *result = (unsigned char *) xmalloc(size); + unsigned char *result = (unsigned char *) xmalloc(size); - gbfread(result, size, 1, f); - return result; + gbfread(result, size, 1, f); + return result; } static void WriteDouble(void* ptr, double d) { - unsigned char result[8]="\0\0\0\0\0\0\0\0"; + unsigned char result[9]="\0\0\0\0\0\0\0\0"; le_write_double(result,d); memcpy(ptr, result, 8); } @@ -58,326 +58,321 @@ WriteDouble(void* ptr, double d) static void rd_init(const char *fname) { - infile = gbfopen_le(fname, "rb", MYNAME); + infile = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(infile); + gbfclose(infile); } static void vitosmt_read(void) { - long version =0; - long subversion =0; - long check1 =-1; - long check2 =-2; - long check3 =-3; - route_head *route_head =0; - waypoint *wpt_tmp =0; - double latrad =0; - double lonrad =0; - double elev =0; - unsigned char* timestamp =0; - struct tm tmStruct; - double seconds =0.0; - double speed =0.0; - double course =0.0; - double pdop =0.0; - unsigned char gpsfix =0; - unsigned char gpsvalid =0; - unsigned char gpssats =0; - int serial =0; - - - memset(&tmStruct, 0, sizeof(tmStruct)); - /* - * 24 bytes header - */ - version = gbfgetint32(infile); /* 2 */ - subversion = gbfgetint32(infile); /* 1000 */ - count = gbfgetint32(infile); /* n */ - check1 = gbfgetint32(infile); /* 0 */ - check2 = gbfgetint32(infile); /* not sure */ - check3 = gbfgetint32(infile); /* n */ - - if (version!=vitosmt_version) { - - fatal("%s (%d) reading file. Unsupported version %ld.%ld\n", - MYNAME, __LINE__, version, subversion ); - } - - if (subversion!=vitosmt_subversion) { - warning("%s (%d) reading file. Unsafe version %ld.%ld\n", - MYNAME, __LINE__, version, subversion ); - } - - if ((count!=check3) || - (check1!=count-1) || - (check3!=count) ) { - - fatal("%s (%d) reading file. Invalid file header\n", - MYNAME, __LINE__ ); - - } - - while (count) { - /* - * 64 bytes of data - */ - if (gbfeof(infile)||gbferror(infile)) - { - warning("%s (%d) reading file. Unexpected end of file %s\n", - MYNAME, __LINE__, strerror(errno) ); - break; - } + long version =0; + long subversion =0; + long check1 =-1; + long check2 =-2; + long check3 =-3; + route_head *route_head =0; + waypoint *wpt_tmp =0; + double latrad =0; + double lonrad =0; + double elev =0; + unsigned char* timestamp =0; + struct tm tmStruct; + double seconds =0.0; + double speed =0.0; + double course =0.0; + double pdop =0.0; + unsigned char gpsfix =0; + unsigned char gpsvalid =0; + unsigned char gpssats =0; + int serial =0; + + + memset(&tmStruct, 0, sizeof(tmStruct)); + /* + * 24 bytes header + */ + version = gbfgetint32(infile); /* 2 */ + subversion = gbfgetint32(infile); /* 1000 */ + count = gbfgetint32(infile); /* n */ + check1 = gbfgetint32(infile); /* 0 */ + check2 = gbfgetint32(infile); /* not sure */ + check3 = gbfgetint32(infile); /* n */ + + if (version!=vitosmt_version) { + + fatal("%s (%d) reading file. Unsupported version %ld.%ld\n", + MYNAME, __LINE__, version, subversion); + } + + if (subversion!=vitosmt_subversion) { + warning("%s (%d) reading file. Unsafe version %ld.%ld\n", + MYNAME, __LINE__, version, subversion); + } + + if ((count!=check3) || + (check1!=count-1) || + (check3!=count)) { + + fatal("%s (%d) reading file. Invalid file header\n", + MYNAME, __LINE__); + + } + + while (count) { + /* + * 64 bytes of data + */ + if (gbfeof(infile)||gbferror(infile)) { + warning("%s (%d) reading file. Unexpected end of file %s\n", + MYNAME, __LINE__, strerror(errno)); + break; + } #if 0 - fprintf(stderr, "Looptop %d\n", gbftell(infile)); + fprintf(stderr, "Looptop %d\n", gbftell(infile)); #endif - latrad =gbfgetdbl(infile); /* WGS84 latitude in radians */ - lonrad =gbfgetdbl(infile); /* WGS84 longitude in radians */ - elev =gbfgetdbl(infile); /* elevation in meters */ + latrad =gbfgetdbl(infile); /* WGS84 latitude in radians */ + lonrad =gbfgetdbl(infile); /* WGS84 longitude in radians */ + elev =gbfgetdbl(infile); /* elevation in meters */ #if 0 - fprintf(stderr, "before %d\n", gbftell(infile)); + fprintf(stderr, "before %d\n", gbftell(infile)); #endif - timestamp =ReadRecord(infile,5); /* UTC time yr/mo/dy/hr/mi */ + timestamp =ReadRecord(infile,5); /* UTC time yr/mo/dy/hr/mi */ #if 0 - fprintf(stderr, "%d latrad %f/%f ele %f\n", gbftell(infile),latrad, DEG(latrad), elev); + fprintf(stderr, "%d latrad %f/%f ele %f\n", gbftell(infile),latrad, DEG(latrad), elev); #endif - seconds =gbfgetdbl(infile); /* seconds */ - speed =gbfgetdbl(infile); /* speed in knots */ - course =gbfgetdbl(infile); /* course in degrees */ - pdop =gbfgetdbl(infile); /* dilution of precision */ - gpsfix =gbfgetc(infile); /* fix type x08,x10, x20 */ - gpsvalid =gbfgetc(infile); /* fix is valid */ - gpssats =gbfgetc(infile); /* number of sats */ - - wpt_tmp = waypt_new(); - - wpt_tmp->latitude =DEG(latrad); - wpt_tmp->longitude =DEG(lonrad); - wpt_tmp->altitude =elev; - - tmStruct.tm_year =timestamp[0]+100; - tmStruct.tm_mon =timestamp[1]-1; - tmStruct.tm_mday =timestamp[2]; - tmStruct.tm_hour =timestamp[3]; - tmStruct.tm_min =timestamp[4]; - tmStruct.tm_sec =(int)floor(seconds); - tmStruct.tm_isdst =-1; - - wpt_tmp->creation_time = mkgmtime(&tmStruct); - wpt_tmp->microseconds = fmod(1000000*seconds+0.5,1000000); - wpt_tmp->shortname =xcalloc(16,1); - snprintf(wpt_tmp->shortname, 15 , "WP%04d", ++serial); - - WAYPT_SET(wpt_tmp, speed, KNOTS_TO_MPS(speed)); /* meters per second */ - WAYPT_SET(wpt_tmp, course, course); - wpt_tmp->pdop = pdop; - - /* - GPS Fix data - */ - if (gpsvalid&0x7) { - if (gpsfix==0) - wpt_tmp->fix =fix_none; - if (gpsfix&0x8) - wpt_tmp->fix =fix_2d; - else if (gpsfix&0x10) - wpt_tmp->fix =fix_3d; - else if (gpsfix&0x20) - wpt_tmp->fix =fix_dgps; - else - wpt_tmp->fix =fix_unknown; - - /* */ - wpt_tmp->sat = gpssats; - } - else - wpt_tmp->fix =fix_unknown; - - if (doing_wpts) /* process as waypoints */ - { - waypt_add(wpt_tmp); - } - else if (doing_rtes) /* process as route */ - { - if (route_head == NULL) { - route_head = route_head_alloc(); - route_add_head(route_head); - } - route_add_wpt(route_head, wpt_tmp); - } - else /* default track mode */ - { - if (route_head == NULL) { - route_head = route_head_alloc(); - track_add_head(route_head); - } - track_add_wpt(route_head, wpt_tmp); - } - - xfree(timestamp); - - count--; - } + seconds =gbfgetdbl(infile); /* seconds */ + speed =gbfgetdbl(infile); /* speed in knots */ + course =gbfgetdbl(infile); /* course in degrees */ + pdop =gbfgetdbl(infile); /* dilution of precision */ + gpsfix =gbfgetc(infile); /* fix type x08,x10, x20 */ + gpsvalid =gbfgetc(infile); /* fix is valid */ + gpssats =gbfgetc(infile); /* number of sats */ + + wpt_tmp = waypt_new(); + + wpt_tmp->latitude =DEG(latrad); + wpt_tmp->longitude =DEG(lonrad); + wpt_tmp->altitude =elev; + + tmStruct.tm_year =timestamp[0]+100; + tmStruct.tm_mon =timestamp[1]-1; + tmStruct.tm_mday =timestamp[2]; + tmStruct.tm_hour =timestamp[3]; + tmStruct.tm_min =timestamp[4]; + tmStruct.tm_sec =(int)floor(seconds); + tmStruct.tm_isdst =-1; + + wpt_tmp->creation_time = mkgmtime(&tmStruct); + wpt_tmp->microseconds = fmod(1000000*seconds+0.5,1000000); + wpt_tmp->shortname = (char*) xcalloc(16,1); + snprintf(wpt_tmp->shortname, 15 , "WP%04d", ++serial); + + WAYPT_SET(wpt_tmp, speed, KNOTS_TO_MPS(speed)); /* meters per second */ + WAYPT_SET(wpt_tmp, course, course); + wpt_tmp->pdop = pdop; + + /* + GPS Fix data + */ + if (gpsvalid&0x7) { + if (gpsfix==0) { + wpt_tmp->fix =fix_none; + } + if (gpsfix&0x8) { + wpt_tmp->fix =fix_2d; + } else if (gpsfix&0x10) { + wpt_tmp->fix =fix_3d; + } else if (gpsfix&0x20) { + wpt_tmp->fix =fix_dgps; + } else { + wpt_tmp->fix =fix_unknown; + } + + /* */ + wpt_tmp->sat = gpssats; + } else { + wpt_tmp->fix =fix_unknown; + } + + if (doing_wpts) { /* process as waypoints */ + waypt_add(wpt_tmp); + } else if (doing_rtes) { /* process as route */ + if (route_head == NULL) { + route_head = route_head_alloc(); + route_add_head(route_head); + } + route_add_wpt(route_head, wpt_tmp); + } else { /* default track mode */ + if (route_head == NULL) { + route_head = route_head_alloc(); + track_add_head(route_head); + } + track_add_wpt(route_head, wpt_tmp); + } + + xfree(timestamp); + + count--; + } } static void wr_init(const char *fname) { - warning(MYNAME " write: format is experimental and may crash Vito Navigator II.\n"); - ofs = gbfopen_le(fname, "wb", MYNAME); + warning(MYNAME " write: format is experimental and may crash Vito Navigator II.\n"); + ofs = gbfopen_le(fname, "wb", MYNAME); } static void wr_deinit(void) { - gbfclose(ofs); + gbfclose(ofs); } static void vitosmt_waypt_pr(const waypoint *waypointp) { - unsigned char * workbuffer =0; - size_t position =0; - struct tm* tmstructp =0; - double seconds =0; - - ++count; - workbuffer = xcalloc(vitosmt_datasize,1); - - WriteDouble(&workbuffer[position], RAD(waypointp->latitude) ); - position += sizeof(double); - WriteDouble(&workbuffer[position], RAD(waypointp->longitude) ); - position += sizeof(double); - if ( waypointp->altitude-1 > unknown_alt) - WriteDouble(&workbuffer[position], waypointp->altitude ); - position += sizeof(double); - - tmstructp = gmtime(&waypointp->creation_time); - seconds = (double) tmstructp->tm_sec + 0.0000001*waypointp->microseconds; - - workbuffer[position++] =tmstructp->tm_year-100; - workbuffer[position++] =tmstructp->tm_mon+1; - workbuffer[position++] =tmstructp->tm_mday; - workbuffer[position++] =tmstructp->tm_hour; - workbuffer[position++] =tmstructp->tm_min; - - WriteDouble(&workbuffer[position], seconds ); - position += sizeof(double); - - /* speed */ - if (waypointp->speed>0) - WriteDouble(&workbuffer[position], MPS_TO_MPH(waypointp->speed)); - position += sizeof(double); - - /* course */ - if ((waypointp->course>=-360.0)&&(waypointp->course<=360.0)) - WriteDouble(&workbuffer[position], waypointp->course ); - position += sizeof(double); - - /* pdop */ - if (waypointp->pdop>0) - WriteDouble(&workbuffer[position], waypointp->pdop ); - position += sizeof(double); - - - /* fix type */ - switch (waypointp->fix) - { - case fix_2d: - workbuffer[position++] = 0x08; - break; - case fix_3d: - workbuffer[position++] = 0x10; - break; - case fix_dgps: - workbuffer[position++] = 0x20; - break; - default: - workbuffer[position++] = 0; - break; - } - - /* Assume position is valid */ - workbuffer[position++] = 0x07; - - if ((waypointp->sat>0)&&(waypointp->sat<128)) - workbuffer[position++] = waypointp->sat; - else - workbuffer[position++] = 0; - - (void)gbfwrite(workbuffer,vitosmt_datasize,1,ofs); - - xfree(workbuffer); + unsigned char * workbuffer =0; + size_t position =0; + struct tm* tmstructp =0; + double seconds =0; + + ++count; + workbuffer = (unsigned char *) xcalloc(vitosmt_datasize,1); + + WriteDouble(&workbuffer[position], RAD(waypointp->latitude)); + position += sizeof(double); + WriteDouble(&workbuffer[position], RAD(waypointp->longitude)); + position += sizeof(double); + if (waypointp->altitude-1 > unknown_alt) { + WriteDouble(&workbuffer[position], waypointp->altitude); + } + position += sizeof(double); + + tmstructp = gmtime(&waypointp->creation_time); + seconds = (double) tmstructp->tm_sec + 0.0000001*waypointp->microseconds; + + workbuffer[position++] =tmstructp->tm_year-100; + workbuffer[position++] =tmstructp->tm_mon+1; + workbuffer[position++] =tmstructp->tm_mday; + workbuffer[position++] =tmstructp->tm_hour; + workbuffer[position++] =tmstructp->tm_min; + + WriteDouble(&workbuffer[position], seconds); + position += sizeof(double); + + /* speed */ + if (waypointp->speed>0) { + WriteDouble(&workbuffer[position], MPS_TO_MPH(waypointp->speed)); + } + position += sizeof(double); + + /* course */ + if ((waypointp->course>=-360.0)&&(waypointp->course<=360.0)) { + WriteDouble(&workbuffer[position], waypointp->course); + } + position += sizeof(double); + + /* pdop */ + if (waypointp->pdop>0) { + WriteDouble(&workbuffer[position], waypointp->pdop); + } + position += sizeof(double); + + + /* fix type */ + switch (waypointp->fix) { + case fix_2d: + workbuffer[position++] = 0x08; + break; + case fix_3d: + workbuffer[position++] = 0x10; + break; + case fix_dgps: + workbuffer[position++] = 0x20; + break; + default: + workbuffer[position++] = 0; + break; + } + + /* Assume position is valid */ + workbuffer[position++] = 0x07; + + if ((waypointp->sat>0)&&(waypointp->sat<128)) { + workbuffer[position++] = waypointp->sat; + } else { + workbuffer[position++] = 0; + } + + (void)gbfwrite(workbuffer,vitosmt_datasize,1,ofs); + + xfree(workbuffer); } static void vitosmt_write(void) { - time_t now = 0; - unsigned char * workbuffer =0; - size_t position =0; - - workbuffer = xcalloc(vitosmt_headersize,1); - - now = current_time(); - count = 0; - position = 0; - - /* leave a spacer for the header */ - memset(workbuffer,0,vitosmt_headersize); - (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); - - if (doing_wpts) /* process as waypoints */ - { - waypt_disp_all(vitosmt_waypt_pr); - } - else if (doing_rtes) /* process as route */ - { - route_disp_all(NULL, NULL, vitosmt_waypt_pr); - } - else /* default track mode */ - { - track_disp_all(NULL, NULL, vitosmt_waypt_pr); - } - - - /* write the complete the header */ - le_write32(&workbuffer[position],vitosmt_version); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],vitosmt_subversion); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],count); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],0); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],count-1); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],count); - position += sizeof(gbuint32); - - gbfrewind(ofs); - (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); - - xfree(workbuffer); + time_t now = 0; + unsigned char * workbuffer =0; + size_t position =0; + + workbuffer = (unsigned char*) xcalloc(vitosmt_headersize,1); + + now = current_time(); + count = 0; + position = 0; + + /* leave a spacer for the header */ + memset(workbuffer,0,vitosmt_headersize); + (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); + + if (doing_wpts) { /* process as waypoints */ + waypt_disp_all(vitosmt_waypt_pr); + } else if (doing_rtes) { /* process as route */ + route_disp_all(NULL, NULL, vitosmt_waypt_pr); + } else { /* default track mode */ + track_disp_all(NULL, NULL, vitosmt_waypt_pr); + } + + + /* write the complete the header */ + le_write32(&workbuffer[position],vitosmt_version); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],vitosmt_subversion); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],0); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count-1); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count); + position += sizeof(gbuint32); + + gbfrewind(ofs); + (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); + + xfree(workbuffer); } ff_vecs_t vitosmt_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - vitosmt_read, - vitosmt_write, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + vitosmt_read, + vitosmt_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ }; diff --git a/gpsbabel/vitovtt.c b/gpsbabel/vitovtt.c index 99f6538e5..c4cc2f606 100644 --- a/gpsbabel/vitovtt.c +++ b/gpsbabel/vitovtt.c @@ -1,8 +1,8 @@ /* Read Vito SmartMap .vtt tracks - + Copyright (C) 2007 Jeremy Ehrhardt, jeremye@caltech.edu - + based on vitostc.c, which is Copyright (C) 2005 Etienne TASSE @@ -48,92 +48,92 @@ static const int vitovtt_microsecondscale = 30; static void rd_init(const char *fname) { - infile = gbfopen_le(fname, "rb", MYNAME); + infile = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(infile); + gbfclose(infile); } static void vitovtt_read(void) { - int version = 0; - route_head *route_head = 0; - waypoint *wpt_tmp = 0; - int scaled_lat = 0; - int scaled_lon = 0; - double altitude = 0; - struct tm tmStruct; - int scaled_sec = 0; - int microseconds = 0; - double speed = 0; - int course = 0; - int status = 0; - - memset(&tmStruct, 0, sizeof(tmStruct)); - - route_head = route_head_alloc(); - track_add_head(route_head); - - /* Read the header. */ - version = gbfgetint32(infile); - count = gbfgetint32(infile); - - if (version!=vitovtt_version) { - - fatal("%s (%d) reading file. Unsupported version %d\n", - MYNAME, __LINE__, version ); - } - - while (count) { - /* Read an entry. */ - scaled_lat = gbfgetint32(infile); - scaled_lon = gbfgetint32(infile); - altitude = gbfgetflt(infile); - tmStruct.tm_year = gbfgetint16(infile) - TM_YEAR_ZERO; - tmStruct.tm_mon = gbfgetc(infile) - TM_MONTH_ZERO; - tmStruct.tm_mday = gbfgetc(infile); - tmStruct.tm_hour = gbfgetc(infile); - tmStruct.tm_min = gbfgetc(infile); - scaled_sec = gbfgetint32(infile); - speed = gbfgetflt(infile); - course = gbfgetint16(infile); - status = gbfgetint32(infile); - - wpt_tmp = waypt_new(); - - wpt_tmp->latitude = scaled_lat / vitovtt_latitudescale; - wpt_tmp->longitude = scaled_lon / vitovtt_longitudescale; - wpt_tmp->altitude = altitude; - - tmStruct.tm_sec = scaled_sec / vitovtt_secondscale; - microseconds = (scaled_sec % vitovtt_secondscale) / vitovtt_microsecondscale; - wpt_tmp->creation_time = mkgmtime(&tmStruct); - wpt_tmp->microseconds = microseconds; - - /* - * TODO: interpret speed, course, status - */ - - track_add_wpt(route_head, wpt_tmp); - - count--; - } + int version = 0; + route_head *route_head = 0; + waypoint *wpt_tmp = 0; + int scaled_lat = 0; + int scaled_lon = 0; + double altitude = 0; + struct tm tmStruct; + int scaled_sec = 0; + int microseconds = 0; + double speed = 0; + int course = 0; + int status = 0; + + memset(&tmStruct, 0, sizeof(tmStruct)); + + route_head = route_head_alloc(); + track_add_head(route_head); + + /* Read the header. */ + version = gbfgetint32(infile); + count = gbfgetint32(infile); + + if (version!=vitovtt_version) { + + fatal("%s (%d) reading file. Unsupported version %d\n", + MYNAME, __LINE__, version); + } + + while (count) { + /* Read an entry. */ + scaled_lat = gbfgetint32(infile); + scaled_lon = gbfgetint32(infile); + altitude = gbfgetflt(infile); + tmStruct.tm_year = gbfgetint16(infile) - TM_YEAR_ZERO; + tmStruct.tm_mon = gbfgetc(infile) - TM_MONTH_ZERO; + tmStruct.tm_mday = gbfgetc(infile); + tmStruct.tm_hour = gbfgetc(infile); + tmStruct.tm_min = gbfgetc(infile); + scaled_sec = gbfgetint32(infile); + speed = gbfgetflt(infile); + course = gbfgetint16(infile); + status = gbfgetint32(infile); + + wpt_tmp = waypt_new(); + + wpt_tmp->latitude = scaled_lat / vitovtt_latitudescale; + wpt_tmp->longitude = scaled_lon / vitovtt_longitudescale; + wpt_tmp->altitude = altitude; + + tmStruct.tm_sec = scaled_sec / vitovtt_secondscale; + microseconds = (scaled_sec % vitovtt_secondscale) / vitovtt_microsecondscale; + wpt_tmp->creation_time = mkgmtime(&tmStruct); + wpt_tmp->microseconds = microseconds; + + /* + * TODO: interpret speed, course, status + */ + + track_add_wpt(route_head, wpt_tmp); + + count--; + } } ff_vecs_t vitovtt_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read, ff_cap_none }, - rd_init, - NULL, - rd_deinit, - NULL, - vitovtt_read, - NULL, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + vitovtt_read, + NULL, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ }; diff --git a/gpsbabel/vmem.c b/gpsbabel/vmem.c index c35a02fa2..64bb5673f 100644 --- a/gpsbabel/vmem.c +++ b/gpsbabel/vmem.c @@ -1,5 +1,5 @@ /* - vmem utilities. Manipulate allocated object optimized for + vmem utilities. Manipulate allocated object optimized for long-term persistence over raw speed. Copyright (C) 2003 Robert Lipe, robertlipe@usa.net @@ -23,28 +23,31 @@ #include "defs.h" #include -vmem_t +vmem_t vmem_alloc(size_t size, int flags) { - vmem_t vm; - /* - * By default, zero the allocated thingy. - */ - if (flags & VMFL_NOZERO) - vm.mem = xmalloc(size); - else - vm.mem = (char *) xcalloc(size, 1); - vm.size = size; - return vm; + vmem_t vm; + /* + * By default, zero the allocated thingy. + */ + if (flags & VMFL_NOZERO) { + vm.mem = (char *) xmalloc(size); + } else { + vm.mem = (char *) xcalloc(size, 1); + } + vm.size = size; + return vm; } void vmem_free(vmem_t *vm) { - if (vm->mem) xfree(vm->mem); - vm->mem = NULL; - vm->size = 0; - return; + if (vm->mem) { + xfree(vm->mem); + } + vm->mem = NULL; + vm->size = 0; + return; } /* @@ -54,12 +57,12 @@ vmem_free(vmem_t *vm) void vmem_realloc(vmem_t *vm, size_t size) { - /* - * Reallocate only if we must. - */ - if (size > vm->size) { - vm->mem = xrealloc(vm->mem, size); - vm->size = size; - } - return; + /* + * Reallocate only if we must. + */ + if (size > vm->size) { + vm->mem = (char *) xrealloc(vm->mem, size); + vm->size = size; + } + return; } diff --git a/gpsbabel/vpl.c b/gpsbabel/vpl.c index 16f32d348..6eb21c77f 100644 --- a/gpsbabel/vpl.c +++ b/gpsbabel/vpl.c @@ -101,7 +101,7 @@ C - Checksum */ -/* +/* TODO: - Implement checksum verification */ @@ -116,7 +116,7 @@ void vpl_parse_75_sentence(const char*); static arglist_t vpl_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static gbfile *vpl_file_in; @@ -129,37 +129,37 @@ static route_head *track_head; static void vpl_rd_init(const char *fname) { - vpl_file_in = gbfopen(fname, "r", MYNAME); + vpl_file_in = gbfopen(fname, "r", MYNAME); } -static void +static void vpl_rd_deinit(void) { - gbfclose(vpl_file_in); + gbfclose(vpl_file_in); } static void vpl_read(void) { - char *ibuf; - - // Set up a track - if(track_head == NULL) { - track_head = route_head_alloc(); - track_add_head(track_head); - } - - while((ibuf = gbfgetstr(vpl_file_in))) { - if(strncmp(ibuf, "75", 2) == 0) { - vpl_parse_75_sentence(ibuf); - } - } + char *ibuf; + + // Set up a track + if (track_head == NULL) { + track_head = route_head_alloc(); + track_add_head(track_head); + } + + while ((ibuf = gbfgetstr(vpl_file_in))) { + if (strncmp(ibuf, "75", 2) == 0) { + vpl_parse_75_sentence(ibuf); + } + } } static void vpl_wr_init(const char *fname) { - fatal("Writing file of type %s is not support\n", MYNAME); + fatal("Writing file of type %s is not support\n", MYNAME); } /******************************************************************************* @@ -169,69 +169,69 @@ vpl_wr_init(const char *fname) void vpl_parse_75_sentence(const char *ibuf) { - gbuint32 ymd, hms; - gbint32 lat_raw, lon_raw; - gbint16 alt, speed_raw; - gbuint16 hdg_raw; - gbuint8 sats, hdop_raw, vdop_raw; - waypoint *waypt; - struct tm tm; - - // The files have DOS line endings (CR/LF) but we don't care, because we - // don't read to the end. - sscanf(ibuf, "75%*2c%8X%8X%4hX%4hX%4hX%*2c%2hhX%2hhX%2hhX%6u%6u", - &lat_raw, &lon_raw, &alt, &speed_raw, &hdg_raw, &sats, &hdop_raw, &vdop_raw, - &ymd, &hms); - - tm.tm_sec = hms % 100; - hms /= 100; - tm.tm_min = hms % 100; - hms /= 100; - tm.tm_hour = hms % 100; - - tm.tm_mday = ymd % 100; - ymd /= 100; - tm.tm_mon = ymd % 100; - ymd /= 100; - tm.tm_year = ymd % 100 + 100; - - waypt = waypt_new(); - - // Lat/Lon are both stored *0xE1000 which we have to divide out - // for decimal degrees - waypt->latitude = lat_raw / (double) 0xE1000; - waypt->longitude = lon_raw / (double) 0xE1000; - waypt->altitude = alt; - waypt->sat = sats; - // Speed comes in (MPH x 0x10) which we have to convert to m/s - WAYPT_SET(waypt, speed, (speed_raw / (double) 0x10) * 0.44704); - waypt->course = hdg_raw * (double) (360/65535); - waypt->hdop = hdop_raw / (double) 8; - waypt->vdop = vdop_raw / (double) 8; - - waypt->creation_time = mkgmtime(&tm); - - track_add_wpt(track_head, waypt); + gbuint32 ymd, hms; + gbint32 lat_raw, lon_raw; + gbint16 alt, speed_raw; + gbuint16 hdg_raw; + gbuint8 sats, hdop_raw, vdop_raw; + waypoint *waypt; + struct tm tm; + + // The files have DOS line endings (CR/LF) but we don't care, because we + // don't read to the end. + sscanf(ibuf, "75%*2c%8X%8X%4hX%4hX%4hX%*2c%2hhX%2hhX%2hhX%6u%6u", + &lat_raw, &lon_raw, &alt, &speed_raw, &hdg_raw, &sats, &hdop_raw, &vdop_raw, + &ymd, &hms); + + tm.tm_sec = hms % 100; + hms /= 100; + tm.tm_min = hms % 100; + hms /= 100; + tm.tm_hour = hms % 100; + + tm.tm_mday = ymd % 100; + ymd /= 100; + tm.tm_mon = ymd % 100; + ymd /= 100; + tm.tm_year = ymd % 100 + 100; + + waypt = waypt_new(); + + // Lat/Lon are both stored *0xE1000 which we have to divide out + // for decimal degrees + waypt->latitude = lat_raw / (double) 0xE1000; + waypt->longitude = lon_raw / (double) 0xE1000; + waypt->altitude = alt; + waypt->sat = sats; + // Speed comes in (MPH x 0x10) which we have to convert to m/s + WAYPT_SET(waypt, speed, (speed_raw / (double) 0x10) * 0.44704); + waypt->course = hdg_raw * (double)(360/65535); + waypt->hdop = hdop_raw / (double) 8; + waypt->vdop = vdop_raw / (double) 8; + + waypt->creation_time = mkgmtime(&tm); + + track_add_wpt(track_head, waypt); } /**************************************************************************/ ff_vecs_t vpl_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - vpl_rd_init, - vpl_wr_init, - vpl_rd_deinit, - NULL, - vpl_read, - NULL, - NULL, - vpl_args, - CET_CHARSET_ASCII, /* ascii is the expected character set */ - 1 /* fixed, can't be changed through command line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + vpl_rd_init, + vpl_wr_init, + vpl_rd_deinit, + NULL, + vpl_read, + NULL, + NULL, + vpl_args, + CET_CHARSET_ASCII, /* ascii is the expected character set */ + 1 /* fixed, can't be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/waypt.c b/gpsbabel/waypt.c index f40c54b39..ff83eb3d3 100644 --- a/gpsbabel/waypt.c +++ b/gpsbabel/waypt.c @@ -34,161 +34,174 @@ static global_trait traits; const global_trait* get_traits(void) { - return &traits; + return &traits; } void waypt_init(void) { - mkshort_handle = mkshort_new_handle(); - QUEUE_INIT(&waypt_head); + mkshort_handle = mkshort_new_handle(); + QUEUE_INIT(&waypt_head); } waypoint * -waypt_dupe(const waypoint *wpt) -{ - /* - * This and waypt_free should be closely synced. - */ - waypoint * tmp; - url_link *url_next; - - tmp = waypt_new(); - memcpy(tmp, wpt, sizeof(waypoint)); - tmp->url_next = NULL; - - if (wpt->shortname) - tmp->shortname = xstrdup(wpt->shortname); - if (wpt->description) - tmp->description = xstrdup(wpt->description); - if (wpt->notes) - tmp->notes = xstrdup(wpt->notes); - if (wpt->url) - tmp->url = xstrdup(wpt->url); - if (wpt->url_link_text) - tmp->url_link_text = xstrdup(wpt->url_link_text); - for (url_next = wpt->url_next; url_next; url_next = url_next->url_next) { - waypt_add_url(tmp, - (url_next->url) ? xstrdup(url_next->url) : NULL, - (url_next->url_link_text) ? xstrdup(url_next->url_link_text) : NULL); - } - if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) - tmp->icon_descr = xstrdup(wpt->icon_descr); - - if (wpt->gc_data != &empty_gc_data) { - geocache_data *gc_data = xmalloc(sizeof(*gc_data)); - tmp->gc_data = (const geocache_data *)gc_data; - - memcpy(gc_data, wpt->gc_data, sizeof(*gc_data)); - if (wpt->gc_data->desc_short.utfstring) { - gc_data->desc_short.utfstring = - xstrdup(wpt->gc_data->desc_short.utfstring); - } - if (wpt->gc_data->desc_long.utfstring) { - gc_data->desc_long.utfstring = - xstrdup(wpt->gc_data->desc_long.utfstring); - } - if (wpt->gc_data->placer) { - gc_data->placer = xstrdup(wpt->gc_data->placer); - } - if (wpt->gc_data->hint) { - gc_data->hint = xstrdup(wpt->gc_data->hint); - } - } - - /* - * It's important that this duplicated waypoint not appear - * on the master Q. - */ - QUEUE_INIT(&tmp->Q); - tmp->fs = fs_chain_copy( wpt->fs ); - - return tmp; +waypt_dupe(const waypoint *wpt) +{ + /* + * This and waypt_free should be closely synced. + */ + waypoint * tmp; + url_link *url_next; + + tmp = waypt_new(); + memcpy(tmp, wpt, sizeof(waypoint)); + tmp->url_next = NULL; + + if (wpt->shortname) { + tmp->shortname = xstrdup(wpt->shortname); + } + if (wpt->description) { + tmp->description = xstrdup(wpt->description); + } + if (wpt->notes) { + tmp->notes = xstrdup(wpt->notes); + } + if (wpt->url) { + tmp->url = xstrdup(wpt->url); + } + if (wpt->url_link_text) { + tmp->url_link_text = xstrdup(wpt->url_link_text); + } + for (url_next = wpt->url_next; url_next; url_next = url_next->url_next) { + waypt_add_url(tmp, + (url_next->url) ? xstrdup(url_next->url) : NULL, + (url_next->url_link_text) ? xstrdup(url_next->url_link_text) : NULL); + } + if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) { + tmp->icon_descr = xstrdup(wpt->icon_descr); + } + + if (wpt->gc_data != &empty_gc_data) { + geocache_data *gc_data = (geocache_data*) xmalloc(sizeof(*gc_data)); + tmp->gc_data = (const geocache_data *)gc_data; + + memcpy(gc_data, wpt->gc_data, sizeof(*gc_data)); + if (wpt->gc_data->desc_short.utfstring) { + gc_data->desc_short.utfstring = + xstrdup(wpt->gc_data->desc_short.utfstring); + } + if (wpt->gc_data->desc_long.utfstring) { + gc_data->desc_long.utfstring = + xstrdup(wpt->gc_data->desc_long.utfstring); + } + if (wpt->gc_data->placer) { + gc_data->placer = xstrdup(wpt->gc_data->placer); + } + if (wpt->gc_data->hint) { + gc_data->hint = xstrdup(wpt->gc_data->hint); + } + } + + /* + * It's important that this duplicated waypoint not appear + * on the master Q. + */ + QUEUE_INIT(&tmp->Q); + tmp->fs = fs_chain_copy(wpt->fs); + + return tmp; } void update_common_traits(const waypoint* wpt) { - /* This is a bit tacky, but it allows a hint whether we've seen - * this data or not in the life cycle of this run. Of course, - * the caches could have been filtered out of existance and not - * all waypoints may have this and a few other pitfalls, but it's - * an easy and fast test here. - */ - traits.trait_geocaches |= (wpt->gc_data->diff && wpt->gc_data->terr); - traits.trait_heartrate |= wpt->heartrate > 0; - traits.trait_cadence |= wpt->cadence > 0; - traits.trait_power |= wpt->power > 0; - traits.trait_depth |= WAYPT_HAS(wpt, depth); - traits.trait_temperature |= WAYPT_HAS(wpt, temperature); + /* This is a bit tacky, but it allows a hint whether we've seen + * this data or not in the life cycle of this run. Of course, + * the caches could have been filtered out of existance and not + * all waypoints may have this and a few other pitfalls, but it's + * an easy and fast test here. + */ + traits.trait_geocaches |= (wpt->gc_data->diff && wpt->gc_data->terr); + traits.trait_heartrate |= wpt->heartrate > 0; + traits.trait_cadence |= wpt->cadence > 0; + traits.trait_power |= wpt->power > 0; + traits.trait_depth |= WAYPT_HAS(wpt, depth); + traits.trait_temperature |= WAYPT_HAS(wpt, temperature); } void waypt_add(waypoint *wpt) { - double lat_orig = wpt->latitude; - double lon_orig = wpt->longitude; - - ENQUEUE_TAIL(&waypt_head, &wpt->Q); - - waypt_ct++; - - if (wpt->latitude < -90) wpt->latitude += 180; - else if (wpt->latitude > +90) wpt->latitude -= 180; - if (wpt->longitude < -180) wpt->longitude += 360; - else if (wpt->longitude > +180) wpt->longitude -= 360; - - if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) - fatal("%s: Invalid latitude %f in waypoint %s.\n", - wpt->session->name, - lat_orig, wpt->shortname ? wpt->shortname : ""); - if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) - fatal ("Invalid longitude %f in waypoint %s.\n", - lon_orig, wpt->shortname ? wpt->shortname : ""); - if (wpt->creation_time < 0) { - warning("%s: Invalid timestamp in waypoint %s.\n", - wpt->session->name, - wpt->shortname ? wpt->shortname : ""); - wpt->creation_time = 0; - } - /* - * Some input may not have one or more of these types so we - * try to be sure that we have these fields even if just by - * copying them from elsewhere. - */ - if (wpt->shortname == NULL) { - if (wpt->description) { - wpt->shortname = xstrdup(wpt->description); - } else if (wpt->notes) { - wpt->shortname = xstrdup(wpt->notes); - } else { - /* Last ditch: make up a name */ - char cbuf[10]; - snprintf(cbuf, sizeof(cbuf), "WPT%03d", waypt_ct); - wpt->shortname = xstrdup(cbuf); - } - } - - if (wpt->description == NULL || strlen(wpt->description) == 0) { - if (wpt->description) - xfree(wpt->description); - if (wpt->notes != NULL) { - wpt->description = xstrdup(wpt->notes); - } else { - if (wpt->shortname != NULL) { - wpt->description = xstrdup(wpt->shortname); - } - } - } - - update_common_traits(wpt); + double lat_orig = wpt->latitude; + double lon_orig = wpt->longitude; + + ENQUEUE_TAIL(&waypt_head, &wpt->Q); + + waypt_ct++; + + if (wpt->latitude < -90) { + wpt->latitude += 180; + } else if (wpt->latitude > +90) { + wpt->latitude -= 180; + } + if (wpt->longitude < -180) { + wpt->longitude += 360; + } else if (wpt->longitude > +180) { + wpt->longitude -= 360; + } + + if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) + fatal("%s: Invalid latitude %f in waypoint %s.\n", + wpt->session->name, + lat_orig, wpt->shortname ? wpt->shortname : ""); + if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) + fatal("Invalid longitude %f in waypoint %s.\n", + lon_orig, wpt->shortname ? wpt->shortname : ""); + if (wpt->creation_time < 0) { + warning("%s: Invalid timestamp in waypoint %s.\n", + wpt->session->name, + wpt->shortname ? wpt->shortname : ""); + wpt->creation_time = 0; + } + /* + * Some input may not have one or more of these types so we + * try to be sure that we have these fields even if just by + * copying them from elsewhere. + */ + if (wpt->shortname == NULL) { + if (wpt->description) { + wpt->shortname = xstrdup(wpt->description); + } else if (wpt->notes) { + wpt->shortname = xstrdup(wpt->notes); + } else { + /* Last ditch: make up a name */ + char cbuf[10]; + snprintf(cbuf, sizeof(cbuf), "WPT%03d", waypt_ct); + wpt->shortname = xstrdup(cbuf); + } + } + + if (wpt->description == NULL || strlen(wpt->description) == 0) { + if (wpt->description) { + xfree(wpt->description); + } + if (wpt->notes != NULL) { + wpt->description = xstrdup(wpt->notes); + } else { + if (wpt->shortname != NULL) { + wpt->description = xstrdup(wpt->shortname); + } + } + } + + update_common_traits(wpt); } void waypt_del(waypoint *wpt) { - dequeue(&wpt->Q); - waypt_ct--; + dequeue(&wpt->Q); + waypt_ct--; } /* @@ -197,135 +210,143 @@ waypt_del(waypoint *wpt) waypoint * waypt_new(void) { - waypoint *wpt; + waypoint *wpt; - wpt = (waypoint *) xcalloc(sizeof (*wpt), 1); + wpt = (waypoint *) xcalloc(sizeof(*wpt), 1); #ifdef DEBUG_MEM - wpt->altitude = unknown_alt; - wpt->longitude = unknown_alt; + wpt->altitude = unknown_alt; + wpt->longitude = unknown_alt; #endif - wpt->altitude = unknown_alt; - wpt->fix = fix_unknown; - wpt->sat = -1; - wpt->session = curr_session(); - wpt->gc_data = &empty_gc_data; + wpt->altitude = unknown_alt; + wpt->fix = fix_unknown; + wpt->sat = -1; + wpt->session = curr_session(); + wpt->gc_data = &empty_gc_data; - QUEUE_INIT(&wpt->Q); - return wpt; + QUEUE_INIT(&wpt->Q); + return wpt; } unsigned int waypt_count(void) { - return waypt_ct; + return waypt_ct; } void set_waypt_count(unsigned int nc) { - waypt_ct = nc; + waypt_ct = nc; } void waypt_disp(const waypoint *wpt) { - char *tmpdesc = NULL; - if (wpt->creation_time) { - printf("%s ", ctime(&wpt->creation_time)); - } - printposn(wpt->latitude,1); - printposn(wpt->longitude,0); - - if ( wpt->description ) { - tmpdesc = xstrdup( wpt->description); - printf("%s/%s", - global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, tmpdesc) : - wpt->shortname, - tmpdesc); - if ( tmpdesc ) - xfree(tmpdesc); - } - - if (wpt->altitude != unknown_alt) - printf(" %f", wpt->altitude); - printf("\n"); + char *tmpdesc = NULL; + if (wpt->creation_time) { + printf("%s ", ctime(&wpt->creation_time)); + } + printposn(wpt->latitude,1); + printposn(wpt->longitude,0); + + if (wpt->description) { + tmpdesc = xstrdup(wpt->description); + printf("%s/%s", + global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, tmpdesc) : + wpt->shortname, + tmpdesc); + if (tmpdesc) { + xfree(tmpdesc); + } + } + + if (wpt->altitude != unknown_alt) { + printf(" %f", wpt->altitude); + } + printf("\n"); } void waypt_status_disp(int total_ct, int myct) { - fprintf(stdout, "%d/%d/%d\r", myct*100/total_ct, myct, total_ct); - fflush(stdout); + fprintf(stdout, "%d/%d/%d\r", myct*100/total_ct, myct, total_ct); + fflush(stdout); } void waypt_disp_all(waypt_cb cb) { - waypt_disp_session(NULL, cb); + waypt_disp_session(NULL, cb); } void waypt_disp_session(const session_t *se, waypt_cb cb) { - queue *elem, *tmp; - waypoint *waypointp; - int i = 0; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - if ((se == NULL) || (waypointp->session == se)) { - if (global_opts.verbose_status) { - i++; - waypt_status_disp(waypt_ct, i); - } - (*cb) (waypointp); - } - } - if (global_opts.verbose_status) { - fprintf(stdout, "\r\n"); - } + queue *elem, *tmp; + waypoint *waypointp; + int i = 0; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + if ((se == NULL) || (waypointp->session == se)) { + if (global_opts.verbose_status) { + i++; + waypt_status_disp(waypt_ct, i); + } + (*cb)(waypointp); + } + } + if (global_opts.verbose_status) { + fprintf(stdout, "\r\n"); + } } void waypt_init_bounds(bounds *bounds) { - /* Set data out of bounds so that even one waypoint will reset */ - bounds->max_lat = -9999; - bounds->max_lon = -9999; - bounds->min_lat = 9999; - bounds->min_lon = 9999; - bounds->max_alt = -unknown_alt; - bounds->min_alt = unknown_alt; + /* Set data out of bounds so that even one waypoint will reset */ + bounds->max_lat = -9999; + bounds->max_lon = -9999; + bounds->min_lat = 9999; + bounds->min_lon = 9999; + bounds->max_alt = unknown_alt; + bounds->min_alt = -unknown_alt; } int waypt_bounds_valid(bounds *bounds) { - /* Returns true if bb has any 'real' data in it */ - return bounds->max_lat > -9999; + /* Returns true if bb has any 'real' data in it */ + return bounds->max_lat > -9999; } /* * Recompund bounding box based on new position point. */ -void +void waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp) { - if (waypointp->latitude > bounds->max_lat) - bounds->max_lat = waypointp->latitude; - if (waypointp->longitude > bounds->max_lon) - bounds->max_lon = waypointp->longitude; - if (waypointp->latitude < bounds->min_lat) - bounds->min_lat = waypointp->latitude; - if (waypointp->longitude < bounds->min_lon) - bounds->min_lon = waypointp->longitude; - if (waypointp->altitude != unknown_alt) { - if (waypointp->altitude < bounds->min_alt) - bounds->min_alt = waypointp->altitude; - if (waypointp->altitude > bounds->max_alt) - bounds->max_alt = waypointp->altitude; - } + if (waypointp->latitude > bounds->max_lat) { + bounds->max_lat = waypointp->latitude; + } + if (waypointp->longitude > bounds->max_lon) { + bounds->max_lon = waypointp->longitude; + } + if (waypointp->latitude < bounds->min_lat) { + bounds->min_lat = waypointp->latitude; + } + if (waypointp->longitude < bounds->min_lon) { + bounds->min_lon = waypointp->longitude; + } + if (waypointp->altitude != unknown_alt) { + if (waypointp->altitude < bounds->min_alt) { + bounds->min_alt = waypointp->altitude; + } + if (waypointp->altitude > bounds->max_alt) { + bounds->max_alt = waypointp->altitude; + } + } } @@ -337,289 +358,307 @@ waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp) void waypt_compute_bounds(bounds *bounds) { - queue *elem, *tmp; - waypoint *waypointp; + queue *elem, *tmp; + waypoint *waypointp; - waypt_init_bounds(bounds); + waypt_init_bounds(bounds); - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - waypt_add_to_bounds(bounds, waypointp); - } + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + waypt_add_to_bounds(bounds, waypointp); + } } waypoint * find_waypt_by_name(const char *name) { - queue *elem, *tmp; - waypoint *waypointp; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - if (0 == strcmp(waypointp->shortname, name)) { - return waypointp; - } - } - - return NULL; -} - -void -waypt_free( waypoint *wpt ) -{ - /* - * This and waypt_dupe should be closely synced. - */ - if (wpt->shortname) { - xfree(wpt->shortname); - } - if (wpt->description) { - xfree(wpt->description); - } - if (wpt->notes) { - xfree(wpt->notes); - } - if (wpt->url) { - xfree(wpt->url); - } - if (wpt->url_link_text) { - xfree(wpt->url_link_text); - } - if (wpt->url_next) { - url_link *url_next; - - for (url_next = wpt->url_next; url_next; ) { - - url_link *tonuke = url_next; - if (tonuke->url) { - xfree(tonuke->url); - } - if (tonuke->url_link_text) { - xfree(tonuke->url_link_text); - } - url_next = tonuke->url_next; - xfree(tonuke); - } - } - if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) { - xfree((char *)(void *)wpt->icon_descr); - } - - if (wpt->gc_data != &empty_gc_data) { - geocache_data *gc_data = (geocache_data *)wpt->gc_data; - - if (gc_data->desc_short.utfstring) { - xfree(gc_data->desc_short.utfstring); - } - if (gc_data->desc_long.utfstring) { - xfree(gc_data->desc_long.utfstring); - } - if (gc_data->placer) { - xfree(gc_data->placer); - } - if (gc_data->hint) { - xfree (gc_data->hint); - } - xfree(gc_data); - } - fs_chain_destroy( wpt->fs ); - xfree(wpt); -} - -void -waypt_flush( queue *head ) -{ - queue *elem, *tmp; - - QUEUE_FOR_EACH(head, elem, tmp) { - waypoint *q = (waypoint *) dequeue(elem); - waypt_free(q); - if (head == &waypt_head) { - waypt_ct--; - } - } + queue *elem, *tmp; + waypoint *waypointp; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + + return NULL; +} + +void +waypt_free(waypoint *wpt) +{ + /* + * This and waypt_dupe should be closely synced. + */ + if (wpt->shortname) { + xfree(wpt->shortname); + } + if (wpt->description) { + xfree(wpt->description); + } + if (wpt->notes) { + xfree(wpt->notes); + } + if (wpt->url) { + xfree(wpt->url); + } + if (wpt->url_link_text) { + xfree(wpt->url_link_text); + } + if (wpt->url_next) { + url_link *url_next; + + for (url_next = wpt->url_next; url_next;) { + + url_link *tonuke = url_next; + if (tonuke->url) { + xfree(tonuke->url); + } + if (tonuke->url_link_text) { + xfree(tonuke->url_link_text); + } + url_next = tonuke->url_next; + xfree(tonuke); + } + } + if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) { + xfree((char *)(void *)wpt->icon_descr); + } + + if (wpt->gc_data != &empty_gc_data) { + geocache_data *gc_data = (geocache_data *)wpt->gc_data; + + if (gc_data->desc_short.utfstring) { + xfree(gc_data->desc_short.utfstring); + } + if (gc_data->desc_long.utfstring) { + xfree(gc_data->desc_long.utfstring); + } + if (gc_data->placer) { + xfree(gc_data->placer); + } + if (gc_data->hint) { + xfree(gc_data->hint); + } + if (gc_data->personal_note) { + xfree(gc_data->personal_note); + } + xfree(gc_data); + } + fs_chain_destroy(wpt->fs); + xfree(wpt); +} + +void +waypt_flush(queue *head) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(head, elem, tmp) { + waypoint *q = (waypoint *) dequeue(elem); + waypt_free(q); + if (head == &waypt_head) { + waypt_ct--; + } + } } void waypt_flush_all() { - if ( mkshort_handle ) { - mkshort_del_handle( &mkshort_handle ); - } - waypt_flush(&waypt_head); + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } + waypt_flush(&waypt_head); } void waypt_backup(signed int *count, queue **head_bak) { - queue *elem, *tmp, *qbackup; - waypoint *wpt; - int no = 0; + queue *elem, *tmp, *qbackup; + waypoint *wpt; + int no = 0; - qbackup = (queue *) xcalloc(1, sizeof(*qbackup)); - QUEUE_INIT(qbackup); - - QUEUE_MOVE(qbackup, &waypt_head); - QUEUE_INIT(&waypt_head); + qbackup = (queue *) xcalloc(1, sizeof(*qbackup)); + QUEUE_INIT(qbackup); - waypt_ct = 0; + QUEUE_MOVE(qbackup, &waypt_head); + QUEUE_INIT(&waypt_head); - QUEUE_FOR_EACH(qbackup, elem, tmp) - { - wpt = (waypoint *)elem; - waypt_add(waypt_dupe(wpt)); - no++; - } + waypt_ct = 0; - *head_bak = qbackup; - *count = no; + QUEUE_FOR_EACH(qbackup, elem, tmp) { + wpt = (waypoint *)elem; + waypt_add(waypt_dupe(wpt)); + no++; + } + + *head_bak = qbackup; + *count = no; } void waypt_restore(signed int count, queue *head_bak) { - if (head_bak == NULL) return; - - waypt_flush(&waypt_head); - QUEUE_INIT(&waypt_head); - QUEUE_MOVE(&waypt_head, head_bak); - waypt_ct = count; - xfree(head_bak); + if (head_bak == NULL) { + return; + } + + waypt_flush(&waypt_head); + QUEUE_INIT(&waypt_head); + QUEUE_MOVE(&waypt_head, head_bak); + waypt_ct = count; + xfree(head_bak); } void waypt_add_url(waypoint *wpt, char *link, char *url_link_text) { - if ((link == NULL) && (url_link_text == NULL)) return; - - /* Special case first one; it goes right into the waypoint. */ - if ((wpt->url == NULL) && (wpt->url_link_text == NULL)) { - wpt->url = link; - wpt->url_link_text = url_link_text; - } else { - url_link *tail; - url_link *new_link = xcalloc(sizeof(url_link), 1); - new_link->url = link; - new_link->url_link_text = url_link_text; - - /* Find current end of chain and tack this onto the end.. */ - for (tail = wpt->url_next;;tail = tail->url_next) { - if (tail == NULL) { - wpt->url_next = new_link; - break; - } - if (tail->url_next == NULL) { - tail->url_next = new_link; - break; - } - } - } + if ((link == NULL) && (url_link_text == NULL)) { + return; + } + + /* Special case first one; it goes right into the waypoint. */ + if ((wpt->url == NULL) && (wpt->url_link_text == NULL)) { + wpt->url = link; + wpt->url_link_text = url_link_text; + } else { + url_link *tail; + url_link *new_link = (url_link*) xcalloc(sizeof(url_link), 1); + new_link->url = link; + new_link->url_link_text = url_link_text; + + /* Find current end of chain and tack this onto the end.. */ + for (tail = wpt->url_next;; tail = tail->url_next) { + if (tail == NULL) { + wpt->url_next = new_link; + break; + } + if (tail->url_next == NULL) { + tail->url_next = new_link; + break; + } + } + } } double gcgeodist(const double lat1, const double lon1, - const double lat2, const double lon2) + const double lat2, const double lon2) { - double res; + double res; + + res = radtometers(gcdist(RAD(lat1), RAD(lon1), RAD(lat2), RAD(lon2))); + if (res < 0.1) { + res = 0; /* calc. diffs on 32- and 64-bit hosts */ + } - res = radtometers(gcdist(RAD(lat1), RAD(lon1), RAD(lat2), RAD(lon2))); - if (res < 0.1) res = 0; /* calc. diffs on 32- and 64-bit hosts */ - - return res; + return res; } /* * returns full creation_time with parts of seconds in fractional portion */ - + double waypt_time(const waypoint *wpt) { - if (wpt->creation_time <= 0) - return (double) 0; - else - return ((double)wpt->creation_time + ((double)wpt->microseconds / 1000000)); + if (wpt->creation_time <= 0) { + return (double) 0; + } else { + return ((double)wpt->creation_time + ((double)wpt->microseconds / 1000000)); + } } /* * Calculates the distance between points "A" and "B" including * special data (Garmin interstep links) * The result comes in meters. - */ + */ double waypt_distance_ex(const waypoint *A, const waypoint *B) { - double res = 0; - garmin_fs_p gmsd; - - if ((A == NULL) || (B == NULL)) return 0; - - if ((gmsd = GMSD_FIND(A)) && (gmsd->ilinks != NULL)) - { - garmin_ilink_t *link = gmsd->ilinks; - - res = gcgeodist(A->latitude, A->longitude, link->lat, link->lon); - while (link->next != NULL) - { - garmin_ilink_t *prev = link; - link = link->next; - res += gcgeodist(prev->lat, prev->lon, link->lat, link->lon); - } - res += gcgeodist(link->lat, link->lon, B->latitude, B->longitude); - } - else - res = gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); - - return res; + double res = 0; + garmin_fs_p gmsd; + + if ((A == NULL) || (B == NULL)) { + return 0; + } + + if ((gmsd = GMSD_FIND(A)) && (gmsd->ilinks != NULL)) { + garmin_ilink_t *link = gmsd->ilinks; + + res = gcgeodist(A->latitude, A->longitude, link->lat, link->lon); + while (link->next != NULL) { + garmin_ilink_t *prev = link; + link = link->next; + res += gcgeodist(prev->lat, prev->lon, link->lat, link->lon); + } + res += gcgeodist(link->lat, link->lon, B->latitude, B->longitude); + } else { + res = gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); + } + + return res; } double waypt_distance(const waypoint *A, const waypoint *B) { - if ((A == NULL) || (B == NULL)) return 0; - else return gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); + if ((A == NULL) || (B == NULL)) { + return 0; + } else { + return gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); + } } /* * Calculates the speed between points "A" and "B" including * special data (Garmin interstep links) * The result comes in meters per second and is always positive. - */ + */ double waypt_speed_ex(const waypoint *A, const waypoint *B) { - double dist, time; - - dist = waypt_distance_ex(A, B); - if (dist == 0) return 0; - - time = fabs(waypt_time(A) - waypt_time(B)); - if (time > 0) - return (dist / time); - else - return 0; + double dist, time; + + dist = waypt_distance_ex(A, B); + if (dist == 0) { + return 0; + } + + time = fabs(waypt_time(A) - waypt_time(B)); + if (time > 0) { + return (dist / time); + } else { + return 0; + } } /* * Calculates the speed between points "A" and "B" * the result comes in meters per second and is always positive - */ + */ double waypt_speed(const waypoint *A, const waypoint *B) { - double dist, time; - - dist = waypt_distance(A, B); - if (dist == 0) return 0; - - time = fabs(waypt_time(A) - waypt_time(B)); - if (time > 0) - return (dist / time); - else - return 0; + double dist, time; + + dist = waypt_distance(A, B); + if (dist == 0) { + return 0; + } + + time = fabs(waypt_time(A) - waypt_time(B)); + if (time > 0) { + return (dist / time); + } else { + return 0; + } } /* @@ -628,26 +667,27 @@ waypt_speed(const waypoint *A, const waypoint *B) double waypt_course(const waypoint *A, const waypoint *B) { - if (A && B) - return heading_true_degrees(RAD(A->latitude), RAD(A->longitude), RAD(B->latitude), RAD(B->longitude)); - else - return 0; + if (A && B) { + return heading_true_degrees(RAD(A->latitude), RAD(A->longitude), RAD(B->latitude), RAD(B->longitude)); + } else { + return 0; + } } geocache_data * waypt_alloc_gc_data(waypoint *wpt) { - geocache_data *res = (geocache_data *)wpt->gc_data; - if (res == &empty_gc_data) { - res = xcalloc(1, sizeof(*res)); - wpt->gc_data = (const geocache_data *)res; - - } - return res; + geocache_data *res = (geocache_data *)wpt->gc_data; + if (res == &empty_gc_data) { + res = (geocache_data*) xcalloc(1, sizeof(*res)); + wpt->gc_data = (const geocache_data *)res; + + } + return res; } int waypt_empty_gc_data(const waypoint *wpt) { - return (wpt->gc_data == &empty_gc_data); + return (wpt->gc_data == &empty_gc_data); } diff --git a/gpsbabel/wbt-200.c b/gpsbabel/wbt-200.c index ab1e0d94b..763bbde88 100644 --- a/gpsbabel/wbt-200.c +++ b/gpsbabel/wbt-200.c @@ -56,9 +56,9 @@ /* Flags for WBT201 */ enum { - WBT201_TRACK_START = 0x01, - WBT201_WAYPOINT = 0x02, - WBT201_OVER_SPEED = 0x04 + WBT201_TRACK_START = 0x01, + WBT201_WAYPOINT = 0x02, + WBT201_OVER_SPEED = 0x04 }; #define BUFSPEC(b) b, sizeof(b) @@ -69,11 +69,11 @@ enum { * heuristics the format matching code will have to be rejigged. */ static struct { - size_t reclen; + size_t reclen; } fmt_version[] = { - { RECLEN_V1 }, - { RECLEN_V2 }, - { 0 } + { RECLEN_V1 }, + { RECLEN_V2 }, + { 0 } }; /* Number of lines to skip while waiting for an ACK from a command. I've seen @@ -92,15 +92,17 @@ static FILE *fl; static char *port; static char *erase; -static enum { - UNKNOWN, WBT200, WBT201, WSG1000 -} dev_type = UNKNOWN; +typedef enum { + UNKNOWN, WBT200, WBT201, WSG1000 +} wintec_gps_types; + +static wintec_gps_types dev_type = UNKNOWN; struct buf_chunk { - struct buf_chunk *next; - size_t size; - size_t used; - /* data follows in memory */ + struct buf_chunk *next; + size_t size; + size_t used; + /* data follows in memory */ }; #define buf_CHUNK_DATA(c) \ @@ -110,364 +112,396 @@ struct buf_chunk { ((void *) ((char *) buf_CHUNK_DATA(c) + (offset))) struct buf_head { - struct buf_chunk *head; - struct buf_chunk *tail; - size_t alloc; - size_t used; - /* read position */ - struct buf_chunk *current; - unsigned long offset; - /* shoehorned in here primarily out of laziness */ - unsigned checksum; + struct buf_chunk *head; + struct buf_chunk *tail; + size_t alloc; + size_t used; + /* read position */ + struct buf_chunk *current; + unsigned long offset; + /* shoehorned in here primarily out of laziness */ + unsigned checksum; }; struct read_state { - route_head *route_head; - unsigned wpn, tpn; + route_head *route_head_; + unsigned wpn, tpn; - struct buf_head data; + struct buf_head data; }; -static void db(int l, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - vprintf(msg, ap); - } - va_end(ap); +static void db(int l, const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); } /* Growable buffer support. TODO: Put this in a separate file and * tidy up its interface. */ -static void buf_init(struct buf_head *h, size_t alloc) { - h->head = NULL; - h->tail = NULL; - h->alloc = alloc; - h->used = 0; - h->checksum = 0; - h->offset = 0; +static void buf_init(struct buf_head *h, size_t alloc) +{ + h->head = NULL; + h->tail = NULL; + h->alloc = alloc; + h->used = 0; + h->checksum = 0; + h->offset = 0; } -static void buf_empty(struct buf_head *h) { - struct buf_chunk *chunk, *next; - for (chunk = h->head; chunk; chunk = next) { - next = chunk->next; - xfree(chunk); - } - h->head = NULL; - h->tail = NULL; - h->used = 0; - h->checksum = 0; +static void buf_empty(struct buf_head *h) +{ + struct buf_chunk *chunk, *next; + for (chunk = h->head; chunk; chunk = next) { + next = chunk->next; + xfree(chunk); + } + h->head = NULL; + h->tail = NULL; + h->used = 0; + h->checksum = 0; } -static void buf_rewind(struct buf_head *h) { - h->current = h->head; - h->offset = 0; +static void buf_rewind(struct buf_head *h) +{ + h->current = h->head; + h->offset = 0; } -static size_t buf_read(struct buf_head *h, void *data, size_t len) { - char *bp = data; - size_t got = 0; +static size_t buf_read(struct buf_head *h, void *data, size_t len) +{ + char *bp = (char *) data; + size_t got = 0; - while (len != 0 && h->current != NULL) { - size_t avail = h->current->used - h->offset; - if (avail > len) { avail = len; } + while (len != 0 && h->current != NULL) { + size_t avail = h->current->used - h->offset; + if (avail > len) { + avail = len; + } - /* Allow NULL buffer pointer to skip bytes */ - if (NULL != bp) { - memcpy(bp, buf_CHUNK_PTR(h->current, h->offset), avail); - bp += avail; - } + /* Allow NULL buffer pointer to skip bytes */ + if (NULL != bp) { + memcpy(bp, buf_CHUNK_PTR(h->current, h->offset), avail); + bp += avail; + } - h->offset += avail; - len -= avail; - got += avail; + h->offset += avail; + len -= avail; + got += avail; - if (h->offset == h->current->used) { - h->current = h->current->next; - h->offset = 0; - } + if (h->offset == h->current->used) { + h->current = h->current->next; + h->offset = 0; } + } - return got; + return got; } -static void buf_extend(struct buf_head *h, size_t amt) { - struct buf_chunk *c; - size_t sz = amt + sizeof(struct buf_chunk); +static void buf_extend(struct buf_head *h, size_t amt) +{ + struct buf_chunk *c; + size_t sz = amt + sizeof(struct buf_chunk); - c = xmalloc(sz); - c->next = NULL; - c->size = amt; - c->used = 0; + c = (struct buf_chunk*) xmalloc(sz); + c->next = NULL; + c->size = amt; + c->used = 0; - if (NULL == h->head) { - h->head = c; - } else { - h->tail->next = c; - } + if (NULL == h->head) { + h->head = c; + } else { + h->tail->next = c; + } - h->tail = c; + h->tail = c; } -static void buf_update_checksum(struct buf_head *h, const void *data, size_t len) { - unsigned char *cp = (unsigned char *) data; - unsigned i; - - db(4, "Updating checksum with %p, %lu, before: %02x ", - data, (unsigned long) len, h->checksum); - for (i = 0; i < len; i++) { - h->checksum ^= cp[i]; - } - db(4, "after: %02x\n", h->checksum); +static void buf_update_checksum(struct buf_head *h, const void *data, size_t len) +{ + unsigned char *cp = (unsigned char *) data; + unsigned i; + + db(4, "Updating checksum with %p, %lu, before: %02x ", + data, (unsigned long) len, h->checksum); + for (i = 0; i < len; i++) { + h->checksum ^= cp[i]; + } + db(4, "after: %02x\n", h->checksum); } -static void buf_write(struct buf_head *h, const void *data, size_t len) { - size_t avail; - const char *bp = data; - - buf_update_checksum(h, data, len); +static void buf_write(struct buf_head *h, const void *data, size_t len) +{ + size_t avail; + const char *bp = (const char *) data; - h->used += len; + buf_update_checksum(h, data, len); - if (NULL == h->tail) { - buf_extend(h, h->alloc); - } + h->used += len; - for (;;) { - avail = h->tail->size - h->tail->used; - if (avail > len) { avail = len; } - - memcpy((char *) buf_CHUNK_PTR(h->tail, h->tail->used), bp, avail); - h->tail->used += avail; - bp += avail; - len -= avail; - if (len == 0) { - break; - } - buf_extend(h, h->alloc); + if (NULL == h->tail) { + buf_extend(h, h->alloc); + } + + for (;;) { + avail = h->tail->size - h->tail->used; + if (avail > len) { + avail = len; } -} -static void rd_drain() { - if (gbser_flush(fd)) { - fatal(MYNAME ": Comm error\n"); + memcpy((char *) buf_CHUNK_PTR(h->tail, h->tail->used), bp, avail); + h->tail->used += avail; + bp += avail; + len -= avail; + if (len == 0) { + break; } + buf_extend(h, h->alloc); + } } -static void rd_line(char *buf, int len) { - int rc; - if (rc = gbser_read_line(fd, buf, len, TIMEOUT, 0x0A, 0x0D), rc != gbser_OK) { - fatal(MYNAME ": Read error (%d)\n", rc); - } - db(3, "Got response: \"%s\"\n", buf); +static void rd_drain() +{ + if (gbser_flush(fd)) { + fatal(MYNAME ": Comm error\n"); + } } -static void wr_cmd(const char *cmd) { - int rc; - db(3, "Sending: %s\n", cmd); - if (rc = gbser_print(fd, cmd), gbser_OK != rc) { - fatal(MYNAME ": Write error (%d)\n", rc); - } +static void rd_line(char *buf, int len) +{ + int rc; + if (rc = gbser_read_line(fd, buf, len, TIMEOUT, 0x0A, 0x0D), rc != gbser_OK) { + fatal(MYNAME ": Read error (%d)\n", rc); + } + db(3, "Got response: \"%s\"\n", buf); } -static void wr_cmdl(const char *cmd) { - wr_cmd(cmd); - wr_cmd(NL); +static void wr_cmd(const char *cmd) +{ + int rc; + db(3, "Sending: %s\n", cmd); + if (rc = gbser_print(fd, cmd), gbser_OK != rc) { + fatal(MYNAME ": Write error (%d)\n", rc); + } } -static int expect(const char *str) { - int state = 0; - int c, i; - int errors = 5; /* allow this many errors */ - - for (i = 0; i < 5000; i++) { - /* reached end of string */ - if (str[state] == '\0') { - return 1; - } - - c = gbser_readc_wait(fd, 500); - if (c < 0) { - db(3, "Got error: %d\n", c); - if (--errors <= 0) { - return 0; - } - } else { - db(3, "Got char: %02x '%c'\n", c, isprint(c) ? c : '.'); - if (c == str[state]) { - state++; /* carry on */ - } else { - state = 0; /* go back to start */ - } - } - } - - return 0; +static void wr_cmdl(const char *cmd) +{ + wr_cmd(cmd); + wr_cmd(NL); } -static int wbt200_try() { - int rc; +static int expect(const char *str) +{ + int state = 0; + int c, i; + int errors = 5; /* allow this many errors */ - db(1, "Trying WBT100/200\n"); + for (i = 0; i < 5000; i++) { + /* reached end of string */ + if (str[state] == '\0') { + return 1; + } - if ((rc = gbser_set_port(fd, WBT200BAUD, 8, 0, 1))) { - db(1, "Set baud rate to %d failed (%d)\n", WBT200BAUD, rc); + c = gbser_readc_wait(fd, 500); + if (c < 0) { + db(3, "Got error: %d\n", c); + if (--errors <= 0) { return 0; + } + } else { + db(3, "Got char: %02x '%c'\n", c, isprint(c) ? c : '.'); + if (c == str[state]) { + state++; /* carry on */ + } else { + state = 0; /* go back to start */ + } } + } - wr_cmdl("$PFST,NORMAL"); - return expect("$PFST"); + return 0; } -static int wbt201_try() { - int rc; - - db(1, "Trying WBT201/G-Rays 2\n"); +static int wbt200_try() +{ + int rc; - if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { - db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); - return 0; - } - - wr_cmdl("@AL"); - return expect("@AL"); + db(1, "Trying WBT100/200\n"); + + if ((rc = gbser_set_port(fd, WBT200BAUD, 8, 0, 1))) { + db(1, "Set baud rate to %d failed (%d)\n", WBT200BAUD, rc); + return 0; + } + + wr_cmdl("$PFST,NORMAL"); + return expect("$PFST"); } -static int wsg1000_try() { - int rc; +static int wbt201_try() +{ + int rc; - db(1, "Trying WSG 1000/G-Rays 2\n"); + db(1, "Trying WBT201/G-Rays 2\n"); - if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { - db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); - return 0; - } - - wr_cmdl("@AL,2,3"); - return expect("@AL,2,3,OK"); -} + if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { + db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); + return 0; + } -static int guess_device() { - int i; - db(1, "Guessing device...\n"); - for (i = 0; i < 5; i++) { - if (wbt200_try()) { - return WBT200; - } - if (wbt201_try()) { - return WBT201; - } - if (wsg1000_try()) { - return WSG1000; - } - } - return UNKNOWN; - + wr_cmdl("@AL"); + return expect("@AL"); } -static void rd_init(const char *fname) { - port = xstrdup(fname); +static int wsg1000_try() +{ + int rc; + + db(1, "Trying WSG 1000/G-Rays 2\n"); + + if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { + db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); + return 0; + } + + wr_cmdl("@AL,2,3"); + return expect("@AL,2,3,OK"); +} - db(1, "Opening port...\n"); - if ((fd = gbser_init(port)) == NULL) { - fatal(MYNAME ": Can't initialise port \"%s\"\n", port); +static wintec_gps_types guess_device() +{ + int i; + db(1, "Guessing device...\n"); + for (i = 0; i < 5; i++) { + if (wbt200_try()) { + return WBT200; } - - dev_type = guess_device(); - if (UNKNOWN == dev_type) { - fatal(MYNAME ": Can't determine device type\n"); + if (wbt201_try()) { + return WBT201; } + if (wsg1000_try()) { + return WSG1000; + } + } + return UNKNOWN; + } -static void rd_deinit(void) { - db(1, "Closing port...\n"); - gbser_deinit(fd); - fd = NULL; - xfree(port); +static void rd_init(const char *fname) +{ + port = xstrdup(fname); + + db(1, "Opening port...\n"); + if ((fd = gbser_init(port)) == NULL) { + fatal(MYNAME ": Can't initialise port \"%s\"\n", port); + } + + dev_type = guess_device(); + if (UNKNOWN == dev_type) { + fatal(MYNAME ": Can't determine device type\n"); + } } -static int rd_buf(void *buf, int len) { - int rc; - if (rc = gbser_read_wait(fd, buf, len, TIMEOUT), rc < 0) { - fatal(MYNAME ": Read error (%d)\n", rc); - } else if (rc < len) { - db(2, MYNAME ": Read timout, got %i of %i bytes\n", rc, len); - return 0; - } - return 1; +static void rd_deinit(void) +{ + db(1, "Closing port...\n"); + gbser_deinit(fd); + fd = NULL; + xfree(port); } -static void file_init(const char *fname) { - db(1, "Opening file...\n"); - if ((fl = fopen(fname, "rb")) == NULL) { - fatal(MYNAME ": Can't open file '%s'\n", fname); - } +static int rd_buf(void *buf, int len) +{ + int rc; + if (rc = gbser_read_wait(fd, buf, len, TIMEOUT), rc < 0) { + fatal(MYNAME ": Read error (%d)\n", rc); + } else if (rc < len) { + db(2, MYNAME ": Read timout, got %i of %i bytes\n", rc, len); + return 0; + } + return 1; } -static void file_deinit(void) { - db(1, "Closing file...\n"); - fclose(fl); +static void file_init(const char *fname) +{ + db(1, "Opening file...\n"); + if ((fl = fopen(fname, "rb")) == NULL) { + fatal(MYNAME ": Can't open file '%s'\n", fname); + } } -static int starts_with(const char *buf, const char *pat) { - size_t pat_len = strlen(pat); - return (pat_len <= strlen(buf)) - ? (memcmp(buf, pat, pat_len) == 0) - : 0; +static void file_deinit(void) +{ + db(1, "Closing file...\n"); + fclose(fl); +} + +static int starts_with(const char *buf, const char *pat) +{ + size_t pat_len = strlen(pat); + return (pat_len <= strlen(buf)) + ? (memcmp(buf, pat, pat_len) == 0) + : 0; } /* Send a command then wait for a line starting with the command string * to be returned. */ -static int do_cmd(const char *cmd, const char *expect, char *buf, int len) { - int try; - - rd_drain(); - wr_cmdl(cmd); - - db(2, "Cmd: %s\n", cmd); - - /* We may need to skip a load of data to start with - the unit streams - * NMEA data all the time so it's highly likely that it'll be in the - * middle of an NMEA sentence when we start listening. - */ - for (try = 0; try < RETRIES; try++) { - rd_line(buf, len); - db(3, "Got: %s\n", buf); - if (starts_with(buf, expect)) { - db(2, "Matched: %s\n", buf); - return strlen(expect); - } - db(2, "Skip %d: %s\n", try, buf); +static int do_cmd(const char *cmd, const char *expect, char *buf, int len) +{ + int trycount; + + rd_drain(); + wr_cmdl(cmd); + + db(2, "Cmd: %s\n", cmd); + + /* We may need to skip a load of data to start with - the unit streams + * NMEA data all the time so it's highly likely that it'll be in the + * middle of an NMEA sentence when we start listening. + */ + for (trycount = 0; trycount < RETRIES; trycount++) { + rd_line(buf, len); + db(3, "Got: %s\n", buf); + if (starts_with(buf, expect)) { + db(2, "Matched: %s\n", buf); + return strlen(expect); } + db(2, "Skip %d: %s\n", trycount, buf); + } - fatal(MYNAME ": Bad response from unit\n"); - return 0; /* keep compiler quiet */ + fatal(MYNAME ": Bad response from unit\n"); + return 0; /* keep compiler quiet */ } /* Issue a command that expects the same string to be echoed * back as an ACK */ -static int do_simple(const char *cmd, char *buf, int len) { - return do_cmd(cmd, cmd, buf, len); +static int do_simple(const char *cmd, char *buf, int len) +{ + return do_cmd(cmd, cmd, buf, len); } -static char *get_param(const char *cmd, char *buf, int len) { - int cl = do_simple(cmd, buf, len); - return buf + cl + 1; +static char *get_param(const char *cmd, char *buf, int len) +{ + int cl = do_simple(cmd, buf, len); + return buf + cl + 1; } -static int get_param_int(const char *cmd) { - char buf[80]; - return atoi(get_param(cmd, buf, sizeof(buf))); +static int get_param_int(const char *cmd) +{ + char buf[80]; + return atoi(get_param(cmd, buf, sizeof(buf))); } -static double get_param_float(const char *cmd) { - char buf[80]; - return atof(get_param(cmd, buf, sizeof(buf))); +static double get_param_float(const char *cmd) +{ + char buf[80]; + return atof(get_param(cmd, buf, sizeof(buf))); } /* Decompose binary date into discreet fields */ @@ -479,597 +513,620 @@ static double get_param_float(const char *cmd) { int mon = (((tim) >> 22) & 0x0F); \ int year = (((tim) >> 26) & 0x3F); -static time_t decode_date(gbuint32 tim) { - _SPLIT_DATE(tim) - struct tm t; +static time_t decode_date(gbuint32 tim) +{ + _SPLIT_DATE(tim) + struct tm t; - t.tm_sec = sec; - t.tm_min = min; - t.tm_hour = hour; - t.tm_mday = mday; - t.tm_mon = mon - 1; - t.tm_year = year + 100; + t.tm_sec = sec; + t.tm_min = min; + t.tm_hour = hour; + t.tm_mday = mday; + t.tm_mon = mon - 1; + t.tm_year = year + 100; - return mkgmtime(&t); + return mkgmtime(&t); } -static int check_date(gbuint32 tim) { - _SPLIT_DATE(tim) +static int check_date(gbuint32 tim) +{ + _SPLIT_DATE(tim) - /* Sanity check the date. We don't allow years prior to 2004 because zero in - * those bits will usually indicate that we have an altitude instead of a - * date (i.e. that the data is the new format that uses 16 byte records). - */ - return sec < 60 && min < 60 && hour < 24 && - mday > 0 && mday <= 31 && mon > 0 && mon <= 12 && year >= 4; + /* Sanity check the date. We don't allow years prior to 2004 because zero in + * those bits will usually indicate that we have an altitude instead of a + * date (i.e. that the data is the new format that uses 16 byte records). + */ + return sec < 60 && min < 60 && hour < 24 && + mday > 0 && mday <= 31 && mon > 0 && mon <= 12 && year >= 4; } -static waypoint *make_point(double lat, double lon, double alt, time_t tim, const char *fmt, int index) { - char wp_name[20]; - waypoint *wpt = waypt_new(); +static waypoint *make_point(double lat, double lon, double alt, time_t tim, const char *fmt, int index) +{ + char wp_name[20]; + waypoint *wpt = waypt_new(); - sprintf(wp_name, fmt, index); + sprintf(wp_name, fmt, index); - wpt->latitude = lat;; - wpt->longitude = lon; - wpt->altitude = alt; - wpt->creation_time = tim; - wpt->shortname = xstrdup(wp_name); - - return wpt; -} + wpt->latitude = lat;; + wpt->longitude = lon; + wpt->altitude = alt; + wpt->creation_time = tim; + wpt->shortname = xstrdup(wp_name); -static waypoint *make_waypoint(struct read_state *st, double lat, double lon, double alt, time_t tim) { - return make_point(lat, lon, alt, tim, "WP%04d", ++st->wpn); + return wpt; } -static waypoint *make_trackpoint(struct read_state *st, double lat, double lon, double alt, time_t tim) { - return make_point(lat, lon, alt, tim, "TP%04d", ++st->tpn); +static waypoint *make_waypoint(struct read_state *st, double lat, double lon, double alt, time_t tim) +{ + return make_point(lat, lon, alt, tim, "WP%04d", ++st->wpn); } -static int wbt200_data_chunk(struct read_state *st, const void *buf, int fmt) { - gbuint32 tim; - double lat, lon, alt; - time_t rtim; - waypoint *tpt = NULL; - const char *bp = buf; - size_t buf_used = fmt_version[fmt].reclen; - - tim = le_read32(bp + 0); - - lat = (double) ((gbint32) le_read32(bp + 4)) / 10000000; - lon = (double) ((gbint32) le_read32(bp + 8)) / 10000000; - - /* Handle extra fields in longer records here. */ - if (buf_used >= 16) { - alt = (double) le_read32(bp + 12) / 10; - } else { - alt = unknown_alt; - } - - rtim = decode_date(tim); - - if (lat >= 100) { - /* Start new track in the northern hemisphere */ - lat -= 100; - st->route_head = NULL; - } else if (lat <= -100) { - /* Start new track in the southern hemisphere */ - /* This fix courtesy of Anton Frolich */ - lat += 100; - st->route_head = NULL; - } - - tpt = make_trackpoint(st, lat, lon, alt, rtim); - - if (NULL == st->route_head) { - db(1, "New Track\n"); - st->route_head = route_head_alloc(); - track_add_head(st->route_head); - } - - track_add_wpt(st->route_head, tpt); +static waypoint *make_trackpoint(struct read_state *st, double lat, double lon, double alt, time_t tim) +{ + return make_point(lat, lon, alt, tim, "TP%04d", ++st->tpn); +} - return 1; +static int wbt200_data_chunk(struct read_state *st, const void *buf, int fmt) +{ + gbuint32 tim; + double lat, lon, alt; + time_t rtim; + waypoint *tpt = NULL; + const char *bp = (const char*) buf; + size_t buf_used = fmt_version[fmt].reclen; + + tim = le_read32(bp + 0); + + lat = (double)((gbint32) le_read32(bp + 4)) / 10000000; + lon = (double)((gbint32) le_read32(bp + 8)) / 10000000; + + /* Handle extra fields in longer records here. */ + if (buf_used >= 16) { + alt = (double) le_read32(bp + 12) / 10; + } else { + alt = unknown_alt; + } + + rtim = decode_date(tim); + + if (lat >= 100) { + /* Start new track in the northern hemisphere */ + lat -= 100; + st->route_head_ = NULL; + } else if (lat <= -100) { + /* Start new track in the southern hemisphere */ + /* This fix courtesy of Anton Frolich */ + lat += 100; + st->route_head_ = NULL; + } + + tpt = make_trackpoint(st, lat, lon, alt, rtim); + + if (NULL == st->route_head_) { + db(1, "New Track\n"); + st->route_head_ = route_head_alloc(); + track_add_head(st->route_head_); + } + + track_add_wpt(st->route_head_, tpt); + + return 1; } /* Return true iff the data appears valid with the specified record length */ -static int is_valid(struct buf_head *h, int fmt) { - char buf[RECLEN_MAX]; - size_t reclen = fmt_version[fmt].reclen; +static int is_valid(struct buf_head *h, int fmt) +{ + char buf[RECLEN_MAX]; + size_t reclen = fmt_version[fmt].reclen; - buf_rewind(h); + buf_rewind(h); - db(2, "Checking %lu bytes of data against format %d\n", h->used, fmt); + db(2, "Checking %lu bytes of data against format %d\n", h->used, fmt); - for (;;) { - size_t got = buf_read(h, buf, reclen); - gbuint32 tim; - /* Don't mind odd bytes at the end - we may - * be examining an incomplete dataset. - */ - if (got != reclen) { - break; - } + for (;;) { + size_t got = buf_read(h, buf, reclen); + gbuint32 tim; + /* Don't mind odd bytes at the end - we may + * be examining an incomplete dataset. + */ + if (got != reclen) { + break; + } - tim = le_read32(buf + 0); - if (!check_date(tim)) { - return 0; - } + tim = le_read32(buf + 0); + if (!check_date(tim)) { + return 0; + } - if (reclen > 12) { + if (reclen > 12) { #ifdef MAXALT - gbuint32 alt = le_read32(buf + 12); - if (alt > MAXALT * 10) { - return 0; - } + gbuint32 alt = le_read32(buf + 12); + if (alt > MAXALT * 10) { + return 0; + } #endif - } } + } - return 1; + return 1; } -static void wbt200_process_data(struct read_state *pst, int fmt) { - char buf[RECLEN_MAX]; - size_t reclen = fmt_version[fmt].reclen; +static void wbt200_process_data(struct read_state *pst, int fmt) +{ + char buf[RECLEN_MAX]; + size_t reclen = fmt_version[fmt].reclen; - buf_rewind(&pst->data); + buf_rewind(&pst->data); - db(2, "Processing %lu bytes of data using format %d\n", pst->data.used, fmt); + db(2, "Processing %lu bytes of data using format %d\n", pst->data.used, fmt); - for (;;) { - size_t got = buf_read(&pst->data, buf, reclen); - if (got != reclen) { - break; - } - wbt200_data_chunk(pst, buf, fmt); + for (;;) { + size_t got = buf_read(&pst->data, buf, reclen); + if (got != reclen) { + break; } + wbt200_data_chunk(pst, buf, fmt); + } } -static void state_init(struct read_state *pst) { - pst->route_head = NULL; - pst->wpn = 0; - pst->tpn = 0; +static void state_init(struct read_state *pst) +{ + pst->route_head_ = NULL; + pst->wpn = 0; + pst->tpn = 0; - buf_init(&pst->data, RECLEN_V1 * RECLEN_V2); + buf_init(&pst->data, RECLEN_V1 * RECLEN_V2); } -static void state_empty(struct read_state *pst) { - buf_empty(&pst->data); - state_init(pst); +static void state_empty(struct read_state *pst) +{ + buf_empty(&pst->data); + state_init(pst); } -static int want_bytes(struct buf_head *h, size_t len) { - char buf[512]; +static int want_bytes(struct buf_head *h, size_t len) +{ + char buf[512]; - db(3, "Reading %lu bytes from device\n", (unsigned long) len); + db(3, "Reading %lu bytes from device\n", (unsigned long) len); - while (len > 0) { - size_t want = sizeof(buf); - if (want > len) { want = len; } - if (!rd_buf(buf, want)) - return 0; - buf_write(h, buf, want); - len -= want; + while (len > 0) { + size_t want = sizeof(buf); + if (want > len) { + want = len; + } + if (!rd_buf(buf, want)) { + return 0; } - return 1; + buf_write(h, buf, want); + len -= want; + } + return 1; } -static void wbt200_data_read(void) { - /* Awooga! Awooga! Statically allocated buffer danger! - * Actually, it's OK because rd_line can read arbitrarily - * long lines returning only the first N characters - */ - char line_buf[100]; - int fmt; - unsigned long count; - struct read_state st; - - state_init(&st); - - /* We could potentially parse the version string to find out which - * data format to use - but it's not clear how the version string - * will increment in the future - so just now it's more future- - * proof to rely on analysing the data. We need to be able to do - * that with files anyway - because they're not versioned. - */ - do_simple("$PFST,FIRMWAREVERSION", BUFSPEC(line_buf)); - - do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); - do_simple("$PFST,READLOGGER", BUFSPEC(line_buf)); +static void wbt200_data_read(void) +{ + /* Awooga! Awooga! Statically allocated buffer danger! + * Actually, it's OK because rd_line can read arbitrarily + * long lines returning only the first N characters + */ + char line_buf[100]; + int fmt; + unsigned long count; + struct read_state st; + + state_init(&st); + + /* We could potentially parse the version string to find out which + * data format to use - but it's not clear how the version string + * will increment in the future - so just now it's more future- + * proof to rely on analysing the data. We need to be able to do + * that with files anyway - because they're not versioned. + */ + do_simple("$PFST,FIRMWAREVERSION", BUFSPEC(line_buf)); + + do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); + do_simple("$PFST,READLOGGER", BUFSPEC(line_buf)); + + /* Now we're into binary mode */ + rd_buf(line_buf, 6); /* six byte header */ + count = le_read16(line_buf + 2) + 1; + if (count == 0x10000) { + count = 0; + } + + db(3, "%lu points available\n", count); + + /* Loop through the known formats requesting more data from the + * device each time. When the device contains only a single + * point the first format will get a false positive - so we'll + * lose the altitude data. + */ + for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { + size_t reclen = fmt_version[fmt].reclen; + size_t want = reclen * count; - /* Now we're into binary mode */ - rd_buf(line_buf, 6); /* six byte header */ - count = le_read16(line_buf + 2) + 1; - if (count == 0x10000) { - count = 0; + if (want < st.data.used) { + fatal(MYNAME ": Internal error: formats not ordered in ascending size order\n"); } - db(3, "%lu points available\n", count); + db(3, "Want %lu bytes of data\n", (unsigned long) want); - /* Loop through the known formats requesting more data from the - * device each time. When the device contains only a single - * point the first format will get a false positive - so we'll - * lose the altitude data. - */ - for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { - size_t reclen = fmt_version[fmt].reclen; - size_t want = reclen * count; + /* Top up the buffer */ + want_bytes(&st.data, want - st.data.used); - if (want < st.data.used) { - fatal(MYNAME ": Internal error: formats not ordered in ascending size order\n"); - } + /* And see if it's valid */ + if (is_valid(&st.data, fmt)) { + break; + } + } - db(3, "Want %lu bytes of data\n", (unsigned long) want); + if (fmt_version[fmt].reclen == 0) { + fatal(MYNAME ": Can't autodetect data format\n"); + } - /* Top up the buffer */ - want_bytes(&st.data, want - st.data.used); + wbt200_process_data(&st, fmt); - /* And see if it's valid */ - if (is_valid(&st.data, fmt)) { - break; - } - } + /* Erase data? */ - if (fmt_version[fmt].reclen == 0) { - fatal(MYNAME ": Can't autodetect data format\n"); + if (*erase != '0') { + int f; + db(1, "Erasing data\n"); + for (f = 27; f <= 31; f++) { + sprintf(line_buf, "$PFST,REMOVEFILE,%d", f); + do_cmd(line_buf, "$PFST,REMOVEFILE", BUFSPEC(line_buf)); } - - wbt200_process_data(&st, fmt); - - /* Erase data? */ - - if (*erase != '0') { - int f; - db(1, "Erasing data\n"); - for (f = 27; f <= 31; f++) { - sprintf(line_buf, "$PFST,REMOVEFILE,%d", f); - do_cmd(line_buf, "$PFST,REMOVEFILE", BUFSPEC(line_buf)); - } - db(1, "Reclaiming free space\n"); - for (f = 0; f <= 3; f++) { - sprintf(line_buf, "$PFST,FFSRECLAIM,%d", f); - do_cmd(line_buf, "$PFST,FFSRECLAIM", BUFSPEC(line_buf)); - } + db(1, "Reclaiming free space\n"); + for (f = 0; f <= 3; f++) { + sprintf(line_buf, "$PFST,FFSRECLAIM,%d", f); + do_cmd(line_buf, "$PFST,FFSRECLAIM", BUFSPEC(line_buf)); } + } - do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); + do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); - state_empty(&st); + state_empty(&st); } -static int all_null(const void *buf, const int len) { - const char *bp = buf; - int i; +static int all_null(const void *buf, const int len) +{ + const char *bp = (const char *) buf; + int i; - for (i = 0; i < len; i++) { - if (bp[i]) { - return 0; - } + for (i = 0; i < len; i++) { + if (bp[i]) { + return 0; } + } - return 1; + return 1; } -static int wbt201_data_chunk(struct read_state *st, const void *buf) { - gbuint32 tim; - gbuint16 flags; - double lat, lon, alt; - time_t rtim; - waypoint *tpt = NULL; - const char *bp = buf; - - /* Zero records are skipped */ - if (all_null(buf, RECLEN_WBT201)) { - return 1; - } +static int wbt201_data_chunk(struct read_state *st, const void *buf) +{ + gbuint32 tim; + gbuint16 flags; + double lat, lon, alt; + time_t rtim; + waypoint *tpt = NULL; + const char *bp = (const char *) buf; + + /* Zero records are skipped */ + if (all_null(buf, RECLEN_WBT201)) { + return 1; + } - flags = le_read16(bp + 0); - tim = le_read32(bp + 2); + flags = le_read16(bp + 0); + tim = le_read32(bp + 2); - if (TK1_END_FLAG == tim) { - /* EOF? (TK1 files only as far as I know) */ - return 0; - } - - lat = (double) ((gbint32) le_read32(bp + 6)) / 10000000; - lon = (double) ((gbint32) le_read32(bp + 10)) / 10000000; - alt = (double) ((gbint16) le_read16(bp + 14)); + if (TK1_END_FLAG == tim) { + /* EOF? (TK1 files only as far as I know) */ + return 0; + } - rtim = decode_date(tim); + lat = (double)((gbint32) le_read32(bp + 6)) / 10000000; + lon = (double)((gbint32) le_read32(bp + 10)) / 10000000; + alt = (double)((gbint16) le_read16(bp + 14)); - if ((flags & WBT201_WAYPOINT) && (global_opts.masked_objective & WPTDATAMASK)) { - waypoint *wpt = make_waypoint(st, lat, lon, alt, rtim); - waypt_add(wpt); - } + rtim = decode_date(tim); - if (global_opts.masked_objective & TRKDATAMASK) { - if (flags & WBT201_TRACK_START) { - st->route_head = NULL; - } + if ((flags & WBT201_WAYPOINT) && (global_opts.masked_objective & WPTDATAMASK)) { + waypoint *wpt = make_waypoint(st, lat, lon, alt, rtim); + waypt_add(wpt); + } - tpt = make_trackpoint(st, lat, lon, alt, rtim); + if (global_opts.masked_objective & TRKDATAMASK) { + if (flags & WBT201_TRACK_START) { + st->route_head_ = NULL; + } - if (NULL == st->route_head) { - db(1, "New Track\n"); - st->route_head = route_head_alloc(); - track_add_head(st->route_head); - } + tpt = make_trackpoint(st, lat, lon, alt, rtim); - track_add_wpt(st->route_head, tpt); + if (NULL == st->route_head_) { + db(1, "New Track\n"); + st->route_head_ = route_head_alloc(); + track_add_head(st->route_head_); } - return 1; + track_add_wpt(st->route_head_, tpt); + } + + return 1; } -static void wbt201_process_chunk(struct read_state *st) { - char buf[RECLEN_WBT201]; +static void wbt201_process_chunk(struct read_state *st) +{ + char buf[RECLEN_WBT201]; - db(2, "Processing %lu bytes of data\n", st->data.used); + db(2, "Processing %lu bytes of data\n", st->data.used); - while (buf_read(&st->data, buf, sizeof(buf)) == sizeof(buf) - && wbt201_data_chunk(st, buf)) { - /* do nothing */ - } + while (buf_read(&st->data, buf, sizeof(buf)) == sizeof(buf) + && wbt201_data_chunk(st, buf)) { + /* do nothing */ + } } -static int wbt201_read_chunk(struct read_state *st, unsigned pos, unsigned limit) { - char cmd_buf[30]; - char line_buf[100]; - unsigned long cs; - char *lp, *op; - static char *cs_prefix = "@AL,CS,"; +static int wbt201_read_chunk(struct read_state *st, unsigned pos, unsigned limit) +{ + char cmd_buf[30]; + char line_buf[100]; + unsigned long cs; + char *lp, *op; + static char *cs_prefix = "@AL,CS,"; - unsigned want = limit - pos; - if (want > WBT201CHUNK) { - want = WBT201CHUNK; - } + unsigned want = limit - pos; + if (want > WBT201CHUNK) { + want = WBT201CHUNK; + } - db(3, "Reading bytes at %u (0x%x), limit = %u (0x%x), want = %u (0x%x)\n", - pos, pos, limit, limit, want, want); + db(3, "Reading bytes at %u (0x%x), limit = %u (0x%x), want = %u (0x%x)\n", + pos, pos, limit, limit, want, want); - buf_empty(&st->data); + buf_empty(&st->data); - rd_drain(); - sprintf(cmd_buf, "@AL,5,3,%d", pos); - wr_cmdl(cmd_buf); + rd_drain(); + sprintf(cmd_buf, "@AL,5,3,%d", pos); + wr_cmdl(cmd_buf); - - if (!want_bytes(&st->data, want)) - return 0; - /* checksum */ - rd_line(BUFSPEC(line_buf)); + if (!want_bytes(&st->data, want)) { + return 0; + } - if (!starts_with(line_buf, cs_prefix)) { - db(2, "Bad checksum response\n"); - return 0; - } + /* checksum */ + rd_line(BUFSPEC(line_buf)); - lp = line_buf + strlen(cs_prefix); - cs = strtoul(lp, &op, 16); - if (*lp == ',' || *op != ',') { - db(2, "Badly formed checksum\n"); - return 0; - } + if (!starts_with(line_buf, cs_prefix)) { + db(2, "Bad checksum response\n"); + return 0; + } - if (cs != st->data.checksum) { - db(2, "Checksums don't match. Got %02x, expected %02\n", cs, st->data.checksum); - return 0; - } - - /* ack */ -/* rd_line(BUFSPEC(line_buf)); + lp = line_buf + strlen(cs_prefix); + cs = strtoul(lp, &op, 16); + if (*lp == ',' || *op != ',') { + db(2, "Badly formed checksum\n"); + return 0; + } + + if (cs != st->data.checksum) { + db(2, "Checksums don't match. Got %02x, expected %02\n", cs, st->data.checksum); + return 0; + } + + /* ack */ + /* rd_line(BUFSPEC(line_buf)); + return starts_with(line_buf, cmd_buf); + */ + if (dev_type == WBT201) { + rd_line(BUFSPEC(line_buf)); return starts_with(line_buf, cmd_buf); -*/ - if (dev_type == WBT201){ - rd_line(BUFSPEC(line_buf)); - return starts_with(line_buf, cmd_buf); - } - return 1; - + } + return 1; + } -static void wbt201_data_read(void) { - char line_buf[100]; - struct read_state st; - unsigned tries; - - const char *tmp; - - double ver_hw; - double ver_sw; - double ver_fmt; - - unsigned log_addr_start; - unsigned log_addr_end; - unsigned log_area_start; - unsigned log_area_end; - - unsigned wantbytes; - unsigned read_pointer; - unsigned read_limit; - - /* Read various device information. We don't use much of this yet - - * just log_addr_start and log_addr_end - but it's useful to have it - * here for debug and documentation purposes. - */ - tmp = get_param("@AL,7,1", BUFSPEC(line_buf)); - db(1, "Reading device \"%s\"\n", tmp); - - ver_hw = get_param_float("@AL,8,1"); - ver_sw = get_param_float("@AL,8,2"); - ver_fmt = get_param_float("@AL,8,3"); - - db(2, "versions: hw=%f, sw=%f, fmt=%f\n", - ver_hw, ver_sw, ver_fmt); - - log_addr_start = get_param_int("@AL,5,1"); /* we read from here... */ - log_addr_end = get_param_int("@AL,5,2"); /* ...to here, but ... */ - log_area_start = get_param_int("@AL,5,9"); /* ...we need these when ... */ - log_area_end = get_param_int("@AL,5,10"); /* ...the gps wrote more then it fits in memory */ - - db(2, "Log addr=(%d..%d), area=(%d..%d)\n", - log_addr_start, log_addr_end, - log_area_start, log_area_end); - - state_init(&st); - - tries = 10; - - /* If the WBT-201 device logs more then the memory can handle it continues to write at the beginning of the memory, - * thus overwriting the oldest tracks. In this case log_addr_end is smaller then log_addr_start and we need to read - * from log_addr_start to log_area_end and then from log_area_start to log_addr_end. - */ - - wantbytes = (log_addr_start < log_addr_end) ? log_addr_end - log_addr_start : log_area_end - (log_addr_start - log_addr_end); - read_pointer = log_addr_start; - read_limit = (log_addr_start < log_addr_end) ? log_addr_end : log_area_end; - - db(2, "Want %d bytes from device\n", wantbytes); - while (wantbytes > 0) { - db(2, "Read params: Want %d bytes, read_pointer = %d, read_limit = %d\n", wantbytes, read_pointer, read_limit); - if (wbt201_read_chunk(&st, read_pointer, read_limit)) { - buf_rewind(&st.data); - wbt201_process_chunk(&st); - wantbytes -= st.data.used; - read_pointer += st.data.used; - if (read_pointer >= log_area_end) - { - read_pointer = log_area_start; - read_limit = log_addr_end; - } - } else { - if (--tries <= 0) { - fatal(MYNAME ": Too many data errors during read\n"); - } - } +static void wbt201_data_read(void) +{ + char line_buf[100]; + struct read_state st; + unsigned tries; + + const char *tmp; + + double ver_hw; + double ver_sw; + double ver_fmt; + + unsigned log_addr_start; + unsigned log_addr_end; + unsigned log_area_start; + unsigned log_area_end; + + unsigned wantbytes; + unsigned read_pointer; + unsigned read_limit; + + /* Read various device information. We don't use much of this yet - + * just log_addr_start and log_addr_end - but it's useful to have it + * here for debug and documentation purposes. + */ + tmp = get_param("@AL,7,1", BUFSPEC(line_buf)); + db(1, "Reading device \"%s\"\n", tmp); + + ver_hw = get_param_float("@AL,8,1"); + ver_sw = get_param_float("@AL,8,2"); + ver_fmt = get_param_float("@AL,8,3"); + + db(2, "versions: hw=%f, sw=%f, fmt=%f\n", + ver_hw, ver_sw, ver_fmt); + + log_addr_start = get_param_int("@AL,5,1"); /* we read from here... */ + log_addr_end = get_param_int("@AL,5,2"); /* ...to here, but ... */ + log_area_start = get_param_int("@AL,5,9"); /* ...we need these when ... */ + log_area_end = get_param_int("@AL,5,10"); /* ...the gps wrote more then it fits in memory */ + + db(2, "Log addr=(%d..%d), area=(%d..%d)\n", + log_addr_start, log_addr_end, + log_area_start, log_area_end); + + state_init(&st); + + tries = 10; + + /* If the WBT-201 device logs more then the memory can handle it continues to write at the beginning of the memory, + * thus overwriting the oldest tracks. In this case log_addr_end is smaller then log_addr_start and we need to read + * from log_addr_start to log_area_end and then from log_area_start to log_addr_end. + */ + + wantbytes = (log_addr_start < log_addr_end) ? log_addr_end - log_addr_start : log_area_end - (log_addr_start - log_addr_end); + read_pointer = log_addr_start; + read_limit = (log_addr_start < log_addr_end) ? log_addr_end : log_area_end; + + db(2, "Want %d bytes from device\n", wantbytes); + while (wantbytes > 0) { + db(2, "Read params: Want %d bytes, read_pointer = %d, read_limit = %d\n", wantbytes, read_pointer, read_limit); + if (wbt201_read_chunk(&st, read_pointer, read_limit)) { + buf_rewind(&st.data); + wbt201_process_chunk(&st); + wantbytes -= st.data.used; + read_pointer += st.data.used; + if (read_pointer >= log_area_end) { + read_pointer = log_area_start; + read_limit = log_addr_end; + } + } else { + if (--tries <= 0) { + fatal(MYNAME ": Too many data errors during read\n"); + } } + } - if (*erase != '0') { - /* erase device */ - do_simple("@AL,5,6", BUFSPEC(line_buf)); - } + if (*erase != '0') { + /* erase device */ + do_simple("@AL,5,6", BUFSPEC(line_buf)); + } - state_empty(&st); - do_simple("@AL,2,1", BUFSPEC(line_buf)); + state_empty(&st); + do_simple("@AL,2,1", BUFSPEC(line_buf)); } -static void file_read(void) { - char buf[512]; - size_t rc; - struct read_state st; - int fmt; +static void file_read(void) +{ + char buf[512]; + size_t rc; + struct read_state st; + int fmt; - const char * tk1_magic = TK1_MAGIC; - size_t tk1_magic_len = strlen(tk1_magic) + 1; + const char * tk1_magic = TK1_MAGIC; + size_t tk1_magic_len = strlen(tk1_magic) + 1; - state_init(&st); + state_init(&st); - /* Read the whole file into the buffer */ + /* Read the whole file into the buffer */ + rc = fread(buf, 1, sizeof(buf), fl); + while (rc != 0) { + buf_write(&st.data, buf, rc); rc = fread(buf, 1, sizeof(buf), fl); - while (rc != 0) { - buf_write(&st.data, buf, rc); - rc = fread(buf, 1, sizeof(buf), fl); - } + } - if (!feof(fl)) { - fatal(MYNAME ": Read error\n"); - } + if (!feof(fl)) { + fatal(MYNAME ": Read error\n"); + } - /* Although wbt-tk1 and wbt-bin are enumerated as distinct formats - * we handle them both here and autodetect which type we have. - */ + /* Although wbt-tk1 and wbt-bin are enumerated as distinct formats + * we handle them both here and autodetect which type we have. + */ - /* WBT201 TK1 format? */ + /* WBT201 TK1 format? */ + buf_rewind(&st.data); + buf_read(&st.data, buf, tk1_magic_len); + if (memcmp(buf, tk1_magic, tk1_magic_len) == 0) { + db(1, "Got TK1 file\n"); buf_rewind(&st.data); - buf_read(&st.data, buf, tk1_magic_len); - if (memcmp(buf, tk1_magic, tk1_magic_len) == 0) { - db(1, "Got TK1 file\n"); - buf_rewind(&st.data); - /* Seek */ - buf_read(&st.data, NULL, TK1_DATA_OFFSET); - wbt201_process_chunk(&st); + /* Seek */ + buf_read(&st.data, NULL, TK1_DATA_OFFSET); + wbt201_process_chunk(&st); + } else { + db(1, "Got bin file\n"); + + /* Try to guess the data format */ + for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { + size_t reclen = fmt_version[fmt].reclen; + if ((st.data.used % reclen) == 0 && is_valid(&st.data, fmt)) { + break; + } } - else { - db(1, "Got bin file\n"); - - /* Try to guess the data format */ - for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { - size_t reclen = fmt_version[fmt].reclen; - if ((st.data.used % reclen) == 0 && is_valid(&st.data, fmt)) { - break; - } - } - - if (fmt_version[fmt].reclen == 0) { - fatal(MYNAME ": Can't autodetect data format\n"); - } - - wbt200_process_data(&st, fmt); + + if (fmt_version[fmt].reclen == 0) { + fatal(MYNAME ": Can't autodetect data format\n"); } - state_empty(&st); + wbt200_process_data(&st, fmt); + } + + state_empty(&st); } -static void data_read(void) { - switch (dev_type) { - case WBT200: - wbt200_data_read(); - break; - case WBT201: - wbt201_data_read(); - break; - case WSG1000: - wbt201_data_read(); - break; - - default: - fatal(MYNAME ": Unknown device type (internal)\n"); - break; - } +static void data_read(void) +{ + switch (dev_type) { + case WBT200: + wbt200_data_read(); + break; + case WBT201: + wbt201_data_read(); + break; + case WSG1000: + wbt201_data_read(); + break; + + default: + fatal(MYNAME ": Unknown device type (internal)\n"); + break; + } } /* wbt */ static arglist_t wbt_sargs[] = { - { "erase", &erase, "Erase device data after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "erase", &erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t wbt_svecs = { - ff_type_serial, - { ff_cap_read, ff_cap_read, ff_cap_none }, - rd_init, - NULL, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - wbt_sargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_serial, + { ff_cap_read, ff_cap_read, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + wbt_sargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; /* used for wbt-bin /and/ wbt-tk1 */ static arglist_t wbt_fargs[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; ff_vecs_t wbt_fvecs = { - ff_type_file, - { ff_cap_none, ff_cap_read, ff_cap_none }, - file_init, - NULL, - file_deinit, - NULL, - file_read, - NULL, - NULL, - wbt_fargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none }, + file_init, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + wbt_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; diff --git a/gpsbabel/wfff_xml.c b/gpsbabel/wfff_xml.c index ffa4bb6ac..1379f0e6c 100644 --- a/gpsbabel/wfff_xml.c +++ b/gpsbabel/wfff_xml.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2006 Etienne Tasse etasse@yahoo.com This program is free software; you can redistribute it and/or modify @@ -28,16 +28,24 @@ static char * snmac =0; static arglist_t wfff_xml_args[] = { - {"aicicon", &aicicon, "Infrastructure closed icon name", - "Red Square", ARGTYPE_STRING }, - {"aioicon", &aioicon, "Infrastructure open icon name", - "Green Square", ARGTYPE_STRING }, - {"ahcicon", &ahcicon, "Ad-hoc closed icon name", - "Red Diamond", ARGTYPE_STRING }, - {"ahoicon", &ahoicon, "Ad-hoc open icon name", - "Green Diamond", ARGTYPE_STRING }, - {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + { + "aicicon", &aicicon, "Infrastructure closed icon name", + "Red Square", ARGTYPE_STRING + }, + { + "aioicon", &aioicon, "Infrastructure open icon name", + "Green Square", ARGTYPE_STRING + }, + { + "ahcicon", &ahcicon, "Ad-hoc closed icon name", + "Red Diamond", ARGTYPE_STRING + }, + { + "ahoicon", &ahoicon, "Ad-hoc open icon name", + "Green Diamond", ARGTYPE_STRING + }, + {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL }, + {0, 0, 0, 0, 0} }; #define xfreez(p) { if (p) xfree(p); p=0; } @@ -49,7 +57,7 @@ arglist_t wfff_xml_args[] = { void wfff_xml_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded WFFF_XML support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded WFFF_XML support because expat was not installed.\n"); } void wfff_xml_read(void) @@ -69,23 +77,23 @@ static xg_callback wfff_mnrssi, wfff_mxrssi; static xg_callback wfff_first, wfff_last; static xg_callback wfff_hdop, wfff_lat, wfff_lon; -static +static xg_tag_mapping loc_map[] = { - { wfff_s, cb_start, "/DocumentElement/AP" }, - { wfff_e, cb_end, "/DocumentElement/AP" }, - { wfff_wep, cb_cdata, "/DocumentElement/AP/WEP" }, - { wfff_mac, cb_cdata, "/DocumentElement/AP/MAC" }, - { wfff_ssid, cb_cdata, "/DocumentElement/AP/SSID" }, - { wfff_type, cb_cdata, "/DocumentElement/AP/Type" }, - { wfff_mnrssi, cb_cdata, "/DocumentElement/AP/MinRSSI" }, - { wfff_mxrssi, cb_cdata, "/DocumentElement/AP/MaxRSSI" }, - { wfff_chan, cb_cdata, "/DocumentElement/AP/Channel" }, - { wfff_first, cb_cdata, "/DocumentElement/AP/FirstSeen" }, - { wfff_last, cb_cdata, "/DocumentElement/AP/LastSeen" }, - { wfff_hdop, cb_cdata, "/DocumentElement/AP/HDOP" }, - { wfff_lat, cb_cdata, "/DocumentElement/AP/Lat" }, - { wfff_lon, cb_cdata, "/DocumentElement/AP/Lon" }, - { 0,0,0 } + { wfff_s, cb_start, "/DocumentElement/AP" }, + { wfff_e, cb_end, "/DocumentElement/AP" }, + { wfff_wep, cb_cdata, "/DocumentElement/AP/WEP" }, + { wfff_mac, cb_cdata, "/DocumentElement/AP/MAC" }, + { wfff_ssid, cb_cdata, "/DocumentElement/AP/SSID" }, + { wfff_type, cb_cdata, "/DocumentElement/AP/Type" }, + { wfff_mnrssi, cb_cdata, "/DocumentElement/AP/MinRSSI" }, + { wfff_mxrssi, cb_cdata, "/DocumentElement/AP/MaxRSSI" }, + { wfff_chan, cb_cdata, "/DocumentElement/AP/Channel" }, + { wfff_first, cb_cdata, "/DocumentElement/AP/FirstSeen" }, + { wfff_last, cb_cdata, "/DocumentElement/AP/LastSeen" }, + { wfff_hdop, cb_cdata, "/DocumentElement/AP/HDOP" }, + { wfff_lat, cb_cdata, "/DocumentElement/AP/Lat" }, + { wfff_lon, cb_cdata, "/DocumentElement/AP/Lon" }, + { 0,(xg_cb_type)0,0 } }; /* work variables for wfff_xxx */ @@ -103,83 +111,105 @@ static double ap_lat =0.0; static double ap_lon =0.0; /* Start of AP block */ -void wfff_s(const char *args, const char **unused) -{ - xfreez(ap_mac); - xfreez(ap_ssid); - xfreez(ap_type); - xfreez(ap_wep); - xfreez(ap_last); - ap_mnrssi=0.0; - ap_mxrssi=0.0; - ap_chan=0; - ap_hdop=0.0; - ap_first=0; - ap_last=0; - ap_lat=0.0; - ap_lon=0.0; +void wfff_s(const char *args, const char **unused) +{ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + ap_mnrssi=0.0; + ap_mxrssi=0.0; + ap_chan=0; + ap_hdop=0.0; + ap_first=0; + ap_last=0; + ap_lat=0.0; + ap_lon=0.0; } void wfff_mac(const char *args, const char **unused) { - if (args) ap_mac = xstrdup(args); + if (args) { + ap_mac = xstrdup(args); + } } void wfff_ssid(const char *args, const char **unused) { - if (args) ap_ssid = xstrdup(args); + if (args) { + ap_ssid = xstrdup(args); + } } void wfff_type(const char *args, const char **unused) { - if (args) ap_type = xstrdup(args); + if (args) { + ap_type = xstrdup(args); + } } void wfff_mnrssi(const char *args, const char **unused) { - if (args) ap_mnrssi = atof(args); + if (args) { + ap_mnrssi = atof(args); + } } void wfff_mxrssi(const char *args, const char **unused) { - if (args) ap_mxrssi = atof(args); + if (args) { + ap_mxrssi = atof(args); + } } void wfff_chan(const char *args, const char **unused) { - if (args) ap_chan = atoi(args); + if (args) { + ap_chan = atoi(args); + } } void wfff_first(const char *args, const char **unused) { - if (args) { - ap_first = xml_parse_time(args, NULL); - } + if (args) { + ap_first = xml_parse_time(args, NULL); + } } void wfff_last(const char *args, const char **unused) { - if (args) ap_last = xstrdup(args); + if (args) { + ap_last = xstrdup(args); + } } void wfff_wep(const char *args, const char **unused) { - if (args) ap_wep = xstrdup(args); + if (args) { + ap_wep = xstrdup(args); + } } void wfff_hdop(const char *args, const char **unused) { - if (args) ap_hdop = atof(args); + if (args) { + ap_hdop = atof(args); + } } void wfff_lat(const char *args, const char **unused) { - if (args) ap_lat = atof(args); + if (args) { + ap_lat = atof(args); + } } void wfff_lon(const char *args, const char **unused) { - if (args) ap_lon = atof(args); + if (args) { + ap_lon = atof(args); + } } /* End of AP Block, set waypoint and add */ @@ -187,60 +217,59 @@ static long tosscount=0; void wfff_e(const char *args, const char **unused) { - waypoint* wpt_tmp =0; - char desc[255] ="\0"; - - if ((ap_hdop>=1)&&(ap_hdop<50)) // Discard invalid GPS fix - { - wpt_tmp = waypt_new(); - - if ( snmac ) { - wpt_tmp->shortname = xstrdup(ap_mac); - } else { - wpt_tmp->shortname = xstrdup(ap_ssid); - } - - snprintf(desc, sizeof desc, - "%s/%s/WEP %s/Ch %d/%2.0fdB/%2.0fdB/%s", - (snmac?ap_ssid:ap_mac), ap_type, ap_wep, - ap_chan, ap_mnrssi, ap_mxrssi, ap_last); - wpt_tmp->description = xstrdup(desc); - - wpt_tmp->latitude = ap_lat; - wpt_tmp->longitude = ap_lon; - wpt_tmp->hdop = ap_hdop; - wpt_tmp->altitude = unknown_alt; - wpt_tmp->fix = fix_unknown; - - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - if (case_ignore_strncmp(ap_wep,"On",2)==0) { - if (case_ignore_strncmp(ap_type,"AP",2)==0) { - wpt_tmp->icon_descr = xstrdup(aicicon); /* Infra Closed */ - } else { - wpt_tmp->icon_descr = xstrdup(ahcicon); /* AdHoc Closed */ - } - } else { - if (case_ignore_strncmp(ap_type,"AP",2)==0) { - wpt_tmp->icon_descr = xstrdup(aioicon); /* Infra Open */ - } else { - wpt_tmp->icon_descr = xstrdup(ahoicon); /* AdHoc Open */ - } - } - - wpt_tmp->creation_time = ap_first; - - waypt_add(wpt_tmp); - - } else { - tosscount++; - } - - /* cleanup */ - xfreez(ap_mac); - xfreez(ap_ssid); - xfreez(ap_type); - xfreez(ap_wep); - xfreez(ap_last); + waypoint* wpt_tmp =0; + char desc[255] ="\0"; + + if ((ap_hdop>=1)&&(ap_hdop<50)) { // Discard invalid GPS fix + wpt_tmp = waypt_new(); + + if (snmac) { + wpt_tmp->shortname = xstrdup(ap_mac); + } else { + wpt_tmp->shortname = xstrdup(ap_ssid); + } + + snprintf(desc, sizeof desc, + "%s/%s/WEP %s/Ch %d/%2.0fdB/%2.0fdB/%s", + (snmac?ap_ssid:ap_mac), ap_type, ap_wep, + ap_chan, ap_mnrssi, ap_mxrssi, ap_last); + wpt_tmp->description = xstrdup(desc); + + wpt_tmp->latitude = ap_lat; + wpt_tmp->longitude = ap_lon; + wpt_tmp->hdop = ap_hdop; + wpt_tmp->altitude = unknown_alt; + wpt_tmp->fix = fix_unknown; + + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + if (case_ignore_strncmp(ap_wep,"On",2)==0) { + if (case_ignore_strncmp(ap_type,"AP",2)==0) { + wpt_tmp->icon_descr = xstrdup(aicicon); /* Infra Closed */ + } else { + wpt_tmp->icon_descr = xstrdup(ahcicon); /* AdHoc Closed */ + } + } else { + if (case_ignore_strncmp(ap_type,"AP",2)==0) { + wpt_tmp->icon_descr = xstrdup(aioicon); /* Infra Open */ + } else { + wpt_tmp->icon_descr = xstrdup(ahoicon); /* AdHoc Open */ + } + } + + wpt_tmp->creation_time = ap_first; + + waypt_add(wpt_tmp); + + } else { + tosscount++; + } + + /* cleanup */ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); } @@ -248,48 +277,48 @@ void wfff_e(const char *args, const char **unused) void wfff_xml_rd_init(const char *fname) { - tosscount = 0; + tosscount = 0; - xml_init(fname, loc_map, NULL); + xml_init(fname, loc_map, NULL); } void wfff_xml_read(void) { - xml_read(); + xml_read(); } void wfff_xml_rd_deinit(void) { - /* cleanup */ - xfreez(ap_mac); - xfreez(ap_ssid); - xfreez(ap_type); - xfreez(ap_wep); - xfreez(ap_last); - - xml_deinit(); + /* cleanup */ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + + xml_deinit(); - if (tosscount) { - warning("Warning: %s reading file. Threw away %ld invalid entries.\n", - MYNAME, tosscount ); - } + if (tosscount) { + warning("Warning: %s reading file. Threw away %ld invalid entries.\n", + MYNAME, tosscount); + } } #endif ff_vecs_t wfff_xml_vecs = { - ff_type_file, - {ff_cap_read, ff_cap_none, ff_cap_none}, - wfff_xml_rd_init, - 0, - wfff_xml_rd_deinit, - 0, - wfff_xml_read, - 0, - 0, - wfff_xml_args + ff_type_file, + {ff_cap_read, ff_cap_none, ff_cap_none}, + wfff_xml_rd_init, + 0, + wfff_xml_rd_deinit, + 0, + wfff_xml_read, + 0, + 0, + wfff_xml_args }; diff --git a/gpsbabel/win32/gpsbabel.ico b/gpsbabel/win32/gpsbabel.ico index 2773cc549ce5f7dd1a06594c7a407f8cc840d864..6e2b952b7eec1009f217b1850f7d4092ef5fcbdc 100644 GIT binary patch literal 25214 zcmeHP2Yij^_kS~FSc#uft7d;KlG3`hRkcPJp|z?tTP~%gKP!nCK@c??luJTMw1T2W zA`Kcd$jz`qjhd|;A(3^*_y0Zby*H9b(9-ew{2fl7_kEu8oO7P@?B_Y}RTMkLRdIKB zXXvQZwo{aE6ou~!-(8eJ#S~=+<1Fvhl|hb*@`AIXRIhHKzhbW_vrEXkg?^QbqKqzW zd#|pnBA=?yD$2_*Tj&QlDayVV<=sk8+IsbD@1*~)q9nIal-i;Lk!%&wt0(}#B!8{q zFM)p>HBkID{(OjuiK*!?4+?37jI?UNziKu`iDrHqWN16`v7I-;XBf287zPf*An#4{ z8uPu~KyRPM!$@%1dxST`^ef)pqa|y`{h{yy-ttxhWZJ?&%X@*pijqou#?Z!j@f_m> zQ{5CLOR$;+jSN*}L8J`%?L^}j0U}h-3_7Bgr~&-Rz@L%+dOc!v47Ga36BQyzs3+=( zS{>shBN5E3*D{HrmZ3(NF$5XvHSpAFa7U{_eT@cL6yixvM!mv#1?gG^wKWW>d2Lds z>!GiyV^(IbsbQ!v1eMY28P8Cw*Jo)MDn#h?sd}A0MyJ#JYl#}2UQvi7QuIU}QA^Yi z6(Tfxe?3vB(Z^^t`c#dE@kBB!&K$*cioUc~(R*tYeIyGUNdX2ubOUtIMQfo;*FZ-# zb!L_{Qcu+B8P8C|P$AMVUGzF#oQ|N?>0Z?67_ZYs(pZsttuC68ep;PPMUbc$}HR?+>aQFLi67^_BWrUjyP&_-$*Y8bMxku<)a zUa#G#(`&0}DM+K&)}aBYk2aE(5>0I)wG1^x8YP;QR9UaphU>K2xmvAuzecOwNJB+K zqqSq@DLReTQLEAZq~SY_NBd~)X~|TbqLqK=HHtQl24&4_O0km5=%87xg=Ve>nzb}? z94nnwr76L}(LNgLqj6RAn$^&0=IV8tK%GugoLXLI3X8?s*J_IEwJar3tJTWEsRhR8qENAnJAl@?*VqIrucgP5SUeYOlXNoq$V7uFa5vzqmmrXkHhs+6n?B*|CeSZ>Z%x)4hE8^6r^F>U&~Ba91}sH+T20p=OmqQm{{HzBlj* zQD2c5?3?N0=GHOH!k>}*eOz2zhKE^_`8U+Z!^I=tdq-!lHMz-1OZ4&ZvM{$qCR4+_ z?@7abeeaP2=Ddk{6Zrfj$Jy#)(+2@Zb52{22ae2M*QJQpT^->taQPzq{ETFw%=@ciiJrQUsdtfvivIJdf;oOtGXVBYwO15 zByU}j^K;}+hOH61jXR^F4X3t$m-G9^DLJQt2j(PyX9U$N$IZWvnyw`RR* z%3A)RY3uqZQ{!m{(+hstrW(FECXaF1riK9q)6eVIn=UW=)O3382Z$Y3$H2UGt@#`F z@GQP<@>>;7-2AE;;=Y@0?7q-o>c1q@)OB8#sonH!Q}civQ{0M)hJ-PV@NB7KQ=A>` zx-;*ylApj;3yo66;d{fZCP-U7BFng7bldPzg`4T?Mq$<7JEnk52Ghcb>!!OA6R_yR7p{`_KZWIGoUQ#- zi0obY2Esoh-8_=3ZCkpZtfrQDdry`1wf2g)pLcY0E`QQESy;~IITHXTMHmZiX@8DXW@R;vDmc_p+ z;!2>mvyWAp1jEE+dEVjm@b|p=@2Ag~3be_~{L!ENl?hpj;(U&MsR(@Cs3>_6e22+j zb`W{dneW88#8ex)@ma7wkaka{+KQr7C$=KWKC>v098dQxPxmcP_buFSa2N4(-*RsZ zd7@A0=Cv#R$M_Qb!`7_LzmG^y3bXBvEITAGFCX8qB?ZU!r`o$*g4-E|&URnrbNB68JGw;u9-NY3vfrq=Bi)`@9 zyL$-p{OQ!di+No{#nNOSdT*CU!UW0h<>BVS{h*th2X}1+)5QWFuG}6ny`yhva$fF| zKQWO;WHQq|ynI9R%p^j|nn*E`eyXDN~lNKD}<0a|Ntev9LGe}UE>7j+^ zAMWMs;w-gWSboa)^2%`W@b$G+Yp!I=Lt1b!+k}TRZBw9d*7O8$1MQW;sx45sTt<>E zP2+y$EF=$0PgL{!7FaXnvgd|fZNf#T`}p|tu%IaMNVK%qdkmlS(?7mWsb17FNgAZ#Uf5q;A#amCBa#cP{4e5e2_WUS)}*Ls1~| zTuIRIKgAtJw)ZT%am9dF&!>cZY{cdfK+Gf{b|!FeJ`m4i)x@Ph(zn2&6&6fdZi$Ou zLYi-Yy>noUo@7p2Hxfy+Kg^!orT#AstGRvWTFh<$<kRcPKw|%@@ep>H1z=1`y15XSSmvNY1 z3UgdA46!<7?plEK9dnSjbt-Oc@Wa*bhT-g@-sYo$9ZWGJn`9*ouZ_;NUG_+M3&<}s zsj0)UJKhy>d7OtSb=K>+v#1m9uIPizHA7*D@T2{|0uEE=@pZ^N9*vvHyKy}^7PpS? zM$RwWfRh`5W2}z@LAd+VG^A`8tIEHyq%Tg+?t}wlni~&~s3YayLD|xd^Ob*cGlyeo z1>~o%=!>j%U*g8@FszS03E!2s&~-r$TJTcn6*h@_{ycJ?47~A`89f(eBVhGS?AVoz zTYHwN<-fdgD9$hL11bMr@1{8-zimzDD9V=l&nMr%sl!nz{~4dUIXAv)VNPTD(^m8Y zB1T|W%t3fg0qTr3p$6}->W&3G$C}|e&I}KRwP~JOoB>|+GvlQI;QWED$c&tT>#IlN z_htRn`qz(bp_ae-b51`}w$yn(`Qw{79LXM25g7sXOm~A?o@49I5oYN1KEnw>dqDzU1O&ty$_~e=Nb}y9Lu&Cp+znvOg8^^{rGM}2!9(OnU z!9P3&ttiu%%e>E50`JWQI#8!B>~0^iOEwKKq1IM^v~^I2pH+Q5Z0ukoc8vE<--_HnnyRL7-&rp8oVXJF$n#O{hi`vt&& zWhPA90!-e>+a7lN0UQQiV|#dcf*Ehj0?zH*f*Y%b;+HvH%!enuhNyne87Qc!Rgg_? zUfGhAH{NYr6URe$C)C2#sm)AxbRQsd)gWXX2*t?NCJbT|AM*pSWG66zO}-WD;H_C^ zG^Y*$>+Zm~ZvlQ=@i|V-?QA|Wp#?VdtddFo4XpC>wmWN7ZXoSJ(0y`q$7AW^YT?|Z z#yL0Ubu^`aHxSqrh|PO1VGwN}u*nQvj75(QUjyA2n&8EHh>J}?dc*{rTRISjzUpK= zO!;eiR7xXHIXVz1SZ+(~y}y!Pc49NfV|T~bLdLAuOortjBK`Y8;F&ir?cap)n}DgC z%~-ZaLZH_Y_B{@}6E+xd@uzRFYibwczR`_QuYz+pc{Q@PQ{G@G^U|Y$$bV)@+hV8F z#??fhCKY0ay0hkn84{{il%@;g5uw z-3-UaHA0nA_A{*l#pVwycV6Ax%epATsdpkMqha_$+Ne^p#Ml;ik+s zPOOFBzG`i_`yKBk_AkMY`b@0kUSs)Q6UML&?ufqz^8p>MgpV>Gn$s=kB;~ui*!f6) zf|UP{g5*)pdaIXKW*H~eROP3y8~|(&z^P-&2#>eeKx}d2cr3DGX5spp(MbNfyYb|N zCMfA-H`FRrEyo{Kfb^=~)k-TfZ1V4{=x5H}G7ecsHe&m66T)bNDA`dSTZ8oI87%(@ z^HJLW^u#7`b+r5BiO4UdOwXQB6KAKrnVr2#3j@#bL0g|Vc@e9VfD?xjac0c~$GCP3Wli=tpq9UCDJ2kr&*R$ccG+jgYq~aB)F5)UW8W)GAQw?vJ$j!t_+-S1GAX4s2WIIPX2)eY2X=hMO~6$-HjNjtfP~ znM9c4m*dKY@rIirJyENy^DHYPrzap^SVU#ATs|0d<9Z<}RI+quAyx^1rET=Xg33f8D)dKI1&@OFG?{Iu>A( z9w;|=0zSFdll08Xy@6Ddrdo2PYg6vsR7wu@dJ$-^9V9M)xxo1TBIXIlt9P7{l#-u+ zlw5rh3dTp$xrY$N4Egkl=G7=+iFaV2)~2VHCEx`q?@Xf>`b@Rnk|F~cygBuga{1{R zlS{7cBwmH+XyJZeJUJB+A6aO;x7^1T!iO?^tj1SmWN1@-tftOeT`+1p+BC`+&sC9j zpsHxT>J?u9WV|yks&j2-eX#0tfBcoeXhCBoiK8Ur3XRRRv zHQo}+=KJ0}BS&wAgHS)cw|{zX|McGe>Ak&-1^@3L-E3NGG#Xc~G#b~M%x11(ih^|0 znlN8qi(f$Q-!8uXD^2G6vZN=i2^C*~e9i=xOmgKP5|)%V5AXG@t_g+ElMTH9LPGcR zPKG;UoUaSu)2FlLBwN&328_-C#BiyD>;D&h6%BuA;IGP;pSFa^{xm}YK zYN^rh*LqVg}Ku52=-5Tvi`;v!ix z9+h6aRhWeiMWTOU#<2-d`O~CAPxiwfk-n}o=~ecR#@{Q$ne16vCKOs%HgzoJ8Z$Ika1jq`9kZ9IBQ4#7iXh7u9eay@j|@IOM|bxhbw8ut-^{C(Htovj{{CpPR45R=z~`qM*1J+Wlj zPYFCIjCs0GRqgYr`_(_QPpw|~CiQ9TQw#ia7LfZ5LAj3+wB1EWDEA+7PgfY)?ns2r zmeCn|nVasXsQS3V0CC-N5oR6hy1>vXrGJeMR&x}eb7^4db-D`l3l zJ#Lw7`U*drt~UKdmkK0!k@s!QOBZ+URPmY81M1eOIHpDY=Vx?yt={79?HYyl?9hBw zZ?6{Nf<4}8vhssB8Z2$os7_FW+Epi2t5|mEe@Ykc;p$whE$_1ANUR!Bd;_J7dCMkc z`Xl9$Iu)J8Cc;N-`3(IRJxjSbcJ!#??$^25^DAb4`o{iElRr9la>f7dWN(`WF{bq z^E#F1Rwz?^Krsh<@nNb?6kFNKBV`f&iUMgHVr$X4MoB08_6@2O4;a<9+V-DDH2dxP zqAo^LIM0wb3^X9r_%_0{BM_#Yv!LEX$9_ZqkHvHV3Z|a)(c`_eig6(@9}I?R zzmB>uM9%Jc$cmYb%xz!cZqyXq-7+3&8@zFQ^)UPv(hso#?eEU`@a3cLyi_iX--iyO z4~+ONNm~@V7FGs{b9S;!z| zKK;)Gb;a@N??U|6;zrhoen@o;Z(JgQI*Pxqv~TI3c|polyj@jgaq7?#xHhs9Zj5^r z{U`DJX4-$(Y=|F)neD^Owj%x%NLWs!lbc}tw~Sv3(*d@9`Z?t6p3nAQwEYX}e{gVh z40y$LFLkUylr~-vME??R(f$wDe+aTRj6_bvIOJ@bO5N$>%Qg+_ha~EHUiRD|X)=?JAkQNn4{l`62|339pe_QblmvN{dsP=F3oU-tt_Fp>`@(pv!!FAZR zFB!8o-b9}z*=R}sN6!gBP5!39a~z&3kF=mX*I=9n(^}F;wfB-7%-EQUpJPwrT0*4i zr+jOp#YfiGe+$|_j_vi=dHWx+%B|6v&L^E9m5ei02>1+}P~ z#b?*z&nrH?;y;@Y87J{J|K8`Vf`$${kzq5iJ;O&jX#g9f0pRK zV=8?-lhAY;@UhO~d#afPGzxeyHk`~l2;`TpbfK>@iY|P+k0XbECg2A zE`@xG^9#D;Q55%n>ym4jU8gyDh0qg&5=CyEu8+QH&P;}scpX* z>!1_$^5Zb`zg57ybLkUJU)=UqlxOkH?Zu@<+ga=%{D!&G2-1h&M#_%)_$Bx=#0Pf5 zZr_%O8tjS9y(;0wvJP{&W@+GB%>KQ~ZcamAukO0!`7#b;sH2QMGFKG@nSYBlD5p$X z(8lR-%c@R6WnAq)a&c5X2yb8P#__?=(x1H!E=_5Ut6#r|lyB)z&pAJSe*)g7Ze8e4 z-J45>i9bU1sqVox)s;hPH{wTJPJG6tPiwXr=>so~C;HP3dG9gY;n;Iw`Cy!!+ZBf= zx50st4X|fmRn%~^pFn+Ny&!8D+xk@2K{ECfoVysM#yK%Td?jU$5I{6!<||E!w$43DCG(Ot$Gv9}Ei)1ApG zNF4~BvOh5f*`ku~r^69@&^zX^Q;1a0wH)DZ+$WC01TM<)nW!3+1A^20AoI@Xfw*MqwwjZu_+@0+{qVCcTq)q%8kbExu4V2bL z`#5Lbr~h)=fAtXL&<7fO=i!&5$1sZHk3akGj7VVq4omy_g6&6q^82uFOaJb}W!>J` zLpZ&90uIjUjhM0R5Iyu2bg5rvo13d+kFq5k`<5@^Fo5g*7bsuG#0Rza2bD|ocXe@4 z+8yuboGtp_4ycc;pjODxb;Ru@-En<{v7hkR?%pSlM|7;ydITAW+ugQH)6j05A}#GWr|qhTdSdV;8H1L?D(x8R>`JIt!q zn{#nTrQOxfT#@2k1)KWSyx61Rv*C@am72f1Z`qu~!)oEggr>N#;6ru(*K^%Ag|-jc z#&1G)0c-TYxb?u7tb;GvKcp`9BwR$so<+E_#v8vb?1iIK+97eICtj&oEQm5?Znce% zf7b4zyMW|(r2ShCe%WD5rBe0-IG?=4xC)HxnAoR8_HSce#PzRUM`~~nWc=uhJBb?+ zyvK}r+kvI*yFbLs_a&A-J(_3U)3=&&D|x4--*T^YZc#5Bo7xVCMtQ=se6i`|ZL>We zp9n}DicMrLkg-7cyHo#nk9}G)>&EyxxJ4iIwBYXQSZd~;Jod;{Ea2F`f_-;GBF7ZHC$Nfz*L*P7uCQo)Xmm z?c@DRW~EU7)LEi`H_KSMV>-X3+lv((_rqd=O^1MaY)ex)9?fBR?PMay{3W=(WiqaQ z|0V5j(O=q6b$18(#-pgcIg_3UNLh;Cr~i_!>YhG3YBEf;@2+EM>h~C14g-sM+&qJI zuq81ArsPfBbInKUW`F8GELZ>d5uT`6%3&yZ|6TgOmCyd7KfmkBju;O!_qM;EI)*g~ zJYG4%IczWR4acJMr%%D0xDpvLbJ^D?;M%G$ah_w>@oDW4H{1iy6u0mHH|g)nIiYQG z-u5H<^Si9<&0}EL^)-ygBM@^uN7X-+?Pz0?5ymqy>b^IF-;LhdI3DM|9c(-_t7}&L z#MZ|BUwXjJ*{&P)f1LS>*&hnhew<}aD^!1e+iHyAA~WeboIQIHQOTSG;Q^o~+u6~fg=;Z~w|P$1ksYl%d5iwi=l&`X-cHp2&Aj?&gmgpB znjy%h{%KqMaWiT*eou(Pu2W`29OW;b9@&ZCx6Z|xm7{QYc6Y>bjm-5;PpgvB=0$HA z8^k_;CD`gU#?#8izw%I2F-^Pic9=H(hi`0GJ;>fSJ5Pv!iIY-tb zedhwMHT~2%E8e#eN;%oRWmQyk7W^yiZnKHVaCEj;UOWF;DN|VY$|vhrDe3RzVApE7 zm)oWD0Znl|q&LzwkLNegi*Vy~0Ii0<4zF2L-xZ3U2p6i^{Rp2$274q{ToBk z-+_CYIyK$w5V zlE&|AWG??FK}s5$+b#ka2WjQqs;zXmv-z8K%XTxurgGQ+C=hz{&^ z_JdaS7d=y^R7VGU`Xwn)ngNL~bz`a2FEH{0mPm&$Y11|W0pe08aUI7= zOH`nh<%YEG3!*K?Jx~Hipr9psB8K+57$OwrIH1QAU}~BMf`o@ebOxa5EA2j&aj}MV zk<~U_yGfla3;C0g3Fy`+$_7CeVt!zbUKLk|pjd^z9;Xvbl7wK@XN6O3j zxz)O+^G97oPo)L!MSRBFIro_k3kP@f`^?|v>*rkKrhbvOoAZfo;tz0r+`j|9mE7nc U4ed0t_#JEbzJq3HmiSY`6N|IkkpKVy diff --git a/gpsbabel/win32/gui-2/gnugettext.pas b/gpsbabel/win32/gui-2/gnugettext.pas index e81821bcf..982dea0ae 100644 --- a/gpsbabel/win32/gui-2/gnugettext.pas +++ b/gpsbabel/win32/gui-2/gnugettext.pas @@ -3,7 +3,7 @@ unit gnugettext; (* *) (* (C) Copyright by Lars B. Dybdahl and others *) (* E-mail: Lars@dybdahl.dk, phone +45 70201241 *) -(* File version: $Date: 2005/12/06 00:25:47 $ *) +(* File version: $Date: 2005-12-06 00:25:47 $ *) (* Revision: $Revision: 1.3 $ *) (* *) (* Contributors: Peter Thornqvist, Troy Wolbrink, *) diff --git a/gpsbabel/win32/gui-2/gnugettextD4.pas b/gpsbabel/win32/gui-2/gnugettextD4.pas index f11c49555..bed4d3066 100644 --- a/gpsbabel/win32/gui-2/gnugettextD4.pas +++ b/gpsbabel/win32/gui-2/gnugettextD4.pas @@ -1,5 +1,5 @@ unit gnugettextD4; -(* File version: $Date: 2005/12/06 00:25:47 $ *) +(* File version: $Date: 2005-12-06 00:25:47 $ *) (* Revision: $Revision: 1.3 $ *) // Delphi 5 optimized interface for gnugettext.pas // This unit must only be used on Delphi 5. When you upgrade to Delphi 6 or diff --git a/gpsbabel/wintec_tes.c b/gpsbabel/wintec_tes.c index f5d76f06c..5c1561dcd 100644 --- a/gpsbabel/wintec_tes.c +++ b/gpsbabel/wintec_tes.c @@ -29,90 +29,90 @@ static gbfile* fin; static void wintec_tes_rd_init(const char *fname) { - fin = gbfopen(fname, "r", MYNAME); + fin = gbfopen(fname, "r", MYNAME); } -static void +static void wintec_tes_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static time_t wintec_date_to_time(gbuint32 w) { - struct tm tm; - memset(&tm, 0, sizeof(tm)); - tm.tm_sec = ((w & 0x0000003f)); - tm.tm_min = ((w & 0x00000fc0) >> 6); - tm.tm_hour = ((w & 0x0001f000) >> 12); - tm.tm_mday = ((w & 0x003f0000) >> 17); - tm.tm_mon = ((w & 0x03c00000) >> 22) - 1; - tm.tm_year = ((w & 0xfc000000) >> 26) + 100; - - return mkgmtime(&tm);; + struct tm tm; + memset(&tm, 0, sizeof(tm)); + tm.tm_sec = ((w & 0x0000003f)); + tm.tm_min = ((w & 0x00000fc0) >> 6); + tm.tm_hour = ((w & 0x0001f000) >> 12); + tm.tm_mday = ((w & 0x003f0000) >> 17); + tm.tm_mon = ((w & 0x03c00000) >> 22) - 1; + tm.tm_year = ((w & 0xfc000000) >> 26) + 100; + + return mkgmtime(&tm);; } static void wintec_tes_read(void) { - route_head *trk = route_head_alloc(); - track_add_head(trk); - - while (!gbfeof(fin)) { - waypoint *wpt; - gbuint16 flags = gbfgetuint16(fin); - gbuint32 date = gbfgetuint32(fin); - gbint32 latitude = gbfgetint32(fin); - gbint32 longitude = gbfgetint32(fin); - gbint16 alt = gbfgetint16(fin); // Signed. Meters. - - (void) flags; // Silence 'unused' warning until we use flags. - wpt = waypt_new(); - wpt->latitude = latitude / 1.0e7; - wpt->longitude = longitude / 1.0e7; - wpt->creation_time = wintec_date_to_time(date); - // The unit of altitude isn't clear and we have a lot of - // samples with wildly negative values, so ignore those for now. - wpt->altitude = alt; - - // The description given to us says this is a bitmask with - // 0x01 "split mark" (not at all clear what that is) - // 0x02 interest point - // 0x04 track point - // But of the files we've seen, none have had > 1 bit set - // and none have had 0x04 set. - // Wintec's software puts a waypoint in the track, so we - // mock that. - if (flags & 0x02) { - waypoint *temp = waypt_dupe(wpt); - waypt_add(temp); - } - - track_add_wpt(trk, wpt); - } + route_head *trk = route_head_alloc(); + track_add_head(trk); + + while (!gbfeof(fin)) { + waypoint *wpt; + gbuint16 flags = gbfgetuint16(fin); + gbuint32 date = gbfgetuint32(fin); + gbint32 latitude = gbfgetint32(fin); + gbint32 longitude = gbfgetint32(fin); + gbint16 alt = gbfgetint16(fin); // Signed. Meters. + + (void) flags; // Silence 'unused' warning until we use flags. + wpt = waypt_new(); + wpt->latitude = latitude / 1.0e7; + wpt->longitude = longitude / 1.0e7; + wpt->creation_time = wintec_date_to_time(date); + // The unit of altitude isn't clear and we have a lot of + // samples with wildly negative values, so ignore those for now. + wpt->altitude = alt; + + // The description given to us says this is a bitmask with + // 0x01 "split mark" (not at all clear what that is) + // 0x02 interest point + // 0x04 track point + // But of the files we've seen, none have had > 1 bit set + // and none have had 0x04 set. + // Wintec's software puts a waypoint in the track, so we + // mock that. + if (flags & 0x02) { + waypoint *temp = waypt_dupe(wpt); + waypt_add(temp); + } + + track_add_wpt(trk, wpt); + } } static arglist_t wintec_tes_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; ff_vecs_t wintec_tes_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - wintec_tes_rd_init, - NULL, - wintec_tes_rd_deinit, - NULL, - wintec_tes_read, - NULL, - NULL, - wintec_tes_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + wintec_tes_rd_init, + NULL, + wintec_tes_rd_deinit, + NULL, + wintec_tes_read, + NULL, + NULL, + wintec_tes_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; diff --git a/gpsbabel/xcsv.c b/gpsbabel/xcsv.c index b72a26761..46e524d66 100644 --- a/gpsbabel/xcsv.c +++ b/gpsbabel/xcsv.c @@ -45,397 +45,433 @@ static const char *intstylebuf = NULL; static arglist_t xcsv_args[] = { - {"style", &styleopt, "Full path to XCSV style file", NULL, - ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"snlen", &snlenopt, "Max synthesized shortname length", NULL, - ARGTYPE_INT, "1", NULL}, - {"snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snupper", &snupperopt, "UPPERCASE synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snunique", &snuniqueopt, "Make synth. shortnames unique", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"urlbase", &xcsv_urlbase, "Basename prepended to URL on output", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"prefer_shortnames", &prefer_shortnames, - "Use shortname instead of description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"datum", &opt_datum, "GPS datum (def. WGS 84)", - "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "style", &styleopt, "Full path to XCSV style file", NULL, + ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "snlen", &snlenopt, "Max synthesized shortname length", NULL, + ARGTYPE_INT, "1", NULL + }, + { + "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snupper", &snupperopt, "UPPERCASE synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snunique", &snuniqueopt, "Make synth. shortnames unique", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "urlbase", &xcsv_urlbase, "Basename prepended to URL on output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "prefer_shortnames", &prefer_shortnames, + "Use shortname instead of description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "datum", &opt_datum, "GPS datum (def. WGS 84)", + "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /* a table of config file constants mapped to chars */ -static +static char_map_t xcsv_char_table[] = { - { "COMMA", "," }, - { "COMMASPACE", ", " }, - { "SINGLEQUOTE", "'" }, - { "DOUBLEQUOTE", "\"" }, - { "COLON", ":" }, - { "SEMICOLON", ";" }, - { "NEWLINE", "\n" }, - { "CR", "\n" }, - { "CRNEWLINE", "\r\n" }, - { "TAB", "\t" }, - { "SPACE", " " }, - { "HASH", "#" }, - { "WHITESPACE", "\\w" }, - { "PIPE", "|" }, - { NULL, NULL } -}; + { "COMMA", "," }, + { "COMMASPACE", ", " }, + { "SINGLEQUOTE", "'" }, + { "DOUBLEQUOTE", "\"" }, + { "COLON", ":" }, + { "SEMICOLON", ";" }, + { "NEWLINE", "\n" }, + { "CR", "\n" }, + { "CRNEWLINE", "\r\n" }, + { "TAB", "\t" }, + { "SPACE", " " }, + { "HASH", "#" }, + { "WHITESPACE", "\\w" }, + { "PIPE", "|" }, + { NULL, NULL } +}; void xcsv_destroy_style(void) { - queue *elem, *tmp; - field_map_t *fmp; - ogue_t *ogp; - int internal = 0; - - /* - * If this xcsv_file struct came from a file we can free it all. - * If not, we can at least free the queue elements. - */ - - /* destroy the prologue */ - QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { - ogp = (ogue_t *)elem; - if (ogp->val) - xfree(ogp->val); - if (elem) - xfree(elem); + queue *elem, *tmp; + field_map_t *fmp; + ogue_t *ogp; + int internal = 0; + + /* + * If this xcsv_file struct came from a file we can free it all. + * If not, we can at least free the queue elements. + */ + + /* destroy the prologue */ + QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { + ogp = (ogue_t *)elem; + if (ogp->val) { + xfree(ogp->val); } - - /* destroy the epilogue */ - QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { - ogp = (ogue_t *)elem; - if (ogp->val) - xfree(ogp->val); - if (elem) - xfree(elem); + if (elem) { + xfree(elem); } + } - /* destroy the ifields */ - QUEUE_FOR_EACH(&xcsv_file.ifield, elem, tmp) { - fmp = (field_map_t *) elem; - if (fmp->key) - xfree(fmp->key); - if (fmp->val) - xfree(fmp->val); - if (fmp->printfc) - xfree(fmp->printfc); - if (elem) - xfree(elem); + /* destroy the epilogue */ + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t *)elem; + if (ogp->val) { + xfree(ogp->val); } + if (elem) { + xfree(elem); + } + } - /* destroy the ofields, if they are not re-mapped to ifields. */ - if (xcsv_file.ofield != &xcsv_file.ifield) { - QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { - fmp = (field_map_t *) elem; - if (fmp->key) - xfree(fmp->key); - if (fmp->val) - xfree(fmp->val); - if (fmp->printfc) - xfree(fmp->printfc); - if (elem) - xfree(elem); - } + /* destroy the ifields */ + QUEUE_FOR_EACH(&xcsv_file.ifield, elem, tmp) { + fmp = (field_map_t *) elem; + if (fmp->key) { + xfree(fmp->key); + } + if (fmp->val) { + xfree(fmp->val); + } + if (fmp->printfc) { + xfree(fmp->printfc); + } + if (elem) { + xfree(elem); + } + } + + /* destroy the ofields, if they are not re-mapped to ifields. */ + if (xcsv_file.ofield != &xcsv_file.ifield) { + QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { + fmp = (field_map_t *) elem; + if (fmp->key) { + xfree(fmp->key); + } + if (fmp->val) { + xfree(fmp->val); + } + if (fmp->printfc) { + xfree(fmp->printfc); + } + if (elem) { + xfree(elem); + } + } - if (xcsv_file.ofield) - xfree(xcsv_file.ofield); + if (xcsv_file.ofield) { + xfree(xcsv_file.ofield); } + } - /* other alloc'd glory */ - if (xcsv_file.field_delimiter) - xfree(xcsv_file.field_delimiter); + /* other alloc'd glory */ + if (xcsv_file.field_delimiter) { + xfree(xcsv_file.field_delimiter); + } - if (xcsv_file.record_delimiter) - xfree(xcsv_file.record_delimiter); + if (xcsv_file.record_delimiter) { + xfree(xcsv_file.record_delimiter); + } - if (xcsv_file.badchars) - xfree(xcsv_file.badchars); + if (xcsv_file.badchars) { + xfree(xcsv_file.badchars); + } - if (xcsv_file.description) - xfree(xcsv_file.description); + if (xcsv_file.description) { + xfree(xcsv_file.description); + } - if (xcsv_file.extension) - xfree(xcsv_file.extension); + if (xcsv_file.extension) { + xfree(xcsv_file.extension); + } - if (xcsv_file.mkshort_handle) - mkshort_del_handle(&xcsv_file.mkshort_handle); + if (xcsv_file.mkshort_handle) { + mkshort_del_handle(&xcsv_file.mkshort_handle); + } - /* return everything to zeros */ - internal = xcsv_file.is_internal; - memset(&xcsv_file, '\0', sizeof(xcsv_file)); - xcsv_file.is_internal = internal; + /* return everything to zeros */ + internal = xcsv_file.is_internal; + memset(&xcsv_file, '\0', sizeof(xcsv_file)); + xcsv_file.is_internal = internal; } const char * xcsv_get_char_from_constant_table(char *key) { - char_map_t *cm = xcsv_char_table; + char_map_t *cm = xcsv_char_table; - while ((cm->key) && (strcmp(key, cm->key) != 0)) { - cm++; - } + while ((cm->key) && (strcmp(key, cm->key) != 0)) { + cm++; + } - return (cm->chars); + return (cm->chars); } static void xcsv_parse_style_line(const char *sbuff) { - int i, linecount = 0; - char *s, *p, *sp; - const char *cp; - char *key, *val, *pfc; - - /* - * tokens should be parsed longest to shortest, unless something - * requires a previously set value. This way something like - * SHORT and SHORTNAME don't collide. - */ - - /* whack off any comments */ - if ((p = strchr(sbuff, '#')) != NULL) { - if ((p > sbuff) && p[-1] == '\\') { - memmove(p-1, p, strlen(p)); - p[strlen(p)-1] = '\0'; - } else { - *p = '\0'; - } + int i, linecount = 0; + char *s, *p, *sp; + const char *cp; + char *key, *val, *pfc; + + /* + * tokens should be parsed longest to shortest, unless something + * requires a previously set value. This way something like + * SHORT and SHORTNAME don't collide. + */ + + /* whack off any comments */ + if ((p = strchr(sbuff, '#')) != NULL) { + if ((p > sbuff) && p[-1] == '\\') { + memmove(p-1, p, strlen(p)); + p[strlen(p)-1] = '\0'; + } else { + *p = '\0'; } + } + + if (strlen(sbuff)) { + if (ISSTOKEN(sbuff, "FIELD_DELIMITER")) { + sp = csv_stringtrim(&sbuff[16], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + if (cp) { + xcsv_file.field_delimiter = xstrdup(cp); + xfree(sp); + } else { + xcsv_file.field_delimiter = sp; + } + + p = csv_stringtrim(xcsv_file.field_delimiter, " ", 0); + + /* field delimiters are always bad characters */ + if (0 == strcmp(p, "\\w")) { + char *s = xstrappend(xcsv_file.badchars, " \n\r"); + if (xcsv_file.badchars) { + xfree(xcsv_file.badchars); + } + xcsv_file.badchars = s; + } else { + xcsv_file.badchars = xstrappend(xcsv_file.badchars, p); + } + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "RECORD_DELIMITER")) { + sp = csv_stringtrim(&sbuff[17], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + if (cp) { + xcsv_file.record_delimiter = xstrdup(cp); + xfree(sp); + } else { + xcsv_file.record_delimiter = sp; + } - if (strlen(sbuff)) { - if (ISSTOKEN(sbuff, "FIELD_DELIMITER")) { - sp = csv_stringtrim(&sbuff[16], "\"", 1); - cp = xcsv_get_char_from_constant_table(sp); - if (cp) { - xcsv_file.field_delimiter = xstrdup(cp); - xfree(sp); - } - else - xcsv_file.field_delimiter = sp; - - p = csv_stringtrim(xcsv_file.field_delimiter, " ", 0); - - /* field delimiters are always bad characters */ - if (0 == strcmp(p, "\\w")) { - char *s = xstrappend(xcsv_file.badchars, " \n\r"); - if (xcsv_file.badchars) xfree(xcsv_file.badchars); - xcsv_file.badchars = s; - } else { - xcsv_file.badchars = xstrappend(xcsv_file.badchars, p); - } - - xfree(p); - - } else - - if (ISSTOKEN(sbuff, "RECORD_DELIMITER")) { - sp = csv_stringtrim(&sbuff[17], "\"", 1); - cp = xcsv_get_char_from_constant_table(sp); - if (cp) { - xcsv_file.record_delimiter = xstrdup(cp); - xfree(sp); - } - else - xcsv_file.record_delimiter = sp; - - p = csv_stringtrim(xcsv_file.record_delimiter, " ", 0); - - /* record delimiters are always bad characters */ - if (xcsv_file.badchars) { - xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, - strlen(xcsv_file.badchars) + - strlen(p) + 1); - } else { - xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); - } - - strcat(xcsv_file.badchars, p); - - xfree(p); - - } else - - if (ISSTOKEN(sbuff, "FORMAT_TYPE")) { - const char *p; - for (p = &sbuff[11]; *p && isspace(*p); p++) { - ; - } - if (ISSTOKEN(p, "INTERNAL")) { - xcsv_file.type = ff_type_internal; - } - /* this is almost inconcievable... */ - if (ISSTOKEN(p, "SERIAL")) { - xcsv_file.type = ff_type_serial; - } - } else - - if (ISSTOKEN(sbuff, "DESCRIPTION")) { - xcsv_file.description = csv_stringtrim(&sbuff[11],"", 0); - } else - - if (ISSTOKEN(sbuff, "EXTENSION")) { - xcsv_file.extension = csv_stringtrim(&sbuff[10],"", 0); - } else - - if (ISSTOKEN(sbuff, "SHORTLEN")) { - if (xcsv_file.mkshort_handle) - setshort_length(xcsv_file.mkshort_handle, atoi(&sbuff[9])); - } else - - if (ISSTOKEN(sbuff, "SHORTWHITE")) { - if (xcsv_file.mkshort_handle) - setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(&sbuff[12])); - } else - - if (ISSTOKEN(sbuff, "BADCHARS")) { - sp = csv_stringtrim(&sbuff[9], "\"", 1); - cp = xcsv_get_char_from_constant_table(sp); - - if (cp) { - p = xstrdup(cp); - xfree(sp); - } - else - p = sp; - - if (xcsv_file.badchars) { - xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, - strlen(xcsv_file.badchars) + - strlen(p) + 1); - } else { - xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); - } - - strcat(xcsv_file.badchars, p); - - xfree(p); - - } else - - if (ISSTOKEN(sbuff, "PROLOGUE")) { - xcsv_prologue_add(xstrdup(&sbuff[9])); - } else - - if (ISSTOKEN(sbuff, "EPILOGUE")) { - xcsv_epilogue_add(xstrdup(&sbuff[9])); - } else - - if (ISSTOKEN(sbuff, "ENCODING")) { - p = csv_stringtrim(&sbuff[8], "\"", 1); - cet_convert_init(p, 1); - xfree(p); - } else - - if (ISSTOKEN(sbuff, "DATUM")) { - p = csv_stringtrim(&sbuff[5], "\"", 1); - xcsv_file.gps_datum = GPS_Lookup_Datum_Index(p); - is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", p); - xfree(p); - } else - - if (ISSTOKEN(sbuff, "DATATYPE")) { - p = csv_stringtrim(&sbuff[8], "\"", 1); - if (case_ignore_strcmp(p, "TRACK") == 0) { - xcsv_file.datatype = trkdata; - } - else if (case_ignore_strcmp(p, "ROUTE") == 0) { - xcsv_file.datatype = rtedata; - } - else if (case_ignore_strcmp(p, "WAYPOINT") == 0) { - xcsv_file.datatype = wptdata; - } - else { - fatal(MYNAME ": Unknown data type \"%s\"!\n", p); - } - xfree(p); - - } else - - if (ISSTOKEN(sbuff, "IFIELD")) { - key = val = pfc = NULL; - - s = csv_lineparse(&sbuff[6], ",", "", linecount); - - i = 0; - while (s) { - switch(i) { - case 0: - /* key */ - key = csv_stringtrim(s, "\"", 1); - break; - case 1: - /* default value */ - val = csv_stringtrim(s, "\"", 1); - break; - case 2: - /* printf conversion */ - pfc = csv_stringtrim(s, "\"", 1); - break; - default: - break; - } - i++; - - s = csv_lineparse(NULL, ",", "", linecount); - } - - xcsv_ifield_add(key, val, pfc); - - } else - - /* - * as OFIELDs are implemented as an after-thought, I'll - * leave this as it's own parsing for now. We could - * change the world on ifield vs ofield format later.. - */ - if (ISSTOKEN(sbuff, "OFIELD")) { - int options = 0; - key = val = pfc = NULL; - - s = csv_lineparse(&sbuff[6], ",", "", linecount); - - i = 0; - while (s) { - switch(i) { - case 0: - /* key */ - key = csv_stringtrim(s, "\"", 1); - break; - case 1: - /* default value */ - val = csv_stringtrim(s, "\"", 1); - break; - case 2: - /* printf conversion */ - pfc = csv_stringtrim(s, "\"", 1); - break; - case 3: - /* Any additional options. */ - if (strstr(s, "no_delim_before")) { - options |= OPTIONS_NODELIM; - } - if (strstr(s, "absolute")) { - options |= OPTIONS_ABSOLUTE; - } - if (strstr(s, "optional")) { - options |= OPTIONS_OPTIONAL; - } - default: - break; - } - i++; - s = csv_lineparse(NULL, ",", "", linecount); - } - - xcsv_ofield_add(key, val, pfc, options); - } - } + p = csv_stringtrim(xcsv_file.record_delimiter, " ", 0); + + /* record delimiters are always bad characters */ + if (xcsv_file.badchars) { + xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, + strlen(xcsv_file.badchars) + + strlen(p) + 1); + } else { + xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); + } + + strcat(xcsv_file.badchars, p); + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "FORMAT_TYPE")) { + const char *p; + for (p = &sbuff[11]; *p && isspace(*p); p++) { + ; + } + if (ISSTOKEN(p, "INTERNAL")) { + xcsv_file.type = ff_type_internal; + } + /* this is almost inconcievable... */ + if (ISSTOKEN(p, "SERIAL")) { + xcsv_file.type = ff_type_serial; + } + } else + + if (ISSTOKEN(sbuff, "DESCRIPTION")) { + xcsv_file.description = csv_stringtrim(&sbuff[11],"", 0); + } else + + if (ISSTOKEN(sbuff, "EXTENSION")) { + xcsv_file.extension = csv_stringtrim(&sbuff[10],"", 0); + } else + + if (ISSTOKEN(sbuff, "SHORTLEN")) { + if (xcsv_file.mkshort_handle) { + setshort_length(xcsv_file.mkshort_handle, atoi(&sbuff[9])); + } + } else + + if (ISSTOKEN(sbuff, "SHORTWHITE")) { + if (xcsv_file.mkshort_handle) { + setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(&sbuff[12])); + } + } else + + if (ISSTOKEN(sbuff, "BADCHARS")) { + sp = csv_stringtrim(&sbuff[9], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + + if (cp) { + p = xstrdup(cp); + xfree(sp); + } else { + p = sp; + } + + if (xcsv_file.badchars) { + xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, + strlen(xcsv_file.badchars) + + strlen(p) + 1); + } else { + xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); + } + + strcat(xcsv_file.badchars, p); + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "PROLOGUE")) { + xcsv_prologue_add(xstrdup(&sbuff[9])); + } else + + if (ISSTOKEN(sbuff, "EPILOGUE")) { + xcsv_epilogue_add(xstrdup(&sbuff[9])); + } else + + if (ISSTOKEN(sbuff, "ENCODING")) { + p = csv_stringtrim(&sbuff[8], "\"", 1); + cet_convert_init(p, 1); + xfree(p); + } else + + if (ISSTOKEN(sbuff, "DATUM")) { + p = csv_stringtrim(&sbuff[5], "\"", 1); + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(p); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", p); + xfree(p); + } else + + if (ISSTOKEN(sbuff, "DATATYPE")) { + p = csv_stringtrim(&sbuff[8], "\"", 1); + if (case_ignore_strcmp(p, "TRACK") == 0) { + xcsv_file.datatype = trkdata; + } else if (case_ignore_strcmp(p, "ROUTE") == 0) { + xcsv_file.datatype = rtedata; + } else if (case_ignore_strcmp(p, "WAYPOINT") == 0) { + xcsv_file.datatype = wptdata; + } else { + fatal(MYNAME ": Unknown data type \"%s\"!\n", p); + } + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "IFIELD")) { + key = val = pfc = NULL; + + s = csv_lineparse(&sbuff[6], ",", "", linecount); + + i = 0; + while (s) { + switch (i) { + case 0: + /* key */ + key = csv_stringtrim(s, "\"", 1); + break; + case 1: + /* default value */ + val = csv_stringtrim(s, "\"", 1); + break; + case 2: + /* printf conversion */ + pfc = csv_stringtrim(s, "\"", 1); + break; + default: + break; + } + i++; + + s = csv_lineparse(NULL, ",", "", linecount); + } + + xcsv_ifield_add(key, val, pfc); + + } else + + /* + * as OFIELDs are implemented as an after-thought, I'll + * leave this as it's own parsing for now. We could + * change the world on ifield vs ofield format later.. + */ + if (ISSTOKEN(sbuff, "OFIELD")) { + int options = 0; + key = val = pfc = NULL; + + s = csv_lineparse(&sbuff[6], ",", "", linecount); + + i = 0; + while (s) { + switch (i) { + case 0: + /* key */ + key = csv_stringtrim(s, "\"", 1); + break; + case 1: + /* default value */ + val = csv_stringtrim(s, "\"", 1); + break; + case 2: + /* printf conversion */ + pfc = csv_stringtrim(s, "\"", 1); + break; + case 3: + /* Any additional options. */ + if (strstr(s, "no_delim_before")) { + options |= OPTIONS_NODELIM; + } + if (strstr(s, "absolute")) { + options |= OPTIONS_ABSOLUTE; + } + if (strstr(s, "optional")) { + options |= OPTIONS_OPTIONAL; + } + default: + break; + } + i++; + s = csv_lineparse(NULL, ",", "", linecount); + } + + xcsv_ofield_add(key, val, pfc, options); + } + } } @@ -447,45 +483,48 @@ xcsv_parse_style_line(const char *sbuff) static void xcsv_parse_style_buff(const char *sbuff) { - char ibuf[256]; - char *ibufp; - size_t i; - - while (*sbuff) { - ibuf[0] = 0; - i = 0; - for (ibufp = ibuf; *sbuff != '\n' && i++ < sizeof(ibuf); ) { - *ibufp++ = *sbuff++; - } - while (*sbuff == '\n' || *sbuff == '\r') - sbuff++; - *ibufp = 0; - xcsv_parse_style_line(ibuf); - } + char ibuf[256]; + char *ibufp; + size_t i; + + while (*sbuff) { + ibuf[0] = 0; + i = 0; + for (ibufp = ibuf; *sbuff != '\n' && i++ < sizeof(ibuf);) { + *ibufp++ = *sbuff++; + } + while (*sbuff == '\n' || *sbuff == '\r') { + sbuff++; + } + *ibufp = 0; + xcsv_parse_style_line(ibuf); + } } static void xcsv_read_style(const char *fname) { - char *sbuff; - gbfile *fp; - - xcsv_file_init(); - - fp = gbfopen(fname, "rb", MYNAME); - while ((sbuff = gbfgetstr(fp))) { - sbuff = lrtrim(sbuff); - xcsv_parse_style_line(sbuff); - } while (!gbfeof(fp)); - - /* if we have no output fields, use input fields as output fields */ - if (xcsv_file.ofield_ct == 0) { - if (xcsv_file.ofield) - xfree(xcsv_file.ofield); - xcsv_file.ofield = &xcsv_file.ifield; - xcsv_file.ofield_ct = xcsv_file.ifield_ct; + char *sbuff; + gbfile *fp; + + xcsv_file_init(); + + fp = gbfopen(fname, "rb", MYNAME); + while ((sbuff = gbfgetstr(fp))) { + sbuff = lrtrim(sbuff); + xcsv_parse_style_line(sbuff); + } + while (!gbfeof(fp)); + + /* if we have no output fields, use input fields as output fields */ + if (xcsv_file.ofield_ct == 0) { + if (xcsv_file.ofield) { + xfree(xcsv_file.ofield); } - gbfclose(fp); + xcsv_file.ofield = &xcsv_file.ifield; + xcsv_file.ofield_ct = xcsv_file.ifield_ct; + } + gbfclose(fp); } /* @@ -496,27 +535,28 @@ xcsv_read_style(const char *fname) void xcsv_read_internal_style(const char *style_buf) { - xcsv_file_init(); - xcsv_file.is_internal = 1; - - xcsv_parse_style_buff(style_buf); - - /* if we have no output fields, use input fields as output fields */ - if (xcsv_file.ofield_ct == 0) { - if (xcsv_file.ofield) - xfree(xcsv_file.ofield); - xcsv_file.ofield = &xcsv_file.ifield; - xcsv_file.ofield_ct = xcsv_file.ifield_ct; - } + xcsv_file_init(); + xcsv_file.is_internal = 1; + + xcsv_parse_style_buff(style_buf); + + /* if we have no output fields, use input fields as output fields */ + if (xcsv_file.ofield_ct == 0) { + if (xcsv_file.ofield) { + xfree(xcsv_file.ofield); + } + xcsv_file.ofield = &xcsv_file.ifield; + xcsv_file.ofield_ct = xcsv_file.ifield_ct; + } } void xcsv_setup_internal_style(const char *style_buf) { - xcsv_file_init(); - xcsv_destroy_style(); - xcsv_file.is_internal = !!style_buf; - intstylebuf = style_buf; + xcsv_file_init(); + xcsv_destroy_style(); + xcsv_file.is_internal = !!style_buf; + intstylebuf = style_buf; } @@ -524,137 +564,143 @@ static void xcsv_rd_init(const char *fname) { - /* - * if we don't have an internal style defined, we need to - * read it from a user-supplied style file, or die trying. - */ - if (xcsv_file.is_internal ) { - xcsv_read_internal_style( intstylebuf ); + /* + * if we don't have an internal style defined, we need to + * read it from a user-supplied style file, or die trying. + */ + if (xcsv_file.is_internal) { + xcsv_read_internal_style(intstylebuf); + } else { + if (!styleopt) { + fatal(MYNAME ": XCSV input style not declared. Use ... -i xcsv,style=path/to/file.style\n"); } - else { - if (!styleopt) - fatal(MYNAME ": XCSV input style not declared. Use ... -i xcsv,style=path/to/file.style\n"); - xcsv_read_style(styleopt); - } + xcsv_read_style(styleopt); + } - if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) { - if (global_opts.masked_objective & (TRKDATAMASK|RTEDATAMASK)) { - warning(MYNAME " attempt to read %s as a track or route, but this format only supports waypoints on read. Reading as waypoints instead.\n", fname); - } + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) { + if (global_opts.masked_objective & (TRKDATAMASK|RTEDATAMASK)) { + warning(MYNAME " attempt to read %s as a track or route, but this format only supports waypoints on read. Reading as waypoints instead.\n", fname); } + } - xcsv_file.xcsvfp = gbfopen(fname, "r", MYNAME); - xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); - is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); + xcsv_file.xcsvfp = gbfopen(fname, "r", MYNAME); + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); } static void xcsv_rd_deinit(void) { - gbfclose(xcsv_file.xcsvfp); + gbfclose(xcsv_file.xcsvfp); - xcsv_destroy_style(); + xcsv_destroy_style(); } static void xcsv_wr_init(const char *fname) { - /* if we don't have an internal style defined, we need to - * read it from a user-supplied style file, or die trying. - */ - if (xcsv_file.is_internal ) { - xcsv_read_internal_style( intstylebuf ); + /* if we don't have an internal style defined, we need to + * read it from a user-supplied style file, or die trying. + * 8/19 - add test for styleopt to ensure that a write of a style + * after a read of a style works. + */ + if (xcsv_file.is_internal && !styleopt) { + xcsv_read_internal_style(intstylebuf); + } else { + + if (!styleopt) { + fatal(MYNAME ": XCSV output style not declared. Use ... -o xcsv,style=path/to/file.style\n"); } - else { - if (!styleopt) - fatal(MYNAME ": XCSV output style not declared. Use ... -o xcsv,style=path/to/file.style\n"); - - xcsv_read_style(styleopt); - } + xcsv_read_style(styleopt); + } - xcsv_file.xcsvfp = gbfopen(fname, "w", MYNAME); - xcsv_file.fname = (char *)fname; + xcsv_file.xcsvfp = gbfopen(fname, "w", MYNAME); + xcsv_file.fname = (char *)fname; - /* set mkshort options from the command line */ - if (global_opts.synthesize_shortnames) { + /* set mkshort options from the command line */ + if (global_opts.synthesize_shortnames) { - if (snlenopt) - setshort_length(xcsv_file.mkshort_handle, atoi(snlenopt)); + if (snlenopt) { + setshort_length(xcsv_file.mkshort_handle, atoi(snlenopt)); + } - if (snwhiteopt) - setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(snwhiteopt)); + if (snwhiteopt) { + setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(snwhiteopt)); + } - if (snupperopt) - setshort_mustupper(xcsv_file.mkshort_handle, atoi(snupperopt)); + if (snupperopt) { + setshort_mustupper(xcsv_file.mkshort_handle, atoi(snupperopt)); + } - if (snuniqueopt) - setshort_mustuniq(xcsv_file.mkshort_handle, atoi(snuniqueopt)); + if (snuniqueopt) { + setshort_mustuniq(xcsv_file.mkshort_handle, atoi(snuniqueopt)); + } - setshort_badchars(xcsv_file.mkshort_handle, xcsv_file.badchars); + setshort_badchars(xcsv_file.mkshort_handle, xcsv_file.badchars); - } - xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); - is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); + } + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); } static void xcsv_wr_position_init(const char *fname) { - xcsv_wr_init(fname); + xcsv_wr_init(fname); } static void xcsv_wr_deinit(void) { - gbfclose(xcsv_file.xcsvfp); + gbfclose(xcsv_file.xcsvfp); - xcsv_destroy_style(); + xcsv_destroy_style(); } static void xcsv_wr_position_deinit(void) { - xcsv_wr_deinit(); + xcsv_wr_deinit(); } static void xcsv_wr_position(waypoint *wpt) { - /* Tweak incoming name if we don't have a fix */ - switch(wpt->fix) { - case fix_none: - if (wpt->shortname) { - xfree(wpt->shortname); - } - wpt->shortname = xstrdup("ESTIMATED Position"); - break; - default: - break; - } - - waypt_add(wpt); - xcsv_data_write(); - waypt_del(wpt); - - gbfflush(xcsv_file.xcsvfp); + /* Tweak incoming name if we don't have a fix */ + switch (wpt->fix) { + case fix_none: + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("ESTIMATED Position"); + break; + default: + break; + } + + waypt_add(wpt); + xcsv_data_write(); + waypt_del(wpt); + + gbfflush(xcsv_file.xcsvfp); } ff_vecs_t xcsv_vecs = { - ff_type_internal, - FF_CAP_RW_WPT, /* This is a bit of a lie for now... */ - xcsv_rd_init, - xcsv_wr_init, - xcsv_rd_deinit, - xcsv_wr_deinit, - xcsv_data_read, - xcsv_data_write, - NULL, - xcsv_args, - CET_CHARSET_ASCII, 0, /* CET-REVIEW */ - { NULL, NULL, NULL, xcsv_wr_position_init, xcsv_wr_position, xcsv_wr_position_deinit } + ff_type_internal, + FF_CAP_RW_WPT, /* This is a bit of a lie for now... */ + xcsv_rd_init, + xcsv_wr_init, + xcsv_rd_deinit, + xcsv_wr_deinit, + xcsv_data_read, + xcsv_data_write, + NULL, + xcsv_args, + CET_CHARSET_ASCII, 0, /* CET-REVIEW */ + { NULL, NULL, NULL, xcsv_wr_position_init, xcsv_wr_position, xcsv_wr_position_deinit } }; #else diff --git a/gpsbabel/xhtmlent.c b/gpsbabel/xhtmlent.c index 499122dd7..2c47c8b32 100644 --- a/gpsbabel/xhtmlent.c +++ b/gpsbabel/xhtmlent.c @@ -1,515 +1,515 @@ -char *xhtml_entities = -"\n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -"\n" -"\n" -"\n" -" \n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -" \n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -" \n" -"\n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -"\n" -"\n" -"\n" -" \n" -"\n" -"\n" -" \n" -"\n" -" \n" -" \n" -" \n" -; +char *xhtml_entities = + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + "\n" + "\n" + "\n" + " \n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + " \n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + "\n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + "\n" + "\n" + "\n" + " \n" + "\n" + "\n" + " \n" + "\n" + " \n" + " \n" + " \n" + ; diff --git a/gpsbabel/xmldoc/chapters/build.xml b/gpsbabel/xmldoc/chapters/build.xml index 997f57a0f..5fd3174b9 100644 --- a/gpsbabel/xmldoc/chapters/build.xml +++ b/gpsbabel/xmldoc/chapters/build.xml @@ -19,13 +19,24 @@ additional information. For operating systems where no binary is provided or if you want the latest development version, you will have to build it from source. The code should be compilable on any system with -ISO C89 compilers. It's been tested on UnixWare, OpenServer, OS/X, -Linux, Solaris, and a variety of processors and compilers. +ISO C89 compilers, though we use a smattering of C99 like double slash +comments. It's tested on Linux, Mac OS/X, and Windows cross compilers. +Less frequently, someone will build on MSVC, FreeBSD, OpenBSD, Solaris, +UnixWare, OpenServer, etc. It's also exercised on a variety of +processors and compilers. -You can grab a release from the GPSBabel download page, but if you're going to be doing any development, you'll find that working from the GPSBabel CVS tree is easier. +You can grab a release from the GPSBabel download page, but if you're going to be doing any development, you'll find that working from the GPSBabel SVN tree is easier. - + +For most cases, an anonymous checkout of the trunk is really all you need. +That can be done easily with the single command: + + + svn checkout http://gpsbabel.googlecode.com/svn/trunk/gpsbabel + + + In most cases, the code is as simple to build as running: ./configure && make diff --git a/gpsbabel/xmldoc/chapters/styles.xml b/gpsbabel/xmldoc/chapters/styles.xml index dffe821fc..234d52a63 100644 --- a/gpsbabel/xmldoc/chapters/styles.xml +++ b/gpsbabel/xmldoc/chapters/styles.xml @@ -1394,7 +1394,7 @@ that are suitable for Garmin's POI loader. For additional examples, please see the *.style files in the -style/ subdirectory of the GPSBabel source tree or at the online source.. +style/ subdirectory of the GPSBabel source tree or at the online source.. diff --git a/gpsbabel/xmldoc/chapters/use.xml b/gpsbabel/xmldoc/chapters/use.xml index 3dba49145..edbfd933f 100644 --- a/gpsbabel/xmldoc/chapters/use.xml +++ b/gpsbabel/xmldoc/chapters/use.xml @@ -68,12 +68,12 @@ name of a file to be read or written. This command will read from a Magellan unit attached to the first serial port on a Linux system (device names will vary on other OSes; typically COMx: on WIndows) and write them as a geocaching loc file. - + Command showing Linux download from Magellan serial and writing to .loc file gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc This second command does the same on Microsoft Windows. - + Command showing Windows download from Magellan serial and writing to .loc file gpsbabel -i magellan -f com1 -o geo -F mag.loc @@ -141,16 +141,16 @@ merged data to multiple destinations. -i argument is seen. Files are read in the order they appear. So you could merge three input files into one output file with: - + Merging multiple files into one gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc You can merge files of different types: - + Merging multiple files of differing types. gpsbabel -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx -o gpsutil -F big.gps - + Writing the same data in multiple output formats. You can write the same data in different output formats: @@ -294,7 +294,7 @@ merged data to multiple destinations. output. Additional formats may be added by interested parties later. - + Read realtime positioning from Garmin USB, write to Keyhole Markup gpsbabel -T -i garmin -f usb: -o kml -F xxx.kml @@ -303,7 +303,7 @@ merged data to multiple destinations. - + Read realtime positioning from Wintec WBT-201 via Bluetooth on Mac, write to Keyhole Markup gpsbabel -T -i nmea -f /dev/cu.G-Rays2-SPPslave-1 -o kml -F xxx.kml diff --git a/gpsbabel/xmldoc/filters/arc-project.xml b/gpsbabel/xmldoc/filters/arc-project.xml new file mode 100644 index 000000000..4f8a77c9d --- /dev/null +++ b/gpsbabel/xmldoc/filters/arc-project.xml @@ -0,0 +1,17 @@ + +When this option is specified, each non deleted waypoint is moved over the +closest segment, or over the nearest point if option +is used. + + +With the and options, if +is possible, altitude, creation_time and microsecond fields of waypoints +are updated by interpolation. + + +This is most useful if you are trying to obtain the closest points in +a road to some places. Or if you want to know the step times on some +places over the tracks. Also to transform waypoints in Garmin course points +(see gtrnctr and +garmin format). + diff --git a/gpsbabel/xmldoc/filters/arc-rte.xml b/gpsbabel/xmldoc/filters/arc-rte.xml new file mode 100644 index 000000000..5e18da5ad --- /dev/null +++ b/gpsbabel/xmldoc/filters/arc-rte.xml @@ -0,0 +1,5 @@ + +When this option is specified the routes contains the vertices of the arc. +If there are several routes then it is assumed that there is a gap between +each of them. + diff --git a/gpsbabel/xmldoc/filters/arc-trk.xml b/gpsbabel/xmldoc/filters/arc-trk.xml new file mode 100644 index 000000000..f8135a6d1 --- /dev/null +++ b/gpsbabel/xmldoc/filters/arc-trk.xml @@ -0,0 +1,5 @@ + +When this option is specified the tracks contains the vertices of the arc. +If there are several tracks then it is assumed that there is a gap between +each of them. + diff --git a/gpsbabel/xmldoc/filters/arc.xml b/gpsbabel/xmldoc/filters/arc.xml index 3b901a28e..902d35dcc 100644 --- a/gpsbabel/xmldoc/filters/arc.xml +++ b/gpsbabel/xmldoc/filters/arc.xml @@ -1,12 +1,13 @@ This filter keeps or removes waypoints based on their proximity to an arc, which is a series of connected line segments similar to a route or a track -but without any associated data other than the coordinates. +but without any associated data other than the coordinates. Optionally, it +can move each non-deleted waypoint over the closest segment of the arc. -The arc is defined in a file whose name must be provided with the -. That file contains pairs of coordinates for the +The arc may defined in a file whose name must be provided with the +, or the tracks or routes that have already been read. That file contains pairs of coordinates for the vertices of the arc, one coordinate pair per line. Comments may be included by preceding them with a '#' character. An arc file looks something like this sample: diff --git a/gpsbabel/xmldoc/filters/bend.xml b/gpsbabel/xmldoc/filters/bend.xml new file mode 100644 index 000000000..6df2bc822 --- /dev/null +++ b/gpsbabel/xmldoc/filters/bend.xml @@ -0,0 +1,32 @@ +The bend filter modifies each route replacing each point inside a +curve with two points: one at a given distance in the direction of the +previous point, and another at the same distance in the direction of +the next point in the route. It only replaces points where there is a +change in heading big enough. + +When creating a route, points are usually created inside curves or +intersections. That means that, while navigating that route using a +GPS unit, the course pointer would aim to the inside of that curve or +intersection, and only when you have passed that point will the GPS +aim to the next waypoint in the route. This behaviour is useful in +marine navigation but when biking, for instance, it may be a bit late +to decide where to turn to in an intersection. + +This filter tries to solve that creating a waypoint before and after +where there is a change in direction.That way, the course pointer will +point to the direction you should turn to ahead in time. + +For this filter to work correctly, the route should be simple enough +that there is only one waypoint inside each curve or intersection. +Because of that, it is usually a good idea to use the simplify filter +before this one. + +This command line reads route.gpx and replaces each point with other two +points: one 25 metres before and another 25 metres after the original +point. It replaces a point only if there is a change of direction +larger than 5 degrees. + +gpsbabel -i gpx -f route.gpx -x +bend,distance=25,interpolate,minangle=5 -o gpx -F newroute.gpx + + diff --git a/gpsbabel/xmldoc/filters/options/arc-file.xml b/gpsbabel/xmldoc/filters/options/arc-file.xml index 6316b64c4..f99544aca 100644 --- a/gpsbabel/xmldoc/filters/options/arc-file.xml +++ b/gpsbabel/xmldoc/filters/options/arc-file.xml @@ -1,7 +1,4 @@ -This option is required. - - This option specifies the name of the file containing the arc to use for filtering. The format of the file is as described above. diff --git a/gpsbabel/xmldoc/filters/options/bend-distance.xml b/gpsbabel/xmldoc/filters/options/bend-distance.xml new file mode 100644 index 000000000..a1342200d --- /dev/null +++ b/gpsbabel/xmldoc/filters/options/bend-distance.xml @@ -0,0 +1,7 @@ +Distance in meters to the original point where the new points will be added. + +The new points will be created at this distance. The first one in the +direction of the previous point, ant the second one in the direction +of the next point in the route. + + diff --git a/gpsbabel/xmldoc/filters/options/bend-minangle.xml b/gpsbabel/xmldoc/filters/options/bend-minangle.xml new file mode 100644 index 000000000..824cc1e63 --- /dev/null +++ b/gpsbabel/xmldoc/filters/options/bend-minangle.xml @@ -0,0 +1,7 @@ +Minimum curve angle in degrees. + +The substitution will only be made if the change in the heading is +greater than this value. This avoids replacing a point if the GPS unit +is already pointing in the correct direction, or if the route reaches +a certain point and goes back the same road. + diff --git a/gpsbabel/xmldoc/filters/transform.xml b/gpsbabel/xmldoc/filters/transform.xml index ddb82ca11..e8e93bc93 100644 --- a/gpsbabel/xmldoc/filters/transform.xml +++ b/gpsbabel/xmldoc/filters/transform.xml @@ -10,7 +10,7 @@ The following example show you how to create a route from a waypoint table. - gpsbabel -i csv waypts.txt -x transform,rte=wpt -o gpx -F route.gpx + gpsbabel -i csv -f waypts.txt -x transform,rte=wpt -o gpx -F route.gpx Only the first letter of option value decides which transformation will be done. Depending on the used option it can be only 'W' for waypoints, 'R' for routes or diff --git a/gpsbabel/xmldoc/formats/an1.xml b/gpsbabel/xmldoc/formats/an1.xml index b90535736..70941595e 100644 --- a/gpsbabel/xmldoc/formats/an1.xml +++ b/gpsbabel/xmldoc/formats/an1.xml @@ -1,5 +1,5 @@ -This format supports the DeLorme ".an1" drawing file format. It can +This format supports the DeLorme ".an1" drawing file format used by their desktop software like Topo USA. It can currently be used to either read or write drawing files. If you use this format to create drawing files with routes or waypoints from another source, by default it will create "Red Flag" symbols for waypoints, and diff --git a/gpsbabel/xmldoc/formats/csv.xml b/gpsbabel/xmldoc/formats/csv.xml index feb3caf9e..6b3425f4d 100644 --- a/gpsbabel/xmldoc/formats/csv.xml +++ b/gpsbabel/xmldoc/formats/csv.xml @@ -17,7 +17,7 @@ on read it will read anything supported by our universal csv format. -Example 'csv' file +Example 'csv' file 35.97203, -87.13470, Mountain Bike Heaven by susy1313 36.09068, -86.67955, The Troll by a182pilot & Family diff --git a/gpsbabel/xmldoc/formats/delbin.xml b/gpsbabel/xmldoc/formats/delbin.xml index 40df43e09..4c6806cc0 100644 --- a/gpsbabel/xmldoc/formats/delbin.xml +++ b/gpsbabel/xmldoc/formats/delbin.xml @@ -1,5 +1,10 @@ - The 'delbin' module supports DeLorme PN-20, PN-30, PN-40, and PN-40 SE receivers. + The 'delbin' module supports +DeLorme PN-20, +DeLorme PN-30, +DeLorme PN-40, +DeLorme PN-40 SE, and +DeLorme PN 60 receivers. Not all strains of Linux are supported. Fedora 7 is known not to work, for example. diff --git a/gpsbabel/xmldoc/formats/dg-100.xml b/gpsbabel/xmldoc/formats/dg-100.xml index b9abe6c90..a8240653f 100644 --- a/gpsbabel/xmldoc/formats/dg-100.xml +++ b/gpsbabel/xmldoc/formats/dg-100.xml @@ -1,7 +1,15 @@ -Serial download protocol for the GlobalSat DG-100, GlobalSat BT-335, and GlboalSat BT-338XGPS data loggers. -While the DG-100 has a button to record waypoints, they seem to be indistinguishable from trackpoints. Therefore, all points will be presented as trackpoints, disregarding whether they were recorded automatically or manually. -GlobalSat DG-100 + Serial download protocol for the GlobalSat DG-100, + GlobalSat BT-335, + and GlboalSat BT-338XGPS data loggers. + + + While the DG-100 has a button to record waypoints, they seem to be indistinguishable + from trackpoints. Therefore, all points will be presented as trackpoints, + regardless of whether they were recorded automatically or manually. + + + GlobalSat DG-100 Command showing DG-100 download and erase on Linux @@ -13,11 +21,11 @@ -The DG-100 provides a physical USB interface to the host computer, but -internally it uses a Prolific PL-2303 chip to do this. So you must have -drivers installed on your computer to recognize the PL-2303 and provide -that data as a serial port to software like GPSBabel. Such software -comes with the unit for Windows. Prolific provides software for Mac OS/X, -but unfortunately their driver has a defect which makes it unusable with -GPSBabel. + The DG-100 provides a physical USB interface to the host computer, but + internally it uses a Prolific PL-2303 chip to do this. So you must have + drivers installed on your computer to recognize the PL-2303 and provide + that data as a serial port to software like GPSBabel. Such software + comes with the unit for Windows. Prolific provides software for Mac OS/X, + but unfortunately their driver has a defect which makes it unstable with + GPSBabel. diff --git a/gpsbabel/xmldoc/formats/dg-200.xml b/gpsbabel/xmldoc/formats/dg-200.xml new file mode 100644 index 000000000..bde00c63a --- /dev/null +++ b/gpsbabel/xmldoc/formats/dg-200.xml @@ -0,0 +1,23 @@ +Serial download protocol for the GlobalSat DG-200GPS data loggers. + +GlobalSat DG-200 + + + Command showing DG-200 download and erase on Linux + gpsbabel -t -i dg-200,erase -o gpx /dev/ttyUSB0 outputfile.gpx + + + Command showing DG-200 erase_only option on Linux + gpsbabel -t -i dg-200,erase_only /dev/ttyUSB0 + + + + The DG-200 provides a physical USB interface to the host computer, but + internally it uses a Prolific PL-2303 chip to do this. So you must have + drivers installed on your computer to recognize the PL-2303 and provide + that data as a serial port to software like GPSBabel. Such software + comes with the unit for Windows. Prolific provides software for Mac OS/X, + but unfortunately their driver has a defect which makes it unstable with + GPSBabel. + + diff --git a/gpsbabel/xmldoc/formats/dna.xml b/gpsbabel/xmldoc/formats/dna.xml index 8e12bb670..567f91688 100644 --- a/gpsbabel/xmldoc/formats/dna.xml +++ b/gpsbabel/xmldoc/formats/dna.xml @@ -1,8 +1,7 @@ - - - - Navitrak DNA marker format - Another CSV format file. This -is the format that is compatible with the DNA Desktop import/export -command. Reading the binary Markers.jwp format directly off the data -card is not supported yet. Contributed by Tim Zickus. + + Navitrak DNA marker format - Another CSV format file. This + is the format that is compatible with the DNA Desktop import/export + command. Reading the binary Markers.jwp format directly off the data + card is not supported yet. Contributed by Tim Zickus. + diff --git a/gpsbabel/xmldoc/formats/easygps.xml b/gpsbabel/xmldoc/formats/easygps.xml index 3f940d3da..100150d47 100644 --- a/gpsbabel/xmldoc/formats/easygps.xml +++ b/gpsbabel/xmldoc/formats/easygps.xml @@ -1,12 +1,11 @@ - - - - This is the binary file format used by EasyGPS -format is seemingly being phased out in favor of GPX in newer versions -of EasyGPS, but this allows conversions to and from the old binary -.loc format. + + This is the binary file format used by EasyGPS + format is seemingly being phased out in favor of GPX in newer versions + of EasyGPS, but this allows conversions to and from the old binary + .loc format. - Information about and sketchy code to implement this file -format were provided by Eric Cloninger. + + Information about and sketchy code to implement this file + format were provided by Eric Cloninger. diff --git a/gpsbabel/xmldoc/formats/enigma.xml b/gpsbabel/xmldoc/formats/enigma.xml index da9a56b83..dcb1ef0ce 100755 --- a/gpsbabel/xmldoc/formats/enigma.xml +++ b/gpsbabel/xmldoc/formats/enigma.xml @@ -1,6 +1,11 @@ - This MGL Avionics format holds waypoints or routes. This routes can be loaded by the MGL Stratomaster Enigma EFIS series (Enigma, Odyssey, Voyager, Explorer). + This MGL Avionics format holds waypoints or routes. This routes can be loaded by the MGL Stratomaster Enigma EFIS series ( +Enigma, +Odyssey, +Voyager, +Explorer). - The format is designed for microcontrollers. The use is free for any none military application. You can find a detailed description in the MGL Documentation. + The format is designed for microcontrollers. The use is free for any non-military + application. You can find a detailed description in the MGL Documentation. diff --git a/gpsbabel/xmldoc/formats/enigma_wp.xml b/gpsbabel/xmldoc/formats/enigma_wp.xml index 4adcb9d84..e627bf9b1 100755 --- a/gpsbabel/xmldoc/formats/enigma_wp.xml +++ b/gpsbabel/xmldoc/formats/enigma_wp.xml @@ -1,6 +1,10 @@ - The MGL Avionics format holds waypoints or routes. These routes can be loaded by the MGL Stratomaster Enigma EFIS series (Enigma, Odyssey, Voyager, Explorer). + The MGL Avionics format holds waypoints or routes. These routes can be loaded by the MGL Stratomaster Enigma EFIS series ( +Enigma, +Odyssey, +Voyager, +Explorer). - The format is designed for microcontrollers. The use is free for any none military application. You can find a detailed description in the MGL Documentation. + The format is designed for microcontrollers. The use is free for any non-military application. You can find a detailed description in the MGL Documentation. diff --git a/gpsbabel/xmldoc/formats/exif.xml b/gpsbabel/xmldoc/formats/exif.xml index d8d1bc48b..e868b4bc6 100644 --- a/gpsbabel/xmldoc/formats/exif.xml +++ b/gpsbabel/xmldoc/formats/exif.xml @@ -3,7 +3,7 @@ EXIF, the Exchangeable Image Format, data. EXIF is a standardized method of encoding data in pictures such as JPEG, TIFF, and WAV and is frequently - used by mobile phones with cameras, cameras with built-in GPS. + used by mobile phones with cameras and cameras with built-in GPS. EXIF is frequently used for Geolocating photographs so their images can be diff --git a/gpsbabel/xmldoc/formats/fit.xml b/gpsbabel/xmldoc/formats/fit.xml new file mode 100644 index 000000000..12c71a848 --- /dev/null +++ b/gpsbabel/xmldoc/formats/fit.xml @@ -0,0 +1,5 @@ + +This format supports Garmin FIT activity files, defined as part +of the ANT standard. These are generated by newer Garmin +devices like the ForeRunner 110. + diff --git a/gpsbabel/xmldoc/formats/flysight.xml b/gpsbabel/xmldoc/formats/flysight.xml new file mode 100644 index 000000000..2e595ca7d --- /dev/null +++ b/gpsbabel/xmldoc/formats/flysight.xml @@ -0,0 +1,6 @@ + +This is the format used by the FlySight GPS for wingsuit pilots. + + +Interfacing with the FlySight is pretty simple. FlySight acts like a USB disk when connected to a computer. Files are organized into folders by date, and individual files within the folder are named according to the time the log started (UTC). The files themselves are CSV text supported by this format. + diff --git a/gpsbabel/xmldoc/formats/garmin.xml b/gpsbabel/xmldoc/formats/garmin.xml index aa88b36ac..ec15946bf 100644 --- a/gpsbabel/xmldoc/formats/garmin.xml +++ b/gpsbabel/xmldoc/formats/garmin.xml @@ -119,15 +119,27 @@ support Garmin communication protocol and don't work with the option. To use these receivers, read or write GPX files from the mass storage device as mounted on your computer. +eTrex 10 +eTrex 20 +eTrex 30 Colorado 300 Colorado 400c Colorado 400i Colorado 400t Dakota 10 Dakota 20 +GPSMap 62 +GPSMap 62sc +GPSMap 62stc GPSMap 78 GPSMap 78s GPSMap 78sc +Montana 600 +Montana 650 +Montana 650t +Nuvi 30 +Nuvi 40 +Nuvi 50 Nuvi 200 Nuvi 205 Nuvi 200W @@ -174,6 +186,17 @@ GPX files from the mass storage device as mounted on your computer. Nuvi 1390T Nuvi 1350 Nuvi 1490T +Nuvi 2250 +Nuvi 2250LT +Nuvi 2350 +Nuvi 2350LT +Nuvi 2360LT +Nuvi 2405 +Nuvi 2450 +Nuvi 2450LM +Nuvi 2450LT +Nuvi 2450LMT +Nuvi 2505 Nuvi 1690T Nuvi 3750 Nuvi 3760T @@ -198,6 +221,7 @@ GPX files from the mass storage device as mounted on your computer. Zumo 550 Zumo 660 Zumo 665 +Surely any Garmin product that Garmin actually sensibly designed after 2006 or so. diff --git a/gpsbabel/xmldoc/formats/garmin_poi.xml b/gpsbabel/xmldoc/formats/garmin_poi.xml index e2059bd00..d807f9b90 100644 --- a/gpsbabel/xmldoc/formats/garmin_poi.xml +++ b/gpsbabel/xmldoc/formats/garmin_poi.xml @@ -1,14 +1,13 @@ - - - - The Garmin POI loader -loads custom points of interest into certain models of -Garmin GPS receivers. (As of this writing, only the models introduced -in 2005 and later are supported. See Garmin's site for more info.) -The garmin_poi format produces csv files that can be - converted into POI files by Garmin's POI loader. -This format was mostly useful when POI Loader couldn't read GPX and we -couldn't write GPI. See GPSBabel's GPI doc. + The Garmin POI loader + loads custom points of interest into certain models of + Garmin GPS receivers. (As of this writing, only the models introduced + in 2005 and later are supported. See Garmin's site for more info.) + The garmin_poi format produces csv files that can be + converted into POI files by Garmin's POI loader. + + + This format was mostly useful when POI Loader couldn't read GPX and we + couldn't write GPI. See GPSBabel's GPI doc. diff --git a/gpsbabel/xmldoc/formats/gcdb.xml b/gpsbabel/xmldoc/formats/gcdb.xml index d9e1d4d53..52a7873a7 100644 --- a/gpsbabel/xmldoc/formats/gcdb.xml +++ b/gpsbabel/xmldoc/formats/gcdb.xml @@ -1,7 +1,6 @@ - - This is format for the - -GeocachingDB program by DougsBrat. It works with v2 -and v3 of this program. - + + This is format for the + GeocachingDB + program by DougsBrat. It works with v2 and v3 of this program. + diff --git a/gpsbabel/xmldoc/formats/gdb.xml b/gpsbabel/xmldoc/formats/gdb.xml index 80788965e..b1a8afec1 100644 --- a/gpsbabel/xmldoc/formats/gdb.xml +++ b/gpsbabel/xmldoc/formats/gdb.xml @@ -1,12 +1,13 @@ -Support for the "Garmin GPS Database" format used by -default in MapSource versions since release 6.0 of -that product. By default GPSBabel creates -gdb files of version 2. Version 2 is used in Mapsource 6.3 and 6.5. + Support for the "Garmin GPS Database" format used by + default in MapSource versions since release 6.0 of + that product. By default GPSBabel creates + gdb files of version 2. Version 2 is used in Mapsource 6.3 and 6.5. This format + is also used by Garmin BaseCamp for Mac and Windows. -Garmin GPS database is an undocumented file format. The -basic info for this module came from the existing MapSource -conversion code. + Garmin GPS database is an undocumented file format. The + basic info for this module came from the existing MapSource + conversion code. diff --git a/gpsbabel/xmldoc/formats/geo.xml b/gpsbabel/xmldoc/formats/geo.xml index f730600cd..54e589f33 100644 --- a/gpsbabel/xmldoc/formats/geo.xml +++ b/gpsbabel/xmldoc/formats/geo.xml @@ -7,7 +7,7 @@ or GPX formats for more general EasyGPS support. This is a simple XML-based format containing only very basic information about geocaches. If you can use the GPX -format instead, you should consider doing so as it is a much richer format. +format from Pocket Queries instead, you should consider doing so as it is a much richer format. We have a separate page describing how to send from Geocaching.com pages to GPS diff --git a/gpsbabel/xmldoc/formats/geonet.xml b/gpsbabel/xmldoc/formats/geonet.xml index 44e255ed8..d50bcf306 100644 --- a/gpsbabel/xmldoc/formats/geonet.xml +++ b/gpsbabel/xmldoc/formats/geonet.xml @@ -1,8 +1,6 @@ - - - - Input support for the GEOnet Names Server (GNS) country -file structure. Export to this format is not possible, as this format -has too many fields that we never get populated by any other -format. - + + Input support for the GEOnet Names Server (GNS) country + file structure. Export to this format is not possible, as this format + has too many fields that we never get populated by any other + format. + diff --git a/gpsbabel/xmldoc/formats/glogbook.xml b/gpsbabel/xmldoc/formats/glogbook.xml index bbaa7b02b..877bd1b72 100644 --- a/gpsbabel/xmldoc/formats/glogbook.xml +++ b/gpsbabel/xmldoc/formats/glogbook.xml @@ -1,11 +1,9 @@ + + This is the XML format used by the Garmin Logbook product + that ships with Forerunner and Foretrex. + As of early 2006, this program is apparently been discontinued in favor of + Garmin Training Center. - - - This is the XML format used by the Garmin Logbook product -that ships with Forerunner and Foretrex. -As of early 2006, this program is apparently been discontinued in favor of -Garmin Training Center. - -See: http://www.garmin.com - + See: http://www.garmin.com + diff --git a/gpsbabel/xmldoc/formats/gnav_trl.xml b/gpsbabel/xmldoc/formats/gnav_trl.xml index 4c17ed14e..06cf6708d 100644 --- a/gpsbabel/xmldoc/formats/gnav_trl.xml +++ b/gpsbabel/xmldoc/formats/gnav_trl.xml @@ -8,7 +8,7 @@ - +
Track point structure (16 bytes) diff --git a/gpsbabel/xmldoc/formats/gopal.xml b/gpsbabel/xmldoc/formats/gopal.xml index 2e692e4a5..a26665820 100644 --- a/gpsbabel/xmldoc/formats/gopal.xml +++ b/gpsbabel/xmldoc/formats/gopal.xml @@ -1,6 +1,7 @@ -The gopal format is a track format written by the - - GoPal Navigation program. + + The gopal format is a track format written by the + GoPal Navigation program. + The format of the file itself is quite simple: diff --git a/gpsbabel/xmldoc/formats/gpl.xml b/gpsbabel/xmldoc/formats/gpl.xml index cace2eaa4..1b4397c32 100644 --- a/gpsbabel/xmldoc/formats/gpl.xml +++ b/gpsbabel/xmldoc/formats/gpl.xml @@ -1,8 +1,7 @@ - - - - This is the 'gpl' format as used in Delorme mapping -products. It is a track format and contains little more than the -tracklog of a GPS that was attached while driving. frontiernet.net - + + This is the 'gpl' format as used in Delorme mapping + products. It is a track format and contains little more than the + tracklog of a GPS that was attached while driving. + frontiernet.net + diff --git a/gpsbabel/xmldoc/formats/gpx.xml b/gpsbabel/xmldoc/formats/gpx.xml index a9b239363..4a29daacc 100644 --- a/gpsbabel/xmldoc/formats/gpx.xml +++ b/gpsbabel/xmldoc/formats/gpx.xml @@ -1,8 +1,5 @@ - - - -This is the most capable and expressive of all the file -formats supplied. It is described at topografix.com and is +This is one of the most capable and expressive formats of all the file +formats supported by GPSBabel. It is described at topografix.com and is supported by EasyGPS, ExpertGPS, and many other programs described at topografix.com @@ -10,8 +7,8 @@ supported by EasyGPS, ExpertGPS, and many other programs described at GPSBabel's reader of this module attempts to preserve tags it doesn't really understand. It also tries to glean interesting data from - pocket queries from Geocaching.com - Garmin's "gpxx" GPX extensions. + pocket queries from Geocaching.com, + Garmin's "gpxx" GPX extensions, Humminbird's "h" GPX extensions. diff --git a/gpsbabel/xmldoc/formats/gtrnctr.xml b/gpsbabel/xmldoc/formats/gtrnctr.xml index cc967b588..fa2459b1f 100644 --- a/gpsbabel/xmldoc/formats/gtrnctr.xml +++ b/gpsbabel/xmldoc/formats/gtrnctr.xml @@ -1,7 +1,7 @@ GPSBabel supports reading and writing of tracks in the .tcx -format used by Garmin Training Center (GTC). GTC is the successor -to Garmin's Logbook program for their workout units. It is a +format used by Garmin Training Center (GTC). GTC is the successor +to Garmin's Logbook program for their workout units. It is a free upgrade. diff --git a/gpsbabel/xmldoc/formats/hiketech.xml b/gpsbabel/xmldoc/formats/hiketech.xml index 65d69bf7d..b9219caf7 100644 --- a/gpsbabel/xmldoc/formats/hiketech.xml +++ b/gpsbabel/xmldoc/formats/hiketech.xml @@ -1,8 +1,7 @@ - - - - This is the .gps format used by the Mac OS X applications -written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. -More information about these products can be found at hiketech.com - + + This is the .gps format used by the Mac OS X applications + written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. + More information about these products can be found at + hiketech.com + diff --git a/gpsbabel/xmldoc/formats/html.xml b/gpsbabel/xmldoc/formats/html.xml index 211da87ff..1c53699a3 100644 --- a/gpsbabel/xmldoc/formats/html.xml +++ b/gpsbabel/xmldoc/formats/html.xml @@ -1,16 +1,21 @@ - GPSBabel's HTML output generates a single HTML file of all of the -waypoints in the input file. It supports a number of Groundspeak GPX -extensions and filters out potentially harmful HTML from the -input file while maintaining almost all of the source HTML formatting. -This makes this format well suited for generating HTML to hand to programs -like Plucker for putting in a PDA and especially so for "paperless caching" -for Geocachers with pocket queries. + + GPSBabel's HTML output generates a single HTML file of all of the + waypoints in the input file. It supports a number of Groundspeak GPX + extensions and filters out potentially harmful HTML from the + input file while maintaining almost all of the source HTML formatting. + This makes this format well suited for generating HTML to hand to programs + like Plucker for putting in a PDA and especially so for "paperless caching" + for Geocachers with pocket queries. -This format is similar to the text format. + + This format is similar to the text format. - The following command line reads a GPX file with -Groundspeak extensions and writes an HTML file with encrypted hints -that is rendered using a custom stylesheet: + + The following command line reads a GPX file with + Groundspeak extensions and writes an HTML file with encrypted hints + that is rendered using a custom stylesheet: + + + gpsbabel -i gpx -f 12345.gpx -o html,stylesheet=green.css,encrypt -F 12345.html -gpsbabel -i gpx -f 12345.gpx -o html,stylesheet=green.css,encrypt -F 12345.html diff --git a/gpsbabel/xmldoc/formats/iblue747.xml b/gpsbabel/xmldoc/formats/iblue747.xml index 09dd575a0..c528b9f1e 100644 --- a/gpsbabel/xmldoc/formats/iblue747.xml +++ b/gpsbabel/xmldoc/formats/iblue747.xml @@ -1,5 +1,5 @@ - This is the format used by the software that comes with the Transystem i-Blue747 GPS + This is the format used by the software that comes with the Transystem i-Blue747 GPS. diff --git a/gpsbabel/xmldoc/formats/iblue757.xml b/gpsbabel/xmldoc/formats/iblue757.xml new file mode 100644 index 000000000..f473bf5e1 --- /dev/null +++ b/gpsbabel/xmldoc/formats/iblue757.xml @@ -0,0 +1,90 @@ + + This is the format used by the software that comes with the + + Transystem i-Blue757 Pro GPS + . + It is very similar to the iBlue747 + format, apart from the date format being reversed. + + + + The csv log file can be extracted from the GPS receiver using + the BT747 software available from + + + +Field definitions: + + +
INDEX +A sequential integer which corresponds for each logged point in the file. +example 3308 +
+ +
RCR +? +example 1: T +example 2: TD +
+ +
DATE +Date that the point was recorded, in the format YYYY/MM/DD +example: 2011/05/14 +
+ +
TIME +Time that the point was recorded, 24-hr format H:MM:SS. Unsure how fractions of a second are handled. +example: 4:15:11 +
+ +
VALID +? +example 1: DGPS +example 2: SPS +
+ +
LATITUDE +Degrees above the equator (use negative for south of the equator) +example: -33.803645 +
+ +
N/S +North (N)or South (S) of the equator +example: S +
+ +
LONGITUDE +Degrees east of the Prime Meridian (use negative for east of the Prime Meridian/Greenwich) +example: 150.880499 +
+ +
E/W +East (E) or West (W) of Greenwich +example: E +
+
HEIGHT +Height above sea level in metres +example: 99.859 m +
+ +
SPEED +Speed in km/h +example: 0.302 km/h +
+ +
DISTANCE +Distance covered since last point in metres +example: 0.30 m +
+ +
Example File + +Example 3.X. Example 'iBlue 757' file + +INDEX,RCR,DATE,TIME,VALID,LATITUDE,N/S,LONGITUDE,E/W,HEIGHT,SPEED,DISTANCE +3308,T,2011/05/14,4:15:11,DGPS,-33.803645,S,150.880499,E,99.859 m,0.207 km/h, 0.28 m +3309,T,2011/05/14,4:15:12,DGPS,-33.803645,S,150.880499,E,100.137 m,0.362 km/h, 0.28 m +3310,T,2011/05/14,4:15:13,DGPS,-33.803644,S,150.8805,E,100.416 m,0.302 km/h, 0.30 m + + +
diff --git a/gpsbabel/xmldoc/formats/kml.xml b/gpsbabel/xmldoc/formats/kml.xml index 6fa86fe57..687521e9a 100644 --- a/gpsbabel/xmldoc/formats/kml.xml +++ b/gpsbabel/xmldoc/formats/kml.xml @@ -1,5 +1,5 @@ -KML, the Keyhole Markup Language, is used by Keyhole and +KML, the Keyhole Markup Language format, was used by Keyhole and is used by Google Earth. There are concepts in KML that GPSBabel can't support very well on @@ -7,7 +7,7 @@ read becuase they don't map well into other programs. For example, KML has ideas of camera views and names and descriptions can have arbitrarily complicated HTML in them. KML files may have tiered "Styles" which can identify sizing info and URLs of associated icons. Reading such -files with GPSBabel - even if your goal it to out to KML - can often +files with GPSBabel - even if your goal it to write it back out as KML - can often have suprising results. Simple files with waypoints and paths (which GPSBabel represents internally as tracks) work fine. diff --git a/gpsbabel/xmldoc/formats/land_air_sea.xml b/gpsbabel/xmldoc/formats/land_air_sea.xml new file mode 100644 index 000000000..5140fa1a0 --- /dev/null +++ b/gpsbabel/xmldoc/formats/land_air_sea.xml @@ -0,0 +1,18 @@ + +Read-only support for the text format exported by Land Air Sea's (Windows only) Past-Track software. This may also work for importing text formatted files from Victoria GPS Tracking, GPS Tracking Key and Land Air Sea's other devices. + + + +Implementation + + + +The text format of the GPS Tracking Key Pro contains one route coordinate per line and is of the format: + + + +01-24-2011,09:12:30,N 48°51'57.9738",W 123°11'48.1354",20.5mph,83.8°,357ft + + +GPS Babel style file correctly imports all data except for bearing (which is un-needed). Since there is no way to create waypoints or routes on the device itself, the text file is read in as one large track. + diff --git a/gpsbabel/xmldoc/formats/lowranceusr.xml b/gpsbabel/xmldoc/formats/lowranceusr.xml index 99fe49495..55ed42c58 100644 --- a/gpsbabel/xmldoc/formats/lowranceusr.xml +++ b/gpsbabel/xmldoc/formats/lowranceusr.xml @@ -1,5 +1,5 @@ -The Lowrance iFinder GPS series has the unique capability +The Lowrance iFinder GPS series has the unique capability within the Lowrance models to output its data to an MMC card. The data is saved to the card as a .USR file and can be read by your computer using a card reader. Waypoints, icons, routes, tracks are supported. Event marker icons contain a symbol, name, latitude and longitude diff --git a/gpsbabel/xmldoc/formats/m241.xml b/gpsbabel/xmldoc/formats/m241.xml index 0d010e767..52c34ab63 100644 --- a/gpsbabel/xmldoc/formats/m241.xml +++ b/gpsbabel/xmldoc/formats/m241.xml @@ -16,3 +16,11 @@ Use the m241 format to connect with the unit serially and m241-bin to read files saved by the device. + + This module is also reported to handle the Holux M1000c. + + + Most of the loggers cannot receive bluetooth commands, they can only send + data. Since GPSBabel needs to send commands to the GPS device it won't + work. Download the data using the USB cable instead. + diff --git a/gpsbabel/xmldoc/formats/maggeo.xml b/gpsbabel/xmldoc/formats/maggeo.xml index 5f88c672a..1ec14617e 100644 --- a/gpsbabel/xmldoc/formats/maggeo.xml +++ b/gpsbabel/xmldoc/formats/maggeo.xml @@ -1,17 +1,19 @@ - - - - This format supports the on-card format used by the Magellan Explorist 400, -Explorist 500, Explorist 600, Explorist 210, and Explorist XL -to describe geocaches. Notice what while the format can -hold an infinite number of geocaches, the unit will read and silently -discard all but 200 geocache POIs at a time. - You should name any file created with this format with a -".gs" extension so the firmware can read it. + + This format supports the on-card format used by the + Magellan Explorist 400, + Explorist 500, Explorist 600, Explorist 210, and Explorist XL + to describe geocaches. Notice what while the format can + hold an infinite number of geocaches, the unit will read and silently + discard all but 200 geocache POIs at a time. + + You should name any file created with this format with a ".gs" extension + so the firmware can read it. + + + This format does support reading .gs files, but it's kind of a + pointless operation as the units can't create or edit these files. + Round-tripped data is lossy for all but the most trivial cases as + many fields are shortened or discarded on write. "Date last found" is + discarded on read as there are no logs stored on the device in which to + store the date last found. -This format does support reading .gs files, but it's kind of a -pointless operation as the units can't create or edit these files. -Round-tripped data is lossy for all but the most trivial cases as -many fields are shortened or discarded on write. "Date last found" is -discarded on read as there are no logs stored on the device in which to -store the date last found. diff --git a/gpsbabel/xmldoc/formats/mapsend.xml b/gpsbabel/xmldoc/formats/mapsend.xml index a33cdc3bc..853a3b7b9 100644 --- a/gpsbabel/xmldoc/formats/mapsend.xml +++ b/gpsbabel/xmldoc/formats/mapsend.xml @@ -1,8 +1,9 @@ -This format supports the Magellan MapSend native -file format. + This format supports the + Magellan + MapSend native file format. -Kudos to Magellan for having the foresight to document their file formats, -making software like this possible. + Kudos to Magellan for having the foresight to document their file formats, + making software like this possible. diff --git a/gpsbabel/xmldoc/formats/mapsource.xml b/gpsbabel/xmldoc/formats/mapsource.xml index 7460e008b..1d3c97d92 100644 --- a/gpsbabel/xmldoc/formats/mapsource.xml +++ b/gpsbabel/xmldoc/formats/mapsource.xml @@ -1,28 +1,27 @@ -This format supports the Garmin Mapsource -product family. + This format supports the Garmin Mapsource product family. -This format is based on significant reverse-engineering and guesswork. -GPSBabel's output appears to be compatible with the various versions of -MapSource. Icon mapping is attempted between different MapSource versions. -Altitude is supported, but proximity and depth are not. + This format is based on significant reverse-engineering and guesswork. + GPSBabel's output appears to be compatible with the various versions of + MapSource. Icon mapping is attempted between different MapSource versions. + Altitude is supported, but proximity and depth are not. -Naming files *.mps will allow file->open in Mapsource to find the files -more easily. + Naming files *.mps will allow file->open in Mapsource to find the files + more easily. -Versions 3, 4, and 5 of the Mapsource data format are handled automatically -on input. By default the output is version 5. (Until 3/2004, it was -version 3, but since Mapsource updates are free, the convenience of -having modern icon sets outweighs the backward compatibility concern. -Users of other versions can either upgrade or specify the switches to -get output in a compatible format.) Waypoints, routes, and tracklogs are -all handled, but map sets are ignored. + Versions 3, 4, and 5 of the Mapsource data format are handled automatically + on input. By default the output is version 5. (Until 3/2004, it was + version 3, but since Mapsource updates are free, the convenience of + having modern icon sets outweighs the backward compatibility concern. + Users of other versions can either upgrade or specify the switches to + get output in a compatible format.) Waypoints, routes, and tracklogs are + all handled, but map sets are ignored. -Information on the Garmin Mapsource format was provided by Ian Cowley and -Mark Bradley. The code was implemented by Robert Lipe and Mark Bradley. + Information on the Garmin Mapsource format was provided by Ian Cowley and + Mark Bradley. The code was implemented by Robert Lipe and Mark Bradley. diff --git a/gpsbabel/xmldoc/formats/miniHomer.xml b/gpsbabel/xmldoc/formats/miniHomer.xml new file mode 100644 index 000000000..609888d77 --- /dev/null +++ b/gpsbabel/xmldoc/formats/miniHomer.xml @@ -0,0 +1,62 @@ + +Serial download protocol for GPS data loggers called "miniHomer". +These loggers are based on Skytraq Venus 5 and Venus 6 chipsets, but with modified firmware. +The miniHomer logger has five POI (or better: Point-to-Return, PTR?), which can be set programatically. The miniHomer module in gpsbabel is an extension of the skytraq module. + + + +Following a list of devices which should be supported by this module +(Note that not all of them have actually been tested, so if you can confirm that additional models work, please mail the gpsbabel-misc group with your success, tips, and any pertinent links for your model.) + + +
+Devices supported by miniHomer module + + + + Manufacturer + Model + USB (baud) + Bluetooth (baud) + + + + + + Navin + Z:NEX + + miniHomer + up to 230400 + this device does not have bluetooth + + + +
+ + + Command showing miniHomer download of tracks and erasing the logger on Linux + gpsbabel -i miniHomer,erase -f /dev/ttyUSB0 -o gpx -F out.gpx + + + + Command showing miniHomer erasing the logger without download on Linux + gpsbabel -i miniHomer,erase,no-output -f /dev/ttyUSB0 + + +miniHomer has five POI called Home, Car, Boat, Heart, Bar. You can set the lla +(Lattitude, Longitude, Altitude) for each of the POI. The format is +<name>=<lat>:<lng>[:<alt>] +Once the according POI symbol is selected on miniHomer, the display shows you the direction and distance to the POI. + + + Command showing miniHomer setting Car and Home POI + + + gpsbabel -i miniHomer,Car=36.790145:-6.352898,Home=-3.066667:37.359167:5895 -f /dev/ttyUSB0 -o gpx -F out.gpx + + Sets the Car/Home symbols' latitude longitude and altitude. + If you select the Car/Home symbol on miniHomer, the display will show the direction and distance to + this location as soon as it has a satellite fix. + + diff --git a/gpsbabel/xmldoc/formats/msroute.xml b/gpsbabel/xmldoc/formats/msroute.xml index d1d4d36b2..1ce5744c7 100644 --- a/gpsbabel/xmldoc/formats/msroute.xml +++ b/gpsbabel/xmldoc/formats/msroute.xml @@ -1,22 +1,25 @@ + + Input support for Microsoft AutoRoute 2002-2006 .axe files + and Microsoft Streets and Trips .est files. This is for reading routes + created this program and is different than the + s_and_t format used for writing pushpins. + These files contains only routes. We can extract the coordinates and + the names of the points within route. An export to this format will + not be supported. + - - - Input support for Microsoft AutoRoute 2002-2006 .axe files -and Microsoft Streets and Trips .est files. This is for reading routes -created this program and is different than the -s_and_t format used for writing pushpins. -These files contains only routes. We can extract the coordinates and -the names of the points within route. An export to this format will -not be supported. - Only the start, stops, and end points are stored in the -.est/.axe/.ptm files. Turn-by-turn route data is not stored in the -.est/.axe/.ptm files, and is recalculated by the Microsoft title each -time on opening the file. This means that the output of GPSBabel will -not contain turns needed for driving directions. - One possible approach to achieve similar results is to -use the Streets and Trips drawing tools to trace a line over the -interesting parts of the route to capture intersections or key turns. -GPSBabel will capture stops in the route and insert those as turns, so -adding stops at intersections can also improve the results when converting. + + Only the start, stops, and end points are stored in the + .est/.axe/.ptm files. Turn-by-turn route data is not stored in the + .est/.axe/.ptm files, and is recalculated by the Microsoft title each + time on opening the file. This means that the output of GPSBabel will + not contain turns needed for driving directions. + + + One possible approach to achieve similar results is to + use the Streets and Trips drawing tools to trace a line over the + interesting parts of the route to capture intersections or key turns. + GPSBabel will capture stops in the route and insert those as turns, so + adding stops at intersections can also improve the results when converting. diff --git a/gpsbabel/xmldoc/formats/mtk.xml b/gpsbabel/xmldoc/formats/mtk.xml index f94ad780e..9276ca1f2 100644 --- a/gpsbabel/xmldoc/formats/mtk.xml +++ b/gpsbabel/xmldoc/formats/mtk.xml @@ -88,4 +88,8 @@ If you can confirm success with others, please share with us. For info about the used log format, see MTK binary format - + +Most of the loggers cannot receive bluetooth commands; they can only send + data. Since GPSBabel needs to send commands to the GPS device it won't + work. Download the data using the USB cable instead. + diff --git a/gpsbabel/xmldoc/formats/navicache.xml b/gpsbabel/xmldoc/formats/navicache.xml index 6400ce3c4..120c54b10 100644 --- a/gpsbabel/xmldoc/formats/navicache.xml +++ b/gpsbabel/xmldoc/formats/navicache.xml @@ -1,9 +1,8 @@ - - - - This is the XML format that's used by Navicache.com for -their geocaching data. There are a number of fields in it that are -marked "required" but are Navicache-specific, so GPSBabel can not -write these files, but we can still read them. navicache.com - + + This is the XML format that's used by Navicache.com for + their geocaching data. There are a number of fields in it that are + marked "required" but are Navicache-specific, so GPSBabel can not + write these files, but we can still read them. + navicache.com + diff --git a/gpsbabel/xmldoc/formats/openoffice.xml b/gpsbabel/xmldoc/formats/openoffice.xml index 56d50f1c0..036336d73 100644 --- a/gpsbabel/xmldoc/formats/openoffice.xml +++ b/gpsbabel/xmldoc/formats/openoffice.xml @@ -1,11 +1,9 @@ - - - - Tab seperated export-all (except geocaching data) file -format. Intended to serve as source for number-processing -applications like OpenOffice, Ploticus and others. Tab was chosen as -delimiter because it is a) supported by both OpenOffice and Ploticus -and b) is not ',', so you can use sed -i -"s/./,/g" <x>.csv' to adapt it to locales where ',' is -used as decimal seperator. Contributed by Tobias Minich. - + + Tab seperated export-all (except geocaching data) file + format. Intended to serve as source for number-processing + applications like OpenOffice, Ploticus and others. Tab was chosen as + delimiter because it is a) supported by both OpenOffice and Ploticus + and b) is not ',', so you can use sed -i + "s/./,/g" <x>.csv' to adapt it to locales where ',' is + used as decimal seperator. Contributed by Tobias Minich. + diff --git a/gpsbabel/xmldoc/formats/options/dg-200-erase.xml b/gpsbabel/xmldoc/formats/options/dg-200-erase.xml new file mode 100644 index 000000000..95424f0dd --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/dg-200-erase.xml @@ -0,0 +1 @@ +This option erases the track log from the device after download. diff --git a/gpsbabel/xmldoc/formats/options/dg-200-erase_only.xml b/gpsbabel/xmldoc/formats/options/dg-200-erase_only.xml new file mode 100644 index 000000000..6479f86f5 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/dg-200-erase_only.xml @@ -0,0 +1,6 @@ + + Much like the this optio erases the data in the GPS. + It does not transfer data before doing so, making it much faster. This may + be handy in a work flow where you want to transfer the data from the GPS, + check it on a map, and then remove it from the unit. + diff --git a/gpsbabel/xmldoc/formats/options/garmin_gpi-bitmap.xml b/gpsbabel/xmldoc/formats/options/garmin_gpi-bitmap.xml index a83f9cb36..d595aed46 100644 --- a/gpsbabel/xmldoc/formats/options/garmin_gpi-bitmap.xml +++ b/gpsbabel/xmldoc/formats/options/garmin_gpi-bitmap.xml @@ -8,6 +8,12 @@ into oen of the above formats to avoid errors about "Unsupported color depth".
+ + Not all devices can support all color depths. GPSBabel (and its + developers) have no way of knowing what is supported on any given model + so some experimentation may be necessary on your part. It was reported + that a Nuvi 3790, for example, will read the POIs only if they use 8BPP. + A color value of 0xFF00FF (blue=255, green=0, red=255), also called "Magenta", can be used for transparent areas. diff --git a/gpsbabel/xmldoc/formats/options/kml-units.xml b/gpsbabel/xmldoc/formats/options/kml-units.xml index 6d7a59578..733e74bb8 100644 --- a/gpsbabel/xmldoc/formats/options/kml-units.xml +++ b/gpsbabel/xmldoc/formats/options/kml-units.xml @@ -1,5 +1,5 @@ Units is a simple option. Specify 's' for "statute" (miles, feet, and other things that don't sensibly convert to each other, but are craved -by Americans) or 'm' for "metric". Default is 's'. +by Americans), 'm' for "metric", 'n' for "nautical" or 'a' for "aviation". Default is 's'. diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-Bar.xml b/gpsbabel/xmldoc/formats/options/miniHomer-Bar.xml new file mode 100644 index 000000000..67151f40d --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-Bar.xml @@ -0,0 +1,20 @@ + + The device provides a location finder display supporting five locations "Home", "Car", "Boat", "Heart", "Bar". + You can program the location of each either by a keypress on the device (which uses the actual position) + or with GPSBabel (which lets you use any position) + You can set the location of "Bar" with the 'Bar' option. Use ':' as the delimiter between latitude, longitude and altitude. + You can leave altitude out, in which case it is assumed to be zero. + Note that GPSBabel terminates after writing the location info to the device, i.e. no logging data will be read from it. + + + Set the target location of the miniHomer Bar POI + + gpsbabel -i miniHomer,Bar=38.99809:-86.34662 -f /dev/ttyUSB0 -o unicsv -F - + + + Sets the Bar symbols' latitude to 38.99809N longitude to 86.34662W and altitude to 0m. + If you select the Bar symbol on miniHomer, the display will show the direction and distance to + this location as soon as it has a satellite fix. + + + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-Boat.xml b/gpsbabel/xmldoc/formats/options/miniHomer-Boat.xml new file mode 100644 index 000000000..ba5cbc5b4 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-Boat.xml @@ -0,0 +1,20 @@ + + The device provides a location finder display supporting five locations "Home", "Car", "Boat", "Heart", "Bar". + You can program the location of each either by a keypress on the device (which uses the actual position) + or with GPSBabel (which lets you use any position) + You can set the location of "Boat" with the 'Boat' option. Use ':' as the delimiter between latitude, longitude and altitude. + You can leave altitude out, in which case it is assumed to be zero. + Note that GPSBabel terminates after writing the location info to the device, i.e. no logging data will be read from it. + + + Set the target location of the miniHomer Boat POI + + gpsbabel -i miniHomer,Boat=32.29287:-64.77527 -f /dev/ttyUSB0 -o unicsv -F - + + + Sets the Boat symbols' latitude to 32.29287N longitude to 64.77527E and altitude to 0m. + If you select the Home symbol on miniHomer, the display will show the direction and distance to + this location as soon as it has a satellite fix. + + + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-Car.xml b/gpsbabel/xmldoc/formats/options/miniHomer-Car.xml new file mode 100644 index 000000000..10d8f8868 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-Car.xml @@ -0,0 +1,20 @@ + + The device provides a location finder display supporting five locations "Home", "Car", "Boat", "Heart", "Bar". + You can program the location of each either by a keypress on the device (which uses the actual position) + or with GPSBabel (which lets you use any position) + You can set the location of "Car" with the 'Car' option. Use ':' as the delimiter between latitude, longitude and altitude. + You can leave altitude out, in which case it is assumed to be zero. + Note that GPSBabel terminates after writing the location info to the device, i.e. no logging data will be read from it. + + + Set the target location of the miniHomer Car POI + + gpsbabel -i miniHomer,Car=-25.272309:153.235330 -f /dev/ttyUSB0 -o unicsv -F - + + + Sets the Car symbols' latitude to 25.272309S longitude to 153.235330E and altitude to 0m. + If you select the Car symbol on miniHomer, the display will show the direction and distance to + this location as soon as it has a satellite fix. + + + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-Heart.xml b/gpsbabel/xmldoc/formats/options/miniHomer-Heart.xml new file mode 100644 index 000000000..9bed7327f --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-Heart.xml @@ -0,0 +1,20 @@ + + The device provides a location finder display supporting five locations "Home", "Car", "Boat", "Heart", "Bar". + You can program the location of each either by a keypress on the device (which uses the actual position) + or with GPSBabel (which lets you use any position) + You can set the location of "Heart" with the 'Heart' option. Use ':' as the delimiter between latitude, longitude and altitude. + You can leave altitude out, in which case it is assumed to be zero. + Note that GPSBabel terminates after writing the location info to the device, i.e. no logging data will be read from it. + + + Set the target location of the miniHomer Heart POI + + gpsbabel -i miniHomer,Heart=36.1269:-115.1698 -f /dev/ttyUSB0 -o unicsv -F - + + + Sets the Heart symbols' latitude to 36.1269N longitude to 115.1698W and altitude to 0m. + If you select the Heart symbol on miniHomer, the display will show the direction and distance to + this location as soon as it has a satellite fix. + + + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-Home.xml b/gpsbabel/xmldoc/formats/options/miniHomer-Home.xml new file mode 100644 index 000000000..ada385885 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-Home.xml @@ -0,0 +1,20 @@ + + The device provides a location finder display supporting five locations "Home", "Car", "Boat", "Heart", "Bar". + You can program the location of each either by a keypress on the device (which uses the actual position) + or with GPSBabel (which lets you use any position) + You can set the location of "Home" with the 'Home' option. Use ':' as the delimiter between latitude, longitude and altitude. + You can leave altitude out, in which case it is assumed to be zero. + Note that GPSBabel terminates after writing the location info to the device, i.e. no logging data will be read from it. + + + Set the target location of the miniHomer Home POI + + gpsbabel -i miniHomer,Home=-3.066667:37.359167:5895 -f /dev/ttyUSB0 -o unicsv -F - + + + Sets the Home symbols' latitude to 3.066667S longitude to 37.359167E and altitude to 5895m. + If you select the Home symbol on miniHomer, the display will show the direction and distance to + this location as soon as it has a satellite fix. + + + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-baud.xml b/gpsbabel/xmldoc/formats/options/miniHomer-baud.xml new file mode 100644 index 000000000..bc17c6c09 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-baud.xml @@ -0,0 +1,8 @@ +The following baud rates can be used: 4800, 9600, 19200, 38400, 57600, 115200, 230400. +Note that your logger might not support all of them (especially 230400 which isn't documented +in the chipset manual, though there are known devices that are capable of this speed). + + +If baud=0 (zero) download takes place at the baud rate the +device is currently set to. This is especially useful for Bluetooth connections (if available) since they +often don't allow changing the baud rate. diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-dump-file.xml b/gpsbabel/xmldoc/formats/options/miniHomer-dump-file.xml new file mode 100644 index 000000000..824b64672 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-dump-file.xml @@ -0,0 +1,6 @@ + +This function is identical to the dump-file function of skytraq module: +Writes raw data as it is read from the logger to the file given as this option's argument +(additional to decoding it as usual). The resulting binary files can be read and decoded by the skytraq-bin format. +Mainly useful for debugging/development purposes. + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-erase.xml b/gpsbabel/xmldoc/formats/options/miniHomer-erase.xml new file mode 100644 index 000000000..7921eb515 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-erase.xml @@ -0,0 +1,4 @@ + +Erase log buffer. + + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-first-sector.xml b/gpsbabel/xmldoc/formats/options/miniHomer-first-sector.xml new file mode 100644 index 000000000..1802768cf --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-first-sector.xml @@ -0,0 +1,15 @@ + +This function is identical to the first-sector function of skytraq module. + +The logger's memory is organized in sectors, serially numbered starting at 0. Each sector takes 4096 bytes of data. +Typical devices hold about 250 sectors. The memory is always filled from sector 0 on, until it is full or the device being +erased again by the user. + +Normally you can safely omit this option. However, it might be useful to read data from erased devices: we observed +that on erase, only the first two sectors are actually cleared. The following example shows how to read the remaining data: + + + + Command showing how to read data from an erased device + gpsbabel -i miniHomer,first-sector=2 -f /dev/ttyUSB0 -o gpx -F out.gpx + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-initbaud.xml b/gpsbabel/xmldoc/formats/options/miniHomer-initbaud.xml new file mode 100644 index 000000000..0edfdee58 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-initbaud.xml @@ -0,0 +1,13 @@ + +This function is identical to the init-baud file function of skytraq module. + +The "initbaud" option might be helpful if autodetection fails or takes too long. With this option you +can tell GPSBabel the baud rate the device is currently set to. In contrast, the option "baud" specifies +the rate at which the actual download should take place. If it is different than "initbaud" (or the autodetected +rate, if initbaud wasn't given), the initial setting will be restored after finishing the download. + + +Please note that miniHomer by default uses 38400bps and does not autodetect the port speed. If you need autodetect, start as +gpsbabel -i miniHomer,initibaud=0 -f /dev/ttyUSB0 -o gpx -F out.gpx + + diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-last-sector.xml b/gpsbabel/xmldoc/formats/options/miniHomer-last-sector.xml new file mode 100644 index 000000000..836f46e23 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-last-sector.xml @@ -0,0 +1,5 @@ +A value of -1 (the default) enables automatic mode, i.e. reading is stopped when an empty sector is +encountered. +We observed that sometimes the device doesn't report the correct number of used sectors, which confuses the Windows +software, so that it might not get all trackpoints. +In contrast, our algorithm ensures that everything is being read (please report if it doesn't work for you). diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-no-output.xml b/gpsbabel/xmldoc/formats/options/miniHomer-no-output.xml new file mode 100644 index 000000000..482aa8c17 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-no-output.xml @@ -0,0 +1,2 @@ +If this option is given, no GPS log data will be read from the device +(unless "dump-file" is given too; in that case only decoding will be disabled). diff --git a/gpsbabel/xmldoc/formats/options/miniHomer-read-at-once.xml b/gpsbabel/xmldoc/formats/options/miniHomer-read-at-once.xml new file mode 100644 index 000000000..7283235cb --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/miniHomer-read-at-once.xml @@ -0,0 +1,7 @@ +If read-at-once >= 1, batch mode is enabled with that many sectors being read at a time. +A value of zero disables batch mode and switches to single read mode. Not all devices support batch mode; in that case +gpsbabel automatically switches to single read mode. + +Under normal circumstances, the larger this number the faster the transfer. +Reducing read-at-once or even switching to single sector mode might help when you get +transmission errors/aborts. diff --git a/gpsbabel/xmldoc/formats/ozi.xml b/gpsbabel/xmldoc/formats/ozi.xml index 1e3819a0e..00d9bafd4 100644 --- a/gpsbabel/xmldoc/formats/ozi.xml +++ b/gpsbabel/xmldoc/formats/ozi.xml @@ -1,7 +1,5 @@ - - - - OziExplorer Waypoint Format - Another CSV format file. -Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex -Mottram + + OziExplorer Waypoint Format - Another CSV format file. + Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex Mottram + diff --git a/gpsbabel/xmldoc/formats/palmdoc.xml b/gpsbabel/xmldoc/formats/palmdoc.xml index 2ed7ff68b..febf0a466 100644 --- a/gpsbabel/xmldoc/formats/palmdoc.xml +++ b/gpsbabel/xmldoc/formats/palmdoc.xml @@ -1,13 +1,14 @@ -PalmDoc output is similar to Text -output, except that it generates a Palm Database (PDB) file suitable for -use with programs like CSpotRun, TealDoc, AportisDoc, Palm Reader, and -others. The resulting file also contains bookmarks to make it easy to jump -to a particular waypoint. + PalmDoc output is similar to Text + output, except that it generates a Palm Database (PDB) file suitable for + use with programs like CSpotRun, TealDoc, AportisDoc, Palm Reader, and + others. The resulting file also contains bookmarks to make it easy to jump + to a particular waypoint. -The following command line reads a GPX file with Groundspeak extensions -and writes a Palm document with encrypted hints and logs: + The following command line reads a GPX file with Groundspeak extensions + and writes a Palm document with encrypted hints and logs: + +gpsbabel -i gpx -f 12345.gpx -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" -F 12345.pdb -gpsbabel -i gpx -f 12345.gpx -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" -F 12345.pdb diff --git a/gpsbabel/xmldoc/formats/pathaway.xml b/gpsbabel/xmldoc/formats/pathaway.xml index 435adff4d..8310068c0 100644 --- a/gpsbabel/xmldoc/formats/pathaway.xml +++ b/gpsbabel/xmldoc/formats/pathaway.xml @@ -1,10 +1,8 @@ - - - - PathAway is a Palm software designed for handling "most" -GPS devices (including BlueTooth). In this time (I mean 2005) a free -tool to convert this database is located on the homepage of PathAway -(www.pathaway.com). But I've read there ... for windows and the output -formats are also very limited. + + PathAway is a Palm software designed for handling "most" + GPS devices (including BlueTooth). In this time (I mean 2005) a free + tool to convert this database is located on the homepage of PathAway + (www.pathaway.com). But I've read there ... for windows and the output + formats are also very limited. diff --git a/gpsbabel/xmldoc/formats/pcx.xml b/gpsbabel/xmldoc/formats/pcx.xml index 60abecec5..4c7330473 100644 --- a/gpsbabel/xmldoc/formats/pcx.xml +++ b/gpsbabel/xmldoc/formats/pcx.xml @@ -1,6 +1,3 @@ - - - Garmin documents only PCX5, an older format limited to the lame NMEA six-character waypoint names that's treated as a second-class citizien in current versions of MapSource. In Mapsource, diff --git a/gpsbabel/xmldoc/formats/s_and_t.xml b/gpsbabel/xmldoc/formats/s_and_t.xml index 2df639326..fda190d97 100644 --- a/gpsbabel/xmldoc/formats/s_and_t.xml +++ b/gpsbabel/xmldoc/formats/s_and_t.xml @@ -1,16 +1,23 @@ + This is a format for creating data to be read by + Microsoft Streets and + Trips. It's been exercised on versions from 2003 through 2008. Detailed + instructions on how to use it, including preserving hyperlinks, are at + gpsbabel.org + + + We have an additional page describing how to solve the + traveling salesman problem with + Streets & Trips to efficiently optimize a trip with many stops, such as + is often made by geocachers. + + + + This format has nothing to do with the .est/axe format + used by this program to store routes. + - - - This is a format for creating data to be read by - Microsoft Streets and -Trips. It's been exercised on versions from 2003 through 2008. Detailed -instructions on how to use it, including preserving hyperlinks, are at -gpsbabel.org - - We have an additional page describing how to solve the traveling salesman problem with Streets & Trips to efficiently optimize a trip with many stops, such as is often made by geocachers. + Since modern versions of Streets and Trips support reading GPX, this format is probably + not so useful. - - This format has nothing to do with the .est/axe format used by this program to store routes. - diff --git a/gpsbabel/xmldoc/formats/sbn.xml b/gpsbabel/xmldoc/formats/sbn.xml index 18d22215c..7adb91fd4 100644 --- a/gpsbabel/xmldoc/formats/sbn.xml +++ b/gpsbabel/xmldoc/formats/sbn.xml @@ -1,6 +1,6 @@ This format is for SBN datalog files saved to the SD card by - the Locosys GT-11/BGT-11/GT-31/BGT-31. + the Locosys GT-11/BGT-11/GT-31/BGT-31 GPS receivers. On the device, logging in this format is enabled by choosing diff --git a/gpsbabel/xmldoc/formats/sbp.xml b/gpsbabel/xmldoc/formats/sbp.xml index 98e61755c..7d41cb7f6 100644 --- a/gpsbabel/xmldoc/formats/sbp.xml +++ b/gpsbabel/xmldoc/formats/sbp.xml @@ -1,4 +1,4 @@ This format is for SBP datalog files saved to the SD card by - the Locosys GT-11/BGT-11/GT-31/BGT-31. + the Locosys GT-11/BGT-11/GT-31/BGT-31 GPS receivers. diff --git a/gpsbabel/xmldoc/formats/shape.xml b/gpsbabel/xmldoc/formats/shape.xml index fc97f6946..2c14744d7 100644 --- a/gpsbabel/xmldoc/formats/shape.xml +++ b/gpsbabel/xmldoc/formats/shape.xml @@ -3,12 +3,12 @@ reality is that shapefiles can contain a lot of map-oriented data that does not convert well to our model of waypoints, tracks, and routes. Points are mapped to waypoints. Arcs are mapped to tracks. -If a field is named 'NAME', that will be used for hte shortname. Likewise +If a field is named 'NAME', that will be used for the shortname. Likewise for a field named 'URL'. Given the forced fit nature of conversions between shapefiles and other -formats, the results of these conversions are frequently disappointing. +common consumer formats, the results of these conversions are frequently disappointing. A custom converter (perhaps via a modification to our source) will frequently deliver better results. diff --git a/gpsbabel/xmlgeneric.c b/gpsbabel/xmlgeneric.c index a8bdf32bf..53c85fdfa 100644 --- a/gpsbabel/xmlgeneric.c +++ b/gpsbabel/xmlgeneric.c @@ -24,8 +24,8 @@ #include "cet_util.h" #if HAVE_LIBEXPAT - #include - static XML_Parser psr; +#include +static XML_Parser psr; #endif static vmem_t current_tag; @@ -41,115 +41,118 @@ static const char **xg_ignore_taglist; void write_xml_header(gbfile *ofd) { - char buff[128]; - cet_cs_vec_t *cs = cet_find_cs_by_name(CET_CHARSET_ASCII); - - if ((global_opts.charset != NULL) && (global_opts.charset != cs)) - snprintf(buff, sizeof(buff), " encoding=\"%s\"", global_opts.charset_name); - else - buff[0] = 0; - gbfprintf(ofd, "\n", buff); + char buff[128]; + cet_cs_vec_t *cs = cet_find_cs_by_name(CET_CHARSET_ASCII); + + if ((global_opts.charset != NULL) && (global_opts.charset != cs)) { + snprintf(buff, sizeof(buff), " encoding=\"%s\"", global_opts.charset_name); + } else { + buff[0] = 0; + } + gbfprintf(ofd, "\n", buff); } void write_xml_entity(gbfile *ofd, const char *indent, const char *tag, const char *value) { - char *tmp_ent = xml_entitize(value); - gbfprintf(ofd, "%s<%s>%s\n", indent, tag, tmp_ent, tag); - xfree(tmp_ent); + char *tmp_ent = xml_entitize(value); + gbfprintf(ofd, "%s<%s>%s\n", indent, tag, tmp_ent, tag); + xfree(tmp_ent); } void write_optional_xml_entity(gbfile *ofd, const char *indent, const char *tag, const char *value) { - if (value && *value) - write_xml_entity(ofd, indent, tag, value); + if (value && *value) { + write_xml_entity(ofd, indent, tag, value); + } } void write_xml_entity_begin0(gbfile *ofd, const char *indent, - const char *tag) + const char *tag) { - gbfprintf(ofd, "%s<%s>\n", indent, tag); + gbfprintf(ofd, "%s<%s>\n", indent, tag); } void write_xml_entity_begin1(gbfile *ofd, const char *indent, - const char *tag, const char *attr, - const char *attrval) + const char *tag, const char *attr, + const char *attrval) { - gbfprintf(ofd, "%s<%s %s=\"%s\">\n", indent, tag, attr, attrval); + gbfprintf(ofd, "%s<%s %s=\"%s\">\n", indent, tag, attr, attrval); } void write_xml_entity_begin2(gbfile *ofd, const char *indent, - const char *tag, const char *attr1, - const char *attrval1, const char *attr2, - const char *attrval2) + const char *tag, const char *attr1, + const char *attrval1, const char *attr2, + const char *attrval2) { - gbfprintf(ofd, "%s<%s %s=\"%s\" %s=\"%s\">\n", indent, tag, attr1, attrval1, attr2, attrval2); + gbfprintf(ofd, "%s<%s %s=\"%s\" %s=\"%s\">\n", indent, tag, attr1, attrval1, attr2, attrval2); } void write_xml_entity_end(gbfile *ofd, const char *indent, - const char *tag) + const char *tag) { - gbfprintf(ofd, "%s\n", indent, tag); + gbfprintf(ofd, "%s\n", indent, tag); } void xml_fill_in_time(char *time_string, const time_t timep, int microseconds, int long_or_short) { - struct tm *tm = gmtime(&timep); - char *format; - int n; - - if (!tm) { - *time_string = 0; - return; - } - - if (long_or_short == XML_LONG_TIME) - format = "%02d-%02d-%02dT%02d:%02d:%02d"; - else - format = "%02d%02d%02dT%02d%02d%02d"; - n = sprintf(time_string, format, - tm->tm_year+1900, - tm->tm_mon+1, - tm->tm_mday, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - if (microseconds) { - n += sprintf(time_string + n, ".%03d", microseconds / 1000); - } - time_string[n++] = 'Z'; - time_string[n++] = '\0'; - + struct tm *tm = gmtime(&timep); + char *format; + int n; + + if (!tm) { + *time_string = 0; + return; + } + + if (long_or_short == XML_LONG_TIME) { + format = "%02d-%02d-%02dT%02d:%02d:%02d"; + } else { + format = "%02d%02d%02dT%02d%02d%02d"; + } + n = sprintf(time_string, format, + tm->tm_year+1900, + tm->tm_mon+1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + if (microseconds) { + n += sprintf(time_string + n, ".%03d", microseconds / 1000); + } + time_string[n++] = 'Z'; + time_string[n++] = '\0'; + } void xml_write_time(gbfile *ofd, const time_t timep, int microseconds, const char *elname) { - char time_string[64]; - xml_fill_in_time(time_string, timep, microseconds, XML_LONG_TIME); - if (time_string[0]) { - gbfprintf(ofd, "<%s>%s\n", - elname, - time_string, - elname - ); - } + char time_string[64]; + xml_fill_in_time(time_string, timep, microseconds, XML_LONG_TIME); + if (time_string[0]) { + gbfprintf(ofd, "<%s>%s\n", + elname, + time_string, + elname + ); + } } /*********************************************************************** * These implement a simple interface for "generic" XML that * maps reasonably close to 1:1 between XML tags and internal data - * structures. - * + * structures. + * * It doesn't work well for formats (like GPX) that really are "real" * XML with extended namespaces and such, but it handles many simpler * xml strains and insulates us from a lot of the grubbiness of expat. @@ -158,13 +161,13 @@ xml_write_time(gbfile *ofd, const time_t timep, int microseconds, const char *el xg_callback * xml_tbl_lookup(const char *tag, xg_cb_type cb_type) { - xg_tag_mapping *tm; - for (tm = xg_tag_tbl; tm->tag_cb != NULL; tm++) { - if (str_match(tag, tm->tag_name) && (cb_type == tm->cb_type)) { - return tm->tag_cb; - } - } - return NULL; + xg_tag_mapping *tm; + for (tm = xg_tag_tbl; tm->tag_cb != NULL; tm++) { + if (str_match(tag, tm->tag_name) && (cb_type == tm->cb_type)) { + return tm->tag_cb; + } + } + return NULL; } /* @@ -174,202 +177,208 @@ xml_tbl_lookup(const char *tag, xg_cb_type cb_type) static int xml_consider_ignoring(const char *t) { - const char **il; - - if (!xg_ignore_taglist) { - return 0; - } - - for (il = xg_ignore_taglist; *il; il++) { - if (0 == strcmp(*il, t)) { - return 1; - } - } - return 0; + const char **il; + + if (!xg_ignore_taglist) { + return 0; + } + + for (il = xg_ignore_taglist; *il; il++) { + if (0 == strcmp(*il, t)) { + return 1; + } + } + return 0; } static void xml_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { - char *e; - char *ep; - xg_callback *cb; - const char *el; - const char **attrs; - - el = xml_convert_to_char_string(xml_el); - attrs = xml_convert_attrs_to_char_string(xml_attr); - - if (xml_consider_ignoring(el)) - return; - - vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); - - e = current_tag.mem; - ep = e + strlen(e); - *ep++ = '/'; - strcpy(ep, el); - - memset(cdatastr.mem, 0, cdatastr.size); - - cb = xml_tbl_lookup(e, cb_start); - if (cb) { - (*cb)(NULL, attrs); - } - xml_free_converted_string(el); - xml_free_converted_attrs(attrs); + char *e; + char *ep; + xg_callback *cb; + const char *el; + const char **attrs; + + el = xml_convert_to_char_string(xml_el); + attrs = xml_convert_attrs_to_char_string(xml_attr); + + if (xml_consider_ignoring(el)) { + return; + } + + vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); + + e = current_tag.mem; + ep = e + strlen(e); + *ep++ = '/'; + strcpy(ep, el); + + memset(cdatastr.mem, 0, cdatastr.size); + + cb = xml_tbl_lookup(e, cb_start); + if (cb) { + (*cb)(NULL, attrs); + } + xml_free_converted_string(el); + xml_free_converted_attrs(attrs); } #if HAVE_LIBEXPAT static void xml_cdata(void *dta, const XML_Char *xml_s, int len) { - char *estr; - const char *s = xml_convert_to_char_string_n(xml_s, &len); - - vmem_realloc(&cdatastr, 1 + len + strlen(cdatastr.mem)); - estr = (char *) cdatastr.mem + strlen(cdatastr.mem); - memcpy(estr, s, len); - estr[len] = 0; - xml_free_converted_string(s); + char *estr; + const char *s = xml_convert_to_char_string_n(xml_s, &len); + + vmem_realloc(&cdatastr, 1 + len + strlen(cdatastr.mem)); + estr = (char *) cdatastr.mem + strlen(cdatastr.mem); + memcpy(estr, s, len); + estr[len] = 0; + xml_free_converted_string(s); } static void xml_end(void *data, const XML_Char *xml_el) { - char *s = strrchr(current_tag.mem, '/'); - const char *el = xml_convert_to_char_string(xml_el); - xg_callback *cb; - - if (xml_consider_ignoring(el)) - return; - - if (strcmp(s + 1, el)) { - fprintf(stderr, "Mismatched tag %s\n", el); - } - cb = xml_tbl_lookup(current_tag.mem, cb_cdata); - if (cb) { - (*cb)( (char *) cdatastr.mem, NULL); - } - - cb = xml_tbl_lookup(current_tag.mem, cb_end); - if (cb) { - (*cb)(el, NULL); - } - *s = 0; - xml_free_converted_string(el); + char *s = strrchr(current_tag.mem, '/'); + const char *el = xml_convert_to_char_string(xml_el); + xg_callback *cb; + + if (xml_consider_ignoring(el)) { + return; + } + + if (strcmp(s + 1, el)) { + fprintf(stderr, "Mismatched tag %s\n", el); + } + cb = xml_tbl_lookup(current_tag.mem, cb_cdata); + if (cb) { + (*cb)((char *) cdatastr.mem, NULL); + } + + cb = xml_tbl_lookup(current_tag.mem, cb_end); + if (cb) { + (*cb)(el, NULL); + } + *s = 0; + xml_free_converted_string(el); } void xml_read(void) { - int len; - char buf[MY_CBUF]; - - while ((len = gbfread(buf, 1, sizeof(buf), ifd))) { - char *str = buf; - if (ifd->unicode) { - str = cet_str_uni_to_utf8((short *)&buf, len >> 1); - len = strlen(str); - } - if (!XML_Parse(psr, str, len, gbfeof(ifd))) { - fatal(MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - if (str != buf) xfree(str); - } - XML_ParserFree(psr); - + int len; + char buf[MY_CBUF]; + + while ((len = gbfread(buf, 1, sizeof(buf), ifd))) { + char *str = buf; + if (ifd->unicode) { + str = cet_str_uni_to_utf8((short *)&buf, len >> 1); + len = strlen(str); + } + if (!XML_Parse(psr, str, len, gbfeof(ifd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + if (str != buf) { + xfree(str); + } + } + XML_ParserFree(psr); + } -void xml_readstring( char *str ) +void xml_readstring(char *str) { - int len = strlen(str); - if (!XML_Parse(psr, str, len, 1)) { - fatal( MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - XML_ParserFree(psr); + int len = strlen(str); + if (!XML_Parse(psr, str, len, 1)) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + XML_ParserFree(psr); } -void xml_readprefixstring( char *str ) +void xml_readprefixstring(char *str) { - int len = strlen(str); - if (!XML_Parse(psr, str, len, 0)) { - fatal( MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } + int len = strlen(str); + if (!XML_Parse(psr, str, len, 0)) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } } void xml_ignore_tags(const char **taglist) { - xg_ignore_taglist = taglist; + xg_ignore_taglist = taglist; } void -xml_init0(const char *fname, xg_tag_mapping *tbl, const char *encoding, - gbsize_t offset ) +xml_init0(const char *fname, xg_tag_mapping *tbl, const char *encoding, + gbsize_t offset) { - if (fname) { - ifd = gbfopen(fname, "r", MYNAME); - if (offset) { - gbfseek(ifd, offset, SEEK_SET); - } - } else { - ifd = NULL; - } + if (fname) { + ifd = gbfopen(fname, "r", MYNAME); + if (offset) { + gbfseek(ifd, offset, SEEK_SET); + } + } else { + ifd = NULL; + } - current_tag = vmem_alloc(1,0); - *((char *)current_tag.mem) = '\0'; + current_tag = vmem_alloc(1,0); + *((char *)current_tag.mem) = '\0'; - psr = XML_ParserCreate((const XML_Char *)encoding); - if (!psr) { - fatal(MYNAME ": Cannot create XML Parser\n"); - } + psr = XML_ParserCreate((const XML_Char *)encoding); + if (!psr) { + fatal(MYNAME ": Cannot create XML Parser\n"); + } - cdatastr = vmem_alloc(1, 0); - *((char *)cdatastr.mem) = '\0'; + cdatastr = vmem_alloc(1, 0); + *((char *)cdatastr.mem) = '\0'; - xg_tag_tbl = tbl; + xg_tag_tbl = tbl; - cet_convert_init(CET_CHARSET_UTF8, 1); + cet_convert_init(CET_CHARSET_UTF8, 1); - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - XML_SetElementHandler(psr, xml_start, xml_end); - XML_SetCharacterDataHandler(psr, xml_cdata); + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, xml_start, xml_end); + XML_SetCharacterDataHandler(psr, xml_cdata); } /* xml_init0 iwth a default seek argument of zero */ void -xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) { +xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) +{ xml_init0(fname, tbl, encoding, 0); } void xml_init_offset(const char *fname, xg_tag_mapping *tbl, const char *encoding, - gbsize_t offset) { + gbsize_t offset) +{ xml_init0(fname, tbl, encoding, offset); } void xml_deinit(void) { - vmem_free(¤t_tag); - vmem_free(&cdatastr); - if (ifd) { - gbfclose(ifd); - ifd = NULL; - } - xg_ignore_taglist = NULL; + vmem_free(¤t_tag); + vmem_free(&cdatastr); + if (ifd) { + gbfclose(ifd); + ifd = NULL; + } + xg_ignore_taglist = NULL; } #else /* HAVE_LIBEXPAT */ void xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) { - fatal("This format does not support reading XML files as libexpat was not present."); + fatal("This format does not support reading XML files as libexpat was not present."); } void xml_read(void) diff --git a/gpsbabel/xmlgeneric.h b/gpsbabel/xmlgeneric.h index 79fa84a2f..3a7fca824 100644 --- a/gpsbabel/xmlgeneric.h +++ b/gpsbabel/xmlgeneric.h @@ -22,44 +22,44 @@ typedef enum { - cb_start = 1, - cb_cdata, - cb_end, + cb_start = 1, + cb_cdata, + cb_end, } xg_cb_type; -typedef void (xg_callback) (const char *, const char **); +typedef void (xg_callback)(const char*, const char**); typedef struct xg_tag_mapping { - xg_callback *tag_cb; - xg_cb_type cb_type; - const char *tag_name; + xg_callback* tag_cb; + xg_cb_type cb_type; + const char* tag_name; } xg_tag_mapping; -extern char *xhtml_entities; +extern char* xhtml_entities; -void write_xml_entity(gbfile *ofd, const char *indent, - const char *tag, const char *value); -void write_xml_entity_begin0(gbfile *ofd, const char *indent, - const char *tag); -void write_xml_entity_begin1(gbfile *ofd, const char *indent, const char *tag, - const char *attr1, const char *attrval1); -void write_xml_entity_begin2(gbfile *ofd, const char *indent, const char *tag, - const char *attr1, const char *attrval1, - const char *attr2, const char *attrval2); -void write_xml_entity_end(gbfile *ofd, const char *indent, const char *tag); +void write_xml_entity(gbfile* ofd, const char* indent, + const char* tag, const char* value); +void write_xml_entity_begin0(gbfile* ofd, const char* indent, + const char* tag); +void write_xml_entity_begin1(gbfile* ofd, const char* indent, const char* tag, + const char* attr1, const char* attrval1); +void write_xml_entity_begin2(gbfile* ofd, const char* indent, const char* tag, + const char* attr1, const char* attrval1, + const char* attr2, const char* attrval2); +void write_xml_entity_end(gbfile* ofd, const char* indent, const char* tag); -void write_optional_xml_entity(gbfile *ofd, const char *indent, - const char *tag, const char *value); -void xml_write_time(gbfile *ofd, const time_t timep, int microseconds, const char *elname); -void xml_fill_in_time(char *time_string, const time_t timep, int microseconds, - int long_or_short); -void write_xml_header(gbfile *ofd); -void xml_ignore_tags(const char **taglist); +void write_optional_xml_entity(gbfile* ofd, const char* indent, + const char* tag, const char* value); +void xml_write_time(gbfile* ofd, const time_t timep, int microseconds, const char* elname); +void xml_fill_in_time(char* time_string, const time_t timep, int microseconds, + int long_or_short); +void write_xml_header(gbfile* ofd); +void xml_ignore_tags(const char** taglist); -void xml_init(const char *fname, xg_tag_mapping *tbl,const char *encoding); -void xml_init_offset(const char *fname, xg_tag_mapping *tbl, - const char *encoding, gbsize_t offset); +void xml_init(const char* fname, xg_tag_mapping* tbl,const char* encoding); +void xml_init_offset(const char* fname, xg_tag_mapping* tbl, + const char* encoding, gbsize_t offset); void xml_read(void); -void xml_readstring(char *str); -void xml_readprefixstring(char *str); +void xml_readstring(char* str); +void xml_readprefixstring(char* str); void xml_deinit(void); diff --git a/gpsbabel/xmltag.c b/gpsbabel/xmltag.c index 2fbeaa618..b769278be 100644 --- a/gpsbabel/xmltag.c +++ b/gpsbabel/xmltag.c @@ -1,6 +1,6 @@ /* - Functions to deal with xml_tags - + Functions to deal with xml_tags + Copyright (C) 2005 Ron Parker and Robert Lipe. This program is free software; you can redistribute it and/or modify @@ -26,135 +26,143 @@ #include "defs.h" static void -free_xml_tag( xml_tag *tag ) +free_xml_tag(xml_tag *tag) { - xml_tag *next = NULL; - char **ap; - - while ( tag ) { - if (tag->cdata) { - xfree(tag->cdata); - } - if (tag->child) { - free_gpx_extras(tag->child); - } - if (tag->parentcdata) { - xfree(tag->parentcdata); - } - if (tag->tagname) { - xfree(tag->tagname); - } - if (tag->attributes) { - ap = tag->attributes; - - while (*ap) - xfree(*ap++); - - xfree(tag->attributes); - } - - next = tag->sibling; - xfree(tag); - tag = next; - } + xml_tag *next = NULL; + char **ap; + + while (tag) { + if (tag->cdata) { + xfree(tag->cdata); + } + if (tag->child) { + free_gpx_extras(tag->child); + } + if (tag->parentcdata) { + xfree(tag->parentcdata); + } + if (tag->tagname) { + xfree(tag->tagname); + } + if (tag->attributes) { + ap = tag->attributes; + + while (*ap) { + xfree(*ap++); + } + + xfree(tag->attributes); + } + + next = tag->sibling; + xfree(tag); + tag = next; + } } static void -copy_xml_tag( xml_tag **copy, xml_tag *src, xml_tag *parent ) { - xml_tag *res = NULL; - char **ap = NULL; - char **ap2 = NULL; - int count = 0; - - if ( !src ) { - *copy = NULL; - return; - } - - res = (xml_tag*) xcalloc( 1, sizeof(xml_tag)); - *copy = res; - - memcpy( res, src, sizeof(xml_tag)); - res->tagname = xstrdup( src->tagname ); - res->cdata = xstrdup( src->cdata ); - res->parentcdata = xstrdup( src->parentcdata ); - if ( src->attributes ) { - ap = src->attributes; - while ( *ap ) { - count++; - ap++; - } - res->attributes = (char **)xcalloc( count+1, sizeof(char *)); - ap = src->attributes; - ap2 = res->attributes; - while (*ap) { - *ap2 = xstrdup(*ap); - ap++; - ap2++; - } - } - res->parent = parent; - copy_xml_tag( &(res->sibling), src->sibling, parent ); - copy_xml_tag( &(res->child), src->child, res ); +copy_xml_tag(xml_tag **copy, xml_tag *src, xml_tag *parent) +{ + xml_tag *res = NULL; + char **ap = NULL; + char **ap2 = NULL; + int count = 0; + + if (!src) { + *copy = NULL; + return; + } + + res = (xml_tag*) xcalloc(1, sizeof(xml_tag)); + *copy = res; + + memcpy(res, src, sizeof(xml_tag)); + res->tagname = xstrdup(src->tagname); + res->cdata = xstrdup(src->cdata); + res->parentcdata = xstrdup(src->parentcdata); + if (src->attributes) { + ap = src->attributes; + while (*ap) { + count++; + ap++; + } + res->attributes = (char **)xcalloc(count+1, sizeof(char *)); + ap = src->attributes; + ap2 = res->attributes; + while (*ap) { + *ap2 = xstrdup(*ap); + ap++; + ap2++; + } + } + res->parent = parent; + copy_xml_tag(&(res->sibling), src->sibling, parent); + copy_xml_tag(&(res->child), src->child, res); } -static void -convert_xml_tag( xml_tag *tag ) { - char **ap = NULL; - - if (tag == NULL) return; - - tag->cdata = cet_convert_string(tag->cdata); - tag->parentcdata = cet_convert_string(tag->parentcdata); - - ap = tag->attributes; - while (*ap) - { - *ap = cet_convert_string(*ap); - ap++; - } - convert_xml_tag(tag->sibling); - convert_xml_tag(tag->child); +static void +convert_xml_tag(xml_tag *tag) +{ + char **ap = NULL; + + if (tag == NULL) { + return; + } + + tag->cdata = cet_convert_string(tag->cdata); + tag->parentcdata = cet_convert_string(tag->parentcdata); + + ap = tag->attributes; + while (*ap) { + *ap = cet_convert_string(*ap); + ap++; + } + convert_xml_tag(tag->sibling); + convert_xml_tag(tag->child); } -fs_xml *fs_xml_alloc( long type ); +fs_xml *fs_xml_alloc(long type); static void -fs_xml_destroy( void *fs ) { - fs_xml *xml = (fs_xml *)fs; - if ( xml ) { - free_xml_tag( xml->tag ); - } - xfree( fs ); +fs_xml_destroy(void *fs) +{ + fs_xml *xml = (fs_xml *)fs; + if (xml) { + free_xml_tag(xml->tag); + } + xfree(fs); } static void -fs_xml_copy( void **copy, void *source ) { - fs_xml *src = (fs_xml *)source; - if ( !source ) { - *copy = NULL; - return; - } - *copy = (void *)fs_xml_alloc( src->fs.type ); - memcpy( *copy, source, sizeof(fs_xml) ); - copy_xml_tag( &(((fs_xml *)(*copy))->tag), src->tag, NULL ); +fs_xml_copy(void **copy, void *source) +{ + fs_xml *src = (fs_xml *)source; + if (!source) { + *copy = NULL; + return; + } + *copy = (void *)fs_xml_alloc(src->fs.type); + memcpy(*copy, source, sizeof(fs_xml)); + copy_xml_tag(&(((fs_xml *)(*copy))->tag), src->tag, NULL); } static void -fs_xml_convert( void *fs ) { - fs_xml *xml = (fs_xml *)fs; - if ( xml ) { - convert_xml_tag( xml->tag ); - } +fs_xml_convert(void *fs) +{ + fs_xml *xml = (fs_xml *)fs; + if (xml) { + convert_xml_tag(xml->tag); + } } -fs_xml *fs_xml_alloc( long type ) { - fs_xml *result = NULL; - - result = (fs_xml *)xcalloc( 1, sizeof(fs_xml)); - result->fs.type = type; - result->fs.copy = fs_xml_copy; - result->fs.destroy = fs_xml_destroy; - result->fs.convert = fs_xml_convert; - return result; +fs_xml *fs_xml_alloc(long type) +{ + fs_xml *result = NULL; + + result = (fs_xml *)xcalloc(1, sizeof(fs_xml)); + result->fs.type = type; + result->fs.copy = fs_xml_copy; + result->fs.destroy = fs_xml_destroy; + result->fs.convert = fs_xml_convert; + return result; } diff --git a/gpsbabel/xol.c b/gpsbabel/xol.c index d0c648f75..874c803ce 100644 --- a/gpsbabel/xol.c +++ b/gpsbabel/xol.c @@ -1,4 +1,4 @@ -/* +/* Support for Swiss Map # (.xol) format @@ -32,9 +32,8 @@ static int space; static bounds all_bounds; static short_handle short_h; -static arglist_t xol_args[] = -{ - ARG_TERMINATOR +static arglist_t xol_args[] = { + ARG_TERMINATOR }; #define MYNAME "xol" @@ -43,7 +42,7 @@ static arglist_t xol_args[] = void xol_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); } void @@ -60,119 +59,129 @@ static xg_callback xol_waypt, xol_overlay; static xg_tag_mapping xol_map[] = { - { xol_overlay, cb_start, XOL }, - { xol_shape, cb_start, XOL "/shapes/*shape" }, - { xol_shape_end, cb_end, XOL "/shapes/*shape" }, - { xol_waypt, cb_start, XOL "/shapes/shape/*points/point" }, - { NULL, 0, NULL } + { xol_overlay, cb_start, XOL }, + { xol_shape, cb_start, XOL "/shapes/*shape" }, + { xol_shape_end, cb_end, XOL "/shapes/*shape" }, + { xol_waypt, cb_start, XOL "/shapes/shape/*points/point" }, + { NULL, (xg_cb_type)0, NULL } }; static void xol_overlay(const char *args, const char **attrv) { - const char **avp = &attrv[0]; + const char **avp = &attrv[0]; - while (*avp) { - if (strcmp(avp[0], "version") == 0) { - if (strcmp(avp[1], "1.0") != 0) - fatal(MYNAME ": Unsupported version %s.\n", avp[1]); - } + while (*avp) { + if (strcmp(avp[0], "version") == 0) { + if (strcmp(avp[1], "1.0") != 0) { + fatal(MYNAME ": Unsupported version %s.\n", avp[1]); + } + } - avp+=2; - } + avp+=2; + } } static void xol_shape(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - while (*avp) { - if (strcmp(avp[0], "type") == 0) { - if (strcmp(avp[1], "waypoint") == 0) { - wpt = waypt_new(); - } - else if (strcmp(avp[1], "polyline") == 0) { - trk = route_head_alloc(); - track_add_head(trk); - } - } - else if (strcmp(avp[0], "name") == 0) { - if (wpt) wpt->shortname = xstrdup(avp[1]); - else if (trk) trk->rte_name = xstrdup(avp[1]); - } - else if (strcmp(avp[0], "comment") == 0) { - if (wpt) wpt->notes = xstrdup(avp[1]); - } - else if (strcmp(avp[0], "alt") == 0) { - if (wpt) wpt->altitude = atof(avp[1]); - } - else if (strcmp(avp[0], "timestamp") == 0) { - if (wpt) wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); - } - else if (strcmp(avp[0], "icon") == 0) { - if (wpt) { - wpt->icon_descr = xstrdup(avp[1]); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - } - } - - avp+=2; - } + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "type") == 0) { + if (strcmp(avp[1], "waypoint") == 0) { + wpt = waypt_new(); + } else if (strcmp(avp[1], "polyline") == 0) { + trk = route_head_alloc(); + track_add_head(trk); + } + } else if (strcmp(avp[0], "name") == 0) { + if (wpt) { + wpt->shortname = xstrdup(avp[1]); + } else if (trk) { + trk->rte_name = xstrdup(avp[1]); + } + } else if (strcmp(avp[0], "comment") == 0) { + if (wpt) { + wpt->notes = xstrdup(avp[1]); + } + } else if (strcmp(avp[0], "alt") == 0) { + if (wpt) { + wpt->altitude = atof(avp[1]); + } + } else if (strcmp(avp[0], "timestamp") == 0) { + if (wpt) { + wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); + } + } else if (strcmp(avp[0], "icon") == 0) { + if (wpt) { + wpt->icon_descr = xstrdup(avp[1]); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + } + } + + avp+=2; + } } -static void +static void xol_shape_end(const char *args, const char **unused) { - if (wpt) { - if (trk) track_add_wpt(trk, wpt); - else waypt_add(wpt); - wpt = NULL; - } - else if (trk) { - if (trk->rte_waypt_ct == 0) track_del_head(trk); - trk = NULL; - } + if (wpt) { + if (trk) { + track_add_wpt(trk, wpt); + } else { + waypt_add(wpt); + } + wpt = NULL; + } else if (trk) { + if (trk->rte_waypt_ct == 0) { + track_del_head(trk); + } + trk = NULL; + } } -static void -xol_waypt(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - int x=0, y=0; - - while (*avp) { - if (strcmp(avp[0], "y") == 0) - y = atoi(avp[1]); - else if (strcmp(avp[0], "x") == 0) - x = atoi(avp[1]); - avp+=2; - } - - GPS_Math_Swiss_EN_To_WGS84((double)x, (double)y, &wpt->latitude, &wpt->longitude); +static void +xol_waypt(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + int x=0, y=0; + + while (*avp) { + if (strcmp(avp[0], "y") == 0) { + y = atoi(avp[1]); + } else if (strcmp(avp[0], "x") == 0) { + x = atoi(avp[1]); + } + avp+=2; + } + + GPS_Math_Swiss_EN_To_WGS84((double)x, (double)y, &wpt->latitude, &wpt->longitude); } -static void +static void xol_rd_init(const char *fname) { - trk = NULL; - wpt = NULL; + trk = NULL; + wpt = NULL; - xml_init(fname, xol_map, NULL); + xml_init(fname, xol_map, NULL); } -static void +static void xol_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void xol_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } /* writer */ @@ -180,175 +189,188 @@ xol_rd_deinit(void) static void xol_fatal_outside(const waypoint *wpt) { - gbfprintf(fout, "#####\n"); - fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", - wpt->shortname ? wpt->shortname : "Waypoint", - pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), - gt_get_mps_grid_longname(grid_swiss, MYNAME)); + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", + wpt->shortname ? wpt->shortname : "Waypoint", + pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), + gt_get_mps_grid_longname(grid_swiss, MYNAME)); } static void xol_write_time(const waypoint *wpt) { - char time_string[64]; - - xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); - if (time_string[0]) { - gbfprintf(fout, " timestamp=\"%s\"", time_string); - } + char time_string[64]; + + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); + if (time_string[0]) { + gbfprintf(fout, " timestamp=\"%s\"", time_string); + } } static void xol_write_string(const char *name, const char *str) { - if (str && *str) { - char *temp = strenquote(str, '"'); - gbfprintf(fout, " %s=%s", name, temp); - xfree(temp); - } + if (str && *str) { + char *temp = strenquote(str, '"'); + gbfprintf(fout, " %s=%s", name, temp); + xfree(temp); + } } static void xol_waypt_bound_calc(const waypoint *wpt) { - waypt_add_to_bounds(&all_bounds, wpt); + waypt_add_to_bounds(&all_bounds, wpt); } static void xol_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); - - space = 1; - waypt_init_bounds(&all_bounds); - short_h = mkshort_new_handle(); - - setshort_length(short_h, 1024); /* ??? */ - setshort_badchars(short_h, "\r\n\t"); - setshort_mustupper(short_h, 0); - setshort_mustuniq(short_h, 1); - setshort_whitespace_ok(short_h, 1); - setshort_repeating_whitespace_ok(short_h, 1); - setshort_defname(short_h, "Waypoint"); + fout = gbfopen(fname, "w", MYNAME); + + space = 1; + waypt_init_bounds(&all_bounds); + short_h = mkshort_new_handle(); + + setshort_length(short_h, 1024); /* ??? */ + setshort_badchars(short_h, "\r\n\t"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + setshort_defname(short_h, "Waypoint"); } static void xol_wr_deinit(void) { - mkshort_del_handle(&short_h); - gbfclose(fout); + mkshort_del_handle(&short_h); + gbfclose(fout); } static void xol_waypt_disp_cb(const waypoint *wpt) { - double x, y; - char *name; - - name = wpt->shortname; - if ((name == NULL) || (*name == '\0') || global_opts.synthesize_shortnames) - name = mkshort_from_wpt(short_h, wpt); - else - name = mkshort(short_h, name); - - if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &x, &y)) - xol_fatal_outside(wpt); - - gbfprintf(fout, "%*snotes); - xol_write_string("icon", wpt->icon_descr); - if (wpt->creation_time) xol_write_time(wpt); - if (wpt->altitude != unknown_alt) gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); - gbfprintf(fout, ">\n"); - - gbfprintf(fout, "%*s\n", space++*2, ""); - gbfprintf(fout, "%*s\n", space*2, "", x, y); - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "%*s\n", --space*2, ""); - - xfree(name); + double x, y; + char *name; + + name = wpt->shortname; + if ((name == NULL) || (*name == '\0') || global_opts.synthesize_shortnames) { + name = mkshort_from_wpt(short_h, wpt); + } else { + name = mkshort(short_h, name); + } + + if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &x, &y)) { + xol_fatal_outside(wpt); + } + + gbfprintf(fout, "%*snotes); + xol_write_string("icon", wpt->icon_descr); + if (wpt->creation_time) { + xol_write_time(wpt); + } + if (wpt->altitude != unknown_alt) { + gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); + } + gbfprintf(fout, ">\n"); + + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s\n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); + + xfree(name); } static void xol_track_hdr_disp_cb(const route_head *trk) { - gbfprintf(fout, "%*srte_name); - gbfprintf(fout, " lineSize=\"3\" lineColor=\"#e60000\" lineStyle=\"solid\">\n"); - gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*srte_name); + gbfprintf(fout, " lineSize=\"3\" lineColor=\"#e60000\" lineStyle=\"solid\">\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); } static void xol_track_tlr_disp_cb(const route_head *trk) { - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); } static void xol_trkpt_disp_cb(const waypoint *wpt) { - double x, y; - - if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &x, &y)) - xol_fatal_outside(wpt); - - gbfprintf(fout, "%*screation_time) xol_write_time(wpt); - if (wpt->altitude != unknown_alt) gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); - gbfprintf(fout, ">\n"); - gbfprintf(fout, "%*s\n", space++*2, ""); - gbfprintf(fout, "%*s\n", space*2, "", x, y); - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "%*s\n", --space*2, ""); + double x, y; + + if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &x, &y)) { + xol_fatal_outside(wpt); + } + + gbfprintf(fout, "%*screation_time) { + xol_write_time(wpt); + } + if (wpt->altitude != unknown_alt) { + gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); + } + gbfprintf(fout, ">\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s\n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); } static void xol_write(void) { - double x, y; - - waypt_disp_all(xol_waypt_bound_calc); - track_disp_all(NULL, NULL, xol_waypt_bound_calc); - - if (! waypt_bounds_valid(&all_bounds)) { - fatal(MYNAME ": No data available!\n"); - } - - if (! GPS_Math_WGS84_To_Swiss_EN( - (all_bounds.min_lat + all_bounds.max_lat) / 2, - (all_bounds.min_lon + all_bounds.max_lon) / 2, &x, &y)) { - gbfprintf(fout, "#####\n"); - fatal(MYNAME ": At least one point is outside of convertable area \"%s\"!\n", - gt_get_mps_grid_longname(grid_swiss, MYNAME)); - } - - gbfprintf(fout, "\n", global_opts.charset_name); - gbfprintf(fout, "\n"); - gbfprintf(fout, "%*s\n", space++*2, ""); - gbfprintf(fout, "%*s

\n", space*2, "", x, y); - gbfprintf(fout, "%*s\n", space++*2, ""); - waypt_disp_all(xol_waypt_disp_cb); - track_disp_all(xol_track_hdr_disp_cb, xol_track_tlr_disp_cb, xol_trkpt_disp_cb); - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "\n"); + double x, y; + + waypt_disp_all(xol_waypt_bound_calc); + track_disp_all(NULL, NULL, xol_waypt_bound_calc); + + if (! waypt_bounds_valid(&all_bounds)) { + fatal(MYNAME ": No data available!\n"); + } + + if (! GPS_Math_WGS84_To_Swiss_EN( + (all_bounds.min_lat + all_bounds.max_lat) / 2, + (all_bounds.min_lon + all_bounds.max_lon) / 2, &x, &y)) { + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": At least one point is outside of convertable area \"%s\"!\n", + gt_get_mps_grid_longname(grid_swiss, MYNAME)); + } + + gbfprintf(fout, "\n", global_opts.charset_name); + gbfprintf(fout, "\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s
\n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", space++*2, ""); + waypt_disp_all(xol_waypt_disp_cb); + track_disp_all(xol_track_hdr_disp_cb, xol_track_tlr_disp_cb, xol_trkpt_disp_cb); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "\n"); } ff_vecs_t xol_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, /* waypoints */ - ff_cap_read | ff_cap_write, /* tracks */ - ff_cap_none }, /* routes */ - xol_rd_init, - xol_wr_init, - xol_rd_deinit, - xol_wr_deinit, - xol_read, - xol_write, - NULL, - xol_args, - CET_CHARSET_UTF8, 0 + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write), /* waypoints */ + (ff_cap)(ff_cap_read | ff_cap_write), /* tracks */ + ff_cap_none + }, /* routes */ + xol_rd_init, + xol_wr_init, + xol_rd_deinit, + xol_wr_deinit, + xol_read, + xol_write, + NULL, + xol_args, + CET_CHARSET_UTF8, 0 }; diff --git a/gpsbabel/yahoo.c b/gpsbabel/yahoo.c index 8a98668fd..e55e00a6f 100644 --- a/gpsbabel/yahoo.c +++ b/gpsbabel/yahoo.c @@ -29,91 +29,93 @@ static char *as; static arglist_t yahoo_args[] = { - {"addrsep", &as, - "String to separate concatenated address fields (default=\", \")", - ", ", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "addrsep", &as, + "String to separate concatenated address fields (default=\", \")", + ", ", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static xg_callback wpt_s, wpt_lat, wpt_lon, wpt_e; static xg_callback wpt_addr /*, wpt_city, wpt_state, wpt_zip, wpt_country*/; static xg_tag_mapping gl_map[] = { - { wpt_s, cb_start, "/ResultSet/Result" }, - { wpt_lat, cb_cdata, "/ResultSet/Result/Latitude" }, - { wpt_lon, cb_cdata, "/ResultSet/Result/Longitude" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/Address" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/City" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/State" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/Zip" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/Country" }, - { wpt_e, cb_end, "/ResultSet/Result" }, - { NULL, 0, NULL} + { wpt_s, cb_start, "/ResultSet/Result" }, + { wpt_lat, cb_cdata, "/ResultSet/Result/Latitude" }, + { wpt_lon, cb_cdata, "/ResultSet/Result/Longitude" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Address" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/City" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/State" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Zip" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Country" }, + { wpt_e, cb_end, "/ResultSet/Result" }, + { NULL, (xg_cb_type)0, NULL} }; static void yahoo_rd_init(const char *fname) { - xml_init(fname, gl_map, NULL); + xml_init(fname, gl_map, NULL); } static void yahoo_read(void) { - xml_read(); + xml_read(); } static void yahoo_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void yahoo_wr_init(const char *fname) { - fatal("Writing file of type %s is not supported\n", MYNAME); + fatal("Writing file of type %s is not supported\n", MYNAME); } void wpt_s(const char *args, const char **unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } void wpt_e(const char *args, const char **unused) { - waypt_add(wpt_tmp); - wpt_tmp = NULL; + waypt_add(wpt_tmp); + wpt_tmp = NULL; } void wpt_lat(const char *args, const char **unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } void wpt_lon(const char *args, const char **unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } void wpt_addr(const char *args, const char **unused) { - if (wpt_tmp->notes) { - wpt_tmp->notes = xstrappend(wpt_tmp->notes, as); - } - wpt_tmp->notes = xstrappend(wpt_tmp->notes, args); + if (wpt_tmp->notes) { + wpt_tmp->notes = xstrappend(wpt_tmp->notes, as); + } + wpt_tmp->notes = xstrappend(wpt_tmp->notes, args); } ff_vecs_t yahoo_vecs = { - ff_type_file, - { ff_cap_read }, - yahoo_rd_init, - yahoo_wr_init, - yahoo_rd_deinit, - NULL, - yahoo_read, - NULL, - NULL, - yahoo_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read }, + yahoo_rd_init, + yahoo_wr_init, + yahoo_rd_deinit, + NULL, + yahoo_read, + NULL, + NULL, + yahoo_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/zlib/ChangeLog b/gpsbabel/zlib/ChangeLog index 1724324fb..6d20a0806 100644 --- a/gpsbabel/zlib/ChangeLog +++ b/gpsbabel/zlib/ChangeLog @@ -604,7 +604,7 @@ Changes in 1.0.6 (19 Jan 1998) - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) - added makelcc.bat for lcc-win32 (Tom St Denis) - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id: ChangeLog,v 1.1 2006/07/22 20:34:06 oliskoli Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- Avoid expanded $Id: ChangeLog,v 1.1 2006-07-22 20:34:06 oliskoli Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. - check for unistd.h in configure (for off_t) - remove useless check parameter in inflate_blocks_free - avoid useless assignment of s->check to itself in inflate_blocks_new diff --git a/gpsbabel/zlib/adler32.c b/gpsbabel/zlib/adler32.c index 847a20dfd..e099363c3 100644 --- a/gpsbabel/zlib/adler32.c +++ b/gpsbabel/zlib/adler32.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: adler32.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ +/* @(#) $Id: adler32.c,v 1.1 2006-07-22 20:34:06 oliskoli Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff --git a/gpsbabel/zlib/compress.c b/gpsbabel/zlib/compress.c index 7ef8d6e5e..9863b79ab 100644 --- a/gpsbabel/zlib/compress.c +++ b/gpsbabel/zlib/compress.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: compress.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ +/* @(#) $Id: compress.c,v 1.1 2006-07-22 20:34:06 oliskoli Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff --git a/gpsbabel/zlib/crc32.c b/gpsbabel/zlib/crc32.c index 1b7bd1a06..4257727a3 100644 --- a/gpsbabel/zlib/crc32.c +++ b/gpsbabel/zlib/crc32.c @@ -9,7 +9,7 @@ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ -/* @(#) $Id: crc32.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ +/* @(#) $Id: crc32.c,v 1.1 2006-07-22 20:34:06 oliskoli Exp $ */ /* Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore diff --git a/gpsbabel/zlib/deflate.c b/gpsbabel/zlib/deflate.c index 3babea592..4df8819b1 100644 --- a/gpsbabel/zlib/deflate.c +++ b/gpsbabel/zlib/deflate.c @@ -47,7 +47,7 @@ * */ -/* @(#) $Id: deflate.c,v 1.1 2006/07/22 20:34:07 oliskoli Exp $ */ +/* @(#) $Id: deflate.c,v 1.1 2006-07-22 20:34:07 oliskoli Exp $ */ #include "deflate.h" diff --git a/gpsbabel/zlib/deflate.h b/gpsbabel/zlib/deflate.h index 78449ca42..443814c53 100644 --- a/gpsbabel/zlib/deflate.h +++ b/gpsbabel/zlib/deflate.h @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id: deflate.h,v 1.1 2006/07/22 20:34:07 oliskoli Exp $ */ +/* @(#) $Id: deflate.h,v 1.1 2006-07-22 20:34:07 oliskoli Exp $ */ #ifndef DEFLATE_H #define DEFLATE_H diff --git a/gpsbabel/zlib/gzio.c b/gpsbabel/zlib/gzio.c index 13f73cd11..38a31cdc3 100644 --- a/gpsbabel/zlib/gzio.c +++ b/gpsbabel/zlib/gzio.c @@ -5,7 +5,7 @@ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. */ -/* @(#) $Id: gzio.c,v 1.3 2006/08/13 17:08:00 oliskoli Exp $ */ +/* @(#) $Id: gzio.c,v 1.3 2006-08-13 17:08:00 oliskoli Exp $ */ #include diff --git a/gpsbabel/zlib/trees.c b/gpsbabel/zlib/trees.c index 7a66ddaa8..a9daa8af5 100644 --- a/gpsbabel/zlib/trees.c +++ b/gpsbabel/zlib/trees.c @@ -29,7 +29,7 @@ * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ -/* @(#) $Id: trees.c,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ +/* @(#) $Id: trees.c,v 1.1 2006-07-22 20:34:08 oliskoli Exp $ */ /* #define GEN_TREES_H */ diff --git a/gpsbabel/zlib/uncompr.c b/gpsbabel/zlib/uncompr.c index cf608299d..b9b530c47 100644 --- a/gpsbabel/zlib/uncompr.c +++ b/gpsbabel/zlib/uncompr.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: uncompr.c,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ +/* @(#) $Id: uncompr.c,v 1.1 2006-07-22 20:34:08 oliskoli Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff --git a/gpsbabel/zlib/zconf.h b/gpsbabel/zlib/zconf.h index 58af16be8..2415469f6 100644 --- a/gpsbabel/zlib/zconf.h +++ b/gpsbabel/zlib/zconf.h @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zconf.h,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ +/* @(#) $Id: zconf.h,v 1.1 2006-07-22 20:34:08 oliskoli Exp $ */ #ifndef ZCONF_H #define ZCONF_H diff --git a/gpsbabel/zlib/zconf.in.h b/gpsbabel/zlib/zconf.in.h index 7c70c966d..d6f4e244c 100644 --- a/gpsbabel/zlib/zconf.in.h +++ b/gpsbabel/zlib/zconf.in.h @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zconf.in.h,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ +/* @(#) $Id: zconf.in.h,v 1.1 2006-07-22 20:34:11 oliskoli Exp $ */ #ifndef ZCONF_H #define ZCONF_H diff --git a/gpsbabel/zlib/zutil.c b/gpsbabel/zlib/zutil.c index 5f50b2471..4e30bec8d 100644 --- a/gpsbabel/zlib/zutil.c +++ b/gpsbabel/zlib/zutil.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zutil.c,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ +/* @(#) $Id: zutil.c,v 1.1 2006-07-22 20:34:11 oliskoli Exp $ */ #include "zutil.h" diff --git a/gpsbabel/zlib/zutil.h b/gpsbabel/zlib/zutil.h index 2045fda8a..201394c79 100644 --- a/gpsbabel/zlib/zutil.h +++ b/gpsbabel/zlib/zutil.h @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id: zutil.h,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ +/* @(#) $Id: zutil.h,v 1.1 2006-07-22 20:34:11 oliskoli Exp $ */ #ifndef ZUTIL_H #define ZUTIL_H -- 2.30.2